爬虫_小结04

一、接触过几种爬虫模块
urllib requestscss

二、robots协议是什么?
网站有一些数据不想被爬虫程序爬取,能够编写robots协议文件,明确指明哪些内容能够爬取哪些不能够爬取。
在Scrapy框架中在settings.py文件中使用了硬性语法对该协议进行了生效python

三、如何处理验证码?
使用三方的打码平台好比:云打码平台、打码兔,能够用来处理验证码。

四、掌握几种数据解析的方式?
re、xpath(最经常使用)、bs4(python独有)

五、如何爬取动态加载的页面数据?
selenium; ajax:抓包工具抓取异步发起的请求(url)

六、接触过哪些反爬机制?如何处理?
robots协议、UA、封IP、验证码、动态数据加载、数据加密、token
处理:
配置不遵照robots协议、假装User-Agent、代理IP更换、打码平台对验证码识别、
selenium处理或者使用抓包工具去抓取动态加载的AJAX请求数据包、
按照已知的各类加密方式进行解密、去前台页面进行token值的查找手动放入请求携带的参数中。

七、在Scrapy中接触过几种爬虫类?
Spider、CrawlSpider(连接提取器和规则解析器)、RedisCrawlSpider、RedisSpider

八、如何实现分布式流程?
必需要经过scrapy-redis组件来实现,能够由RedisCrawlSpider、RedisSpider这两种类分别实现。

9.简述 requests模块的做用及基本使用?
Requests 自称 "HTTP for Humans",说明使用更简洁方便。
Requests支持HTTP链接保持和链接池,支持使用cookie保持会话,支持文件上传,支持自动肯定响应内容的编码,
支持国际化的 URL 和 POST 数据自动编码。

十、requests模块参数,data与json参数的区别?
在经过requests.post()进行POST请求时,传入报文的参数有两个,一个是data,一个是json。
data与json既能够是str类型,也能够是dict类型。
区别:
一、无论json是str仍是dict,若是不指定headers中的content-type,默认为application/json
二、data为dict时,若是不指定content-type,默认为application/x-www-form-urlencoded,至关于普通form表单提交的形式
三、data为str时,若是不指定content-type,默认为application/json
四、用data参数提交数据时,request.body的内容则为a=1&b=2的这种形式,用json参数提交数据时,request.body的内容则为'{"a": 1, "b": 2}'的这种形式

十一、简述 beautifulsoup模块的做用及基本使用?
和 lxml 同样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。
lxml 只会局部遍历,而Beautiful Soup 是基于HTML DOM的,会载入整个文档,解析整个DOM树,所以时间和内存开销都会大不少,因此性能要低于lxml。

十二、简述 seleninu模块的做用及基本使用?
Selenium 能够根据咱们的指令,让浏览器自动加载页面,获取须要的数据,甚至页面截屏,或者判断网站上某些动做是否发生。
Selenium 本身不带浏览器,不支持浏览器的功能,它须要与第三方浏览器结合在一块儿才能使用。

1三、scrapy框架中各组件的工做流程?
Scrapy Engine: 这是引擎,负责Spiders、ItemPipeline、Downloader、Scheduler中间的通信,信号、数据传递等等
Scheduler(调度器): 它负责接受引擎发送过来的requests请求,并按照必定的方式进行整理排列,入队、并等待Scrapy Engine(引擎)来请求时,交给引擎。
Downloader(下载器):负责下载Scrapy Engine(引擎)发送的全部Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spiders来处理
Spiders:它负责处理全部Responses,从中分析提取数据,获取Item字段须要的数据,并将须要跟进的URL提交给引擎,再次进入Scheduler(调度器)
Item Pipeline:它负责处理Spiders中获取到的Item,并进行处理,好比去重,持久化存储(存数据库,写入文件,总之就是保存数据用的)
Downloader Middlewares(下载中间件):你能够看成是一个能够自定义扩展下载功能的组件
Spider Middlewares(Spider中间件):你能够理解为是一个能够自定扩展和操做引擎和Spiders中间‘通讯‘的功能组件
(好比进入Spiders的Responses;和从Spiders出去的Requests) ajax

 

1四、在scrapy框架中如何设置代理(两种方法)?redis

一.使用中间件DownloaderMiddleware进行配置       
        1.在Scrapy工程下新建“middlewares.py”
        # Importing base64 library because we'll need it ONLY in case if the proxy we are going to use requires authentication
        import base64 
        # Start your middleware class
        class ProxyMiddleware(object):
            # overwrite process request
            def process_request(self, request, spider):
                # Set the location of the proxy
                request.meta['proxy'] = "http://YOUR_PROXY_IP:PORT"
          
                # Use the following lines if your proxy requires authentication
                proxy_user_pass = "USERNAME:PASSWORD"
                # setup basic authentication for the proxy
                encoded_user_pass = base64.encodestring(proxy_user_pass)
                request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass    
            
        2.在项目配置文件里(./pythontab/settings.py)添加
        DOWNLOADER_MIDDLEWARES = {
            'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 110,
            'pythontab.middlewares.ProxyMiddleware': 100,
        }           
        注意:
            1.proxy必定是要写号http://前缀
            2.若是代理有用户名密码等就须要在后面再加上一些内容
使用中间件DownloaderMiddleware进行配置
二.直接在爬虫程序中设置proxy字段
        能够直接在本身具体的爬虫程序中设置proxy字段,直接在构造Request里面加上meta字段便可     
        class QuotesSpider(scrapy.Spider):
            name = "quotes"
            def start_requests(self):
                urls = [
                    'http://quotes.toscrape.com/page/1/',
                    'http://quotes.toscrape.com/page/2/',
                ]
                for url in urls:
                    yield scrapy.Request(url=url, callback=self.parse, meta={'proxy': 'http://proxy.yourproxy:8001'})
         
            def parse(self, response):
                for quote in response.css('div.quote'):
                    yield {
                        'text': quote.css('span.text::text').extract_first(),
                        'author': quote.css('span small::text').extract_first(),
                        'tags': quote.css('div.tags a.tag::text').extract(),
                }
            
        --------------
        import scrapy

        class ProxySpider(scrapy.Spider):
            name = 'proxy'
            allowed_domains = ["httpbin.org"]
        
            def start_requests(self):
                url = 'http://httpbin.org/get'
                proxy = '127.0.0.0:8000'
        
                proxies = ""
                if url.startswith("http://"):
                    proxies = "http://"+str(proxy)
                elif url.startswith("https://"):
                    proxies = "https://"+str(proxy)
                #注意这里面的meta={'proxy':proxies},必定要是proxy进行携带,其它的不行,后面的proxies必定 要是字符串,其它任何形式都不行
                yield scrapy.Request(url, callback=self.parse,meta={'proxy':proxies})
        
            def parse(self,response):
                print(response.text)
  
直接在爬虫程序中设置proxy字段

1五、scrapy框架中如何实现大文件的下载?
利用scrapy下载大量大尺寸图片及视频时有时会报错,显示放弃重试
缘由:
这是因为scrapy并发请求过多,默认状况下会同时下载16个文件,而链接时间默认超过三分钟就会丢失。
就是说若是三分钟以内你的网速无法支持你同时下载完16个文件的话就会形成这个问题。
解决方法:
在settings.py中将默认并发链接数调小或者将timeout时间调大
CONCURRENT_REQUESTS = 2
DOWNLOAD_TIMEOUT=1800
此时并发请求被调成2, 等待时间被1800秒,通常的小视频和图片是没有问题了。数据库

1六、scrapy中如何实现限速?
自动限速:
限制爬虫速度,对对方服务器友好些,防止被识别

在setting.py开启相关扩展:
自动限速设定:
AUTOTHROTTLE_ENABLED = True
设定爬取速度:
DOWNLOAD_DELAY = 1 #单位为秒json


1七、scrapy中如何实现暂定爬虫?
1.进入到scrapy项目里
二、在scrapy项目里建立保存记录信息的文件 zant/001
三、执行命令:
scrapy crawl 爬虫名称 -s JOBDIR=保存记录信息的路径
如:scrapy crawl cnblogs -s JOBDIR=zant/001
执行命令会启动指定爬虫,而且记录状态到指定目录
爬虫已经启动,咱们能够按键盘上的ctrl+c中止爬虫,中止后咱们看一下记录文件夹,会多出3个文件,
其中的requests.queue文件夹里的p0文件就是URL记录文件,这个文件存在就说明还有未完成的URL,当全部URL完成后会自动删除此文件
当咱们从新执行命令:scrapy crawl cnblogs -s JOBDIR=zant/001  时爬虫会根据p0文件从中止的地方开始继续爬取。浏览器

 

1八、scrapy中如何进行自定制命令?服务器

【同时运行多个scrapy爬虫的几种方法(自定义scrapy项目命令)】
    一、建立commands目录
        mkdir commands
    注意:commands和spiders目录是同级的
    
    二、在commands下面添加一个文件crawlall.py
    这里主要经过修改scrapy的crawl命令来完成同时执行spider的效果。
    
        from scrapy.commands import ScrapyCommand  
        from scrapy.crawler import CrawlerRunner
        from scrapy.utils.conf import arglist_to_dict
        
        class Command(ScrapyCommand):
            requires_project = True
            
            def syntax(self):  
                return '[options]'  
            
            def short_desc(self):  
                return 'Runs all of the spiders'  
            
            def add_options(self, parser):
                ScrapyCommand.add_options(self, parser)
                parser.add_option("-a", dest="spargs", action="append", default=[], metavar="NAME=VALUE",
                    help="set spider argument (may be repeated)")
                parser.add_option("-o", "--output", metavar="FILE",
                    help="dump scraped items into FILE (use - for stdout)")
                parser.add_option("-t", "--output-format", metavar="FORMAT",
                    help="format to use for dumping items with -o")
            
            def process_options(self, args, opts):
                ScrapyCommand.process_options(self, args, opts)
                try:
                    opts.spargs = arglist_to_dict(opts.spargs)
                except ValueError:
                    raise UsageError("Invalid -a value, use -a NAME=VALUE", print_help=False)
            
            def run(self, args, opts):
                #settings = get_project_settings()
                spider_loader = self.crawler_process.spider_loader
                for spidername in args or spider_loader.list():
                    print "*********cralall spidername************" + spidername
                    self.crawler_process.crawl(spidername, **opts.spargs)
                self.crawler_process.start()
            
        self.crawler_process.spider_loader.list()方法获取项目下全部的spider,而后利用self.crawler_process.crawl运行spider   
    三、commands命令下添加__init__.py文件
        touch __init__.py
        注意:这一步必定不能省略。

    cnblogs.commands为命令文件目录,crawlall为命令名。
    4. 在settings.py中添加配置:
        COMMANDS_MODULE = 'cnblogs.commands'
    5. 运行命令scrapy crawlall
View Code

 

1九、scrapy中如何实现的记录爬虫的深度?
经过在settings.py中设置DEPTH_LIMIT的值能够限制爬取深度,这个深度是与start_urls中定义url的相对值。cookie

20、scrapy中的pipelines工做原理?
pipelines文件实现了一个item pipieline类,和scrapy的item pipeline是同一个对象,
经过从settings中拿到咱们配置的REDIS_ITEMS_KEY做为key,
把item串行化以后存入redis数据库对应的value中(这个value能够看出出是个list,咱们的每一个item是这个list中的一个结点),
这个pipeline把提取出的item存起来,主要是为了方便咱们延后处理数据。并发

2一、scrapy的pipelines如何丢弃一个item对象?
//TODO

2二、简述scrapy中爬虫中间件和下载中间件的做用?
下载中间件:
下载中间件是处于引擎(crawler.engine)和下载器(crawler.engine.download())之间的一层组件,能够有多个下载中间件被加载运行。
1.当引擎传递请求给下载器的过程当中,下载中间件能够对请求进行处理 (例如增长http header信息,增长proxy信息等);
2.在下载器完成http请求,传递响应给引擎的过程当中, 下载中间件能够对响应进行处理(例如进行gzip的解压等)
Spider中间件(Middleware):
下载器中间件是介入到Scrapy的spider处理机制的钩子框架,能够添加代码来处理发送给 Spiders 的response及spider产生的item和request。

2三、scrapy-redis组件的做用?
实现分布式抓取

2四、scrapy-redis组件中如何实现的任务的去重?
原理:
在分布式爬取时,会有master机器和slave机器,其中,master为核心服务器,slave为具体的爬虫服务器。
在master服务器上搭建一个redis数据库,并将要抓取的url存放到redis数据库中,全部的slave爬虫服务器在抓取的时候从redis数据库中获取连接,
因为scrapy_redis自身的队列机制,slave获取的url不会相互冲突,而后抓取的结果最后都存储到数据库中。
master的redis数据库中还会将抓取过的url的指纹存储起来,用来去重。相关代码在dupefilter.py文件中的request_seen()方法中能够找到。

去重问题:
dupefilter.py 里面的源码:
def request_seen(self, request):
fp = request_fingerprint(request)
added = self.server.sadd(self.key, fp)
return not added
去重是把 request 的 fingerprint 存在 redis 上,来实现的。


2五、scrapy-redis的调度器如何实现任务的深度优先和广度优先?
//TODO


2六、假设有以下两个list:a = ['a', 'b', 'c', 'd', 'e'],b = [1, 2, 3, 4, 5],
将 a 中的元素做为 key,b 中元素做为 value,将 a,b 合并为字典。

a = ['a', 'b', 'c', 'd', 'e']
b = [1, 2, 3, 4, 5]

zip1 = zip(a,b)
# print(zip1) #<zip object at 0x000002984CB6CCC8>
# print(list(zip1))
d = {}
for i in zip1:
d[i[0]] = i[1]
print(d) #{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}


2七、爬取数据后使用哪一个数据库存储数据的,为何?
有规则的数据能够存入 MySQL 中,可是要注意抓取内容出现缺失的状况
不规则的数据存储在 MongoDB 中,直接将数据存入再进行数据清洗

相关文章
相关标签/搜索