Downloader Middleware处理的过程主要在调度器发送requests请求的时候以及网页将response结果返回给spider的时候, 所以说下载中间件是结余Scrapy的request/response处理的钩子, 用于修改Scrapy request和response.
编写自己的下载器中间件 :
编写下载器中间件, 需要定义下一或者多个方法的python类
新建一个关于爬取httpbin.org网站的项目
scrapy startproject httpbintest
cd httpbintest
scrapy genspider example example.com
写一个简单的代理中间件实现ip伪装
创建好爬虫之后将httpbin.py中的parse方法改成:
def parse(self, response): print(response.text)
然后命令行启动爬虫: scrapy crawl httpbin
在下面看到"origin": "114.250.88.66"
在查看自己的ip
编写中间件实现ip伪装, 在middleares.py中:
class ProxyMiddleare(object): logger = logging.getLogger(__name__) def process_request(self,request, spider): self.logger.debug("Using Proxy") request.meta['proxy'] = 'http://127.0.0.1:9743' return None
然后再settings.py中配置文件开启下载中间件的功能, 默认是关闭的
重启爬虫
在日志中可以看到定义的中间件已经移动,而且查看origin的ip地址也已经变成了日本的ip地址
详细说明
class Scrapy.downloadermiddleares.DownliaderMiddleware
process_request(request, spider) :
当每个request通过下载中间件的时候, 该方法被调用, 该方法必须返回以下三种中的任意一种:
1. None: Scrapy将继续处理该request, 执行其他的中间件的响应方法, 知道何时的下载器处理函数(download handler)被调用, 该request被执行(其resposne被下载)
2. Response对象: Scrapy将不会调用人其他的process_request()或者process_exception()方法, 或者响应的下载函数; 其将返回response. 已安装的中间件的process_response()方法胡子爱每个res[onse返回时被调用
3. Request对象或raise异常:
返回Request对象时: Scrapy停止调用process_request方法并衷心调度返回的request. 当新的request被执行之后, 相应的中间件将会根据下载的response被调用.
当raises异常时: 安装的下载中间件的process_exception()方法会被调用. 如果没有任何一个方法处理该异常, 则request的errback(Request.errback)方法被调用. 如果没有代码处理抛出的异常, 则该异常被忽略且不被记录.
process_response(request, response, spider) :
process_response的返回值也是有三种:
1. response对象: 如果返回的是一个Resopnse(可以与传入的response相同, 也可以是全新的对象), 该response会被链中的其他中间件的process_response()方法处理.
2. Request对象: 如果其返回一个Request对象, 则中间件链停止, 返回的request会被重新调度下载. 处理类似于process_request()返回request所做的那样.
3. raiseu异常: 如果其抛出一个lgnoreRequest异常, 则调用request的errback(Request.errback). 如果没有代码处理抛出的异常, 则该异常被忽略且不记录.
process_exception(request, exception, spider) :
当下载处理器(downloader handler)或者process_request()(下载中间件)抛出异常(包括lgnoreRequest异常)时, Scrapy调用process_exception().
process_exception()也是返回三者中的一个:
1. 返回None: Scrapy将会继续处理该异常, 接着调用已安装的其他中间件的process_exception()方法,知道所有的中间件都被调用完毕, 则调用默认的异常处理.
2. 返回Response: 已安装的中间件链的process_response()方法被调用. Scrapy将不会调用任何其他中间件的process_exception()方法.
3. 返回一个Request对象: 返回的额request将会被重新调用下载. 浙江停止中间件的process_exception()方法的执行, 就如返回一个response那样. 相当于如果失败了可以在这里进行一次失败的重试, 例如当访问一个网站出现因为频繁爬取被封ip就可以在这里设置增加代理继续访问.