关于Scrapy框架中yield方法和Downloader中间件的讲解

一、yield方法

1》作用:调用yield方法,将请求(request)发送给Scrapy Engine(引擎)进行处理
2》参数分析:

yield scrapy.Request(       # 该Request对象代表了一个http请求,会经由Downloader去执行,从而产生一个response
	url=task["task_url"],    	# 请求数据库中的url
	callback=xxx,				# callback回调函数,默认不写会调用parse方法
	method='GET',				# 请求方法,默认为get
	headers=xxx,				# 请求头信息(一般在setting.py中的DEFAULT_REQUEST_HEADERS设置即可)
	body=xxx,					# 请求体
	cookies=xxx,				# 要携带的cookie信息(一般在middlewares.py中自定义即可)
	meta=xxx,	               	# 以字典的格式,向其他方法里面传递信息
	encoding='utf-8',			# 字符编码
	priority=0,					# 请求的优先级(数值越低,优先级越高)
	dont_filter=False,         	# 设置请求是否要过滤
	errback=self.handle_err,   	# 当程序处理请求返回有错误时,使用该参数并调用handle_err()函数
)

3》请求方式:
携带的参数相同,如上代码所示。

  • GET请求:调用 yield scrapy.Request() 方法
  • POST请求:调用 yield scrapy.FormRequest() 方法

二、Downloader中间件

主要讲解ProjectDownloaderMiddleware(object)中间件中三个主要的方法!!

def process_request(self, request, spider)

【在request被scarpy引擎调度给Downloader之前调用该方法(即发送请求之前)】
【request参数就是一个request对象,就是当前被处理的request】
【spider就是一个spider对象,就是当前request所对应的spider】

    def process_request(self, request, spider):
        # Called for each request that goes through the downloader
        # middleware.

        # Must either:
        # - return None: continue processing this request       
            
        # - or return a Response object                                 
        
        # - or return a Request object                          
        
        # - or raise IgnoreRequest: process_exception() methods of 
        return None

返回结果解释:

》当返回的结果为None,那么scrapy将继续处理该request,接着执行其他Downloader中间件的process_request()方法,一直到Downloader中间件把request执行后得到response时才结束

》当返回的结果为Response,那么更低优先级(数值越大)的Downloader中间件的process_request()和process_exception()方法就不会被调用,转而调用每个Downloader中间件的process_response()方法,调用完后直接将response对象发送给爬虫文件(spider)进行处理

》当返回的结果为Request,那么更低优先级(数值越大)的Downloader中间件的process_request()方法会停止执行,该request对象会重新放入调度器里面(即转变成一个全新的request,等待被重新依照顺序调度)

》当返回的结果为IgnoreRequest(即有异常),那么所有的Downloader中间件里面的process_exception()方法会被依次执行;如果没有方法去处理该异常,那么request的errback方法就会回调(即爬虫文件(spider)中的request的errback参数),如果该异常还没被处理则会忽略

def process_response(self, request, response, spider)

【当Downloader返回response到爬虫文件(spider)时,可以调用process_response()方法进行处理】
【 request参数就是一个request对象,就是当前response对应的request】
【response参数就是一个response对象,就是当前被处理的response】
【 spider参数就是一个spider对象,就是当前response对应的spider】

    def process_response(self, request, response, spider):
        # Called with the response returned from the downloader.

        # Must either;
        # - return a Response object        
        
        # - return a Request object        
        
        # - or raise IgnoreRequest          
        return response

返回结果解释:

》当返回的结果为Response,那么更低优先级(数值越大)的Downloader中间件的process_response()方法会被继续调用,接着来处理这个response对象

》 当返回的结果为Request,那么更低优先级(数值越大)的Downloader中间件的process_response()方法不会继续被调用。会将该request对象重新放到调度队列中等待被调度(相当于一个全新的request),然后会被process_request()方法顺次处理

》当返回的结果为IgnoreRequest(即有异常),它不会进入到process_exception()方法中,而是直接被爬虫文件(spider)的request里边的errback方法回调,如果该异常还没被处理则会忽略

def process_exception(self, request, exception, spider)

【当有抛出异常,process_exception()方法就会被调用】
【 request参数就是一个request对象,就是产生异常的那个request】
【exception参数就是一个execption对象,就是抛出的异常】
【spider参数就是一个spider对象,就是当前request对应的spider】

    def process_exception(self, request, exception, spider):
        # Called when a download handler or a process_request()
        # (from other downloader middleware) raises an exception.

        # Must either:
        # - return None: continue processing this exception             
        
        # - return a Response object: stops process_exception() chain   
        
        # - return a Request object: stops process_exception() chain   
        pass

返回结果解释:

》当返回的结果为None,那么更低优先级(数值越大)的Downloader中间件的process_execption()方法会被继续的顺次调用,直到所有的方法都被调度完毕

》当返回的结果为Response,那么更低优先级(数值越大)的Downloader中间件的process_execption()方法不会继续被调用,那么所有的Downloader中间件里面的process_response()方法则开始被调用,根据优先级顺次调用

》 当返回的结果为Request,那么更低优先级(数值越大)的Downloader中间件的process_execption()方法也不会继续被调用,该request对象就会被放到调度器里面去,等待调度(相当于一个全新的request),然后request又会被process_request()方法依次进行顺次处理

以上的中间件方法,只要实现至少一个方法就可以定义一个Downloader中间件了!!!

发布了23 篇原创文章 · 获赞 5 · 访问量 5339

猜你喜欢

转载自blog.csdn.net/ytraister/article/details/105318668
今日推荐