Scrapy 中间件

Downloader Middleware 的用法

Downloader Middleware 即下载中间件,它是处于Scrapy 的Request 和Response之间的处理模块。

Downloader Middleware 在整个架构中起作用的位置是以下两个:

  • 在Scheduler 调度出队列的Request 发送给Doanloader 下载之前,也就是我们可以在Request执行下载之前对其进行修改。
  • 在下载后生成的Response 发送给Spider 之前,也就是我们可以在生成Resposne 被Spider 解析之前对其进行修改。

利用Downloader Middleware 可以修改User-Agent 、处理重定向、设置代理、失败重试、设置Cookies

下载中间件,爬虫中间件都是写在middlewares.py中(名字随便命名)的,在settings.py中配置生效,如下

# 数字小的Downloader Middleware 会被优先调用
# 爬虫中间件
SPIDER_MIDDLEWARES = { 'cnblogs_crawl.middlewares.CnblogsCrawlSpiderMiddleware': 543, }

# 下载中间件 DOWNLOADER_MIDDLEWARES
= { 'cnblogs_crawl.middlewares.CnblogsCrawlDownloaderMiddleware': 543, }

Downloader Middleware中间件三个方法

process _request(self, request, spider):

该方法被Scrapy引擎调度给Downloader之前调用

# - return None: Scrapy将继续处理该Request,接着执行其他Downloader Middleware的其他中间件的process_request()方法,一直到Downloader把Request执行后得到Response才结束。
# - return Response:更低优先级的Downloader Middleware 的process_request()和process_exception()方法就不会被继续调用,
  每个Downloader Middleware的process response()方法转而被依次调用。
  调用完毕之后,直接将Response对象发送给Spider来处理。(可以自己爬,包装成Response)
# - return Request : 相当于把Request重新给了引擎,引擎再去做调度 # - 抛异常:执行process_exception

process_response(self, request, response, spider):

Downloader执行Request下载之后,会得到对应的Response 。Scrapy引擎便会将Response 发送给Spider进行解析。在发送之前,我们都可以用process_response()方法来对Response 进行处理。

# - return Response :继续处理当次Response,继续走更低优先级的中间件
# - return Request :重新给引擎做调度
# - or raise IgnoreRequest :process_exception

process_exception(self, request, exception, spider):

当Downloader 或process_request()方法抛异常时,例如抛出Ignore Request异常,process_exception()方法就会被调用

# - return None: 更低优先级的Downloader Middleware的process_exception()会被继续顺次调用,直到所有的方法都被调度完毕
# - return Response: 后续中间件的process_exception()方法不再被继续调用,每个Downloader Middleware 的process_response()方法转而被依次调用。
# - return Request:更低优先级的Downloader Middleware的process_exception()不再被继续调用,该Resquest给引擎(重新调度)

案例:process _request中加cookie、代理和User-Agent

class CnblogsCrawlDownloaderMiddleware(object):
    # 获取代理函数
    def get_proxy(self):
        import requests
        proxy = requests.get('代理地址/get').json()['proxy']
        return proxy

    def process_request(self, request, spider):
        # 1 加cookie(在request.cookies中就是访问该网站的cookie)
        print(request.cookies)
        #从你的cookie池中取出来的,  字典,设置
        request.cookies={'k':'v'}
        print(request.cookies)
        
        # 2 加代理 在request.meta['proxy']中加
        request.meta['proxy'] = self.get_proxy()
        
        # 3 修改useragent
        from fake_useragent import UserAgent
        ua = UserAgent(verify_ssl=False)
        request.headers['User-Agent'] = ua
        
        return None
原文地址:https://www.cnblogs.com/baohanblog/p/12679163.html