scrapy框架及中间件
scrapy框架官方图如下
基本流程是
1.spider发出初始request需求,默认是对start_urls发起get方法的request,如果带参数或者post就重写start_requests(def start_requests(self):)
经过spider middlewears的process_start_requests(self, start_requests, spider),准备向服务器发起访问。
2.这时会经过downloader middlewears的process_request(request, spider),这里的中间件优先级会比setting里的高,比如访问时要带上特别的headers,user-agent,proxy,cookies之类都在process_request中间件里定义。
3.得到response之后会经过downloader middlewears的process_response(self, request, response, spider),结果必须是其中之一
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
然后再经过spider middlewears的process_spider_input(self, response, spider)这个中间件结果只能是none或者抛出异常。
经过两个中间件之后进入spider进行页面解析,得到item或者一系列新的带爬url,
4.item经中间件process_spider_output(self, response, result, spider):此中间件必须返回an iterable of Request, dict or Item objects.
然后进入pipeline进行数据清洗下载。
spider返回的是url则经中间件后又进入scheduler排队带爬。
我倒是觉得这个图说的更明白
当然,我省去了scrapy engine,它是调度,所有request,response及产生的数据都会经他之手。
中间件
SpiderMiddleware主要处理解析Item的相关逻辑修正,比如数据不完整要添加默认,增加其他额外信息等。
DownloaderMiddleware主要处理请求Request发出去和结果Response返回的一些回调,
上文其他未提及的中间件还有:SpiderMiddleware中的
process_spider_exception(self, response, exception, spider):
downloader middlewears中的
process_exception(self, request, exception, spider):可以处理超时
看名字就知道这是两个异常中间件。
downloader middlewears详细说明:
process_request(request,spider)
当每个request通过下载中间件时,该方法被调用,这里有一个要求,该方法必须返回以下三种中的任意一种:None,返回一个Response对象,返回一个Request对象或raise IgnoreRequest。三种返回值的作用是不同的。
None:Scrapy将继续处理该request,执行其他的中间件的相应方法,直到合适的下载器处理函数(download handler)被调用,该request被执行(其response被下载)。
Response对象:Scrapy将不会调用任何其他的process_request()或process_exception() 方法,或相应地下载函数;其将返回该response。 已安装的中间件的 process_response() 方法则会在每个response返回时被调用。
Request对象:Scrapy则停止调用 process_request方法并重新调度返回的request。当新返回的request被执行后, 相应地中间件链将会根据下载的response被调用。
raise一个IgnoreRequest异常:则安装的下载中间件的 process_exception() 方法会被调用。如果没有任何一个方法处理该异常, 则request的errback(Request.errback)方法会被调用。如果没有代码处理抛出的异常, 则该异常被忽略且不记录。
process_response(request, response, spider)
可以看返回是否是200加入重试机制
process_response的返回值也是有三种:response对象,request对象,或者raise一个IgnoreRequest异常
如果其返回一个Response(可以与传入的response相同,也可以是全新的对象), 该response会被在链中的其他中间件的 process_response() 方法处理。
如果其返回一个 Request 对象,则中间件链停止, 返回的request会被重新调度下载。处理类似于 process_request() 返回request所做的那样。
如果其抛出一个 IgnoreRequest 异常,则调用request的errback(Request.errback)。 如果没有代码处理抛出的异常,则该异常被忽略且不记录(不同于其他异常那样)。
参考:
https://www.cnblogs.com/x-pyue/p/7795315.html
https://www.colabug.com/2119457.html
https://www.cnblogs.com/zhaof/p/7198407.html
https://blog.csdn.net/xnby/article/details/52297047