一、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中间件了!!!