博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
scrapy进阶开发(四):spiderMiddleware
阅读量:7142 次
发布时间:2019-06-29

本文共 4025 字,大约阅读时间需要 13 分钟。

SpiderMiddleWare的定义

spiderMiddleware 是一个Scrapy的spider处理机制的钩子框架,你可以插入自定义的功能用来处理engine发往spider的response和spider发往engine的request和item

激活SpiderMiddleware

想要激活SpiderMiddleware,需要在settings里配置SPIDER_MIDDLEWARES,这是一个字典dict,key:value对应的是 类路径:顺序,顺序由大到小,越小的越靠近spider,由大的越靠近engine,也就是说,由spider到engine是升序调用,从engine到spider为降序调用

SPIDER_MIDDLEWARES = {    'myproject.middlewares.CustomSpiderMiddleware': 543,    #如果想禁用一个内置的spider,需要将其顺序设置为None    'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': None,}复制代码

定义自己的spider

class scrapy.spidermiddlewares.SpiderMiddleware:    """     这个方法在将response发往spider的过程中被调用    这个方法应该返回None或者raise一个异常    * response:正在响应的处理    * spider:该响应的目标spider    """    def process_spider_input(response, spider):        pass            """    这个方法将在requset或者item发往engine的过程中被调用    这个方法必须返回一个reponse,dict,item    * response:产生该响应对应的response    * result:(一个request,dict,item)由这个spider返回的结果    * spider:该响应的目标spider    """    def process_spider_output(response, result, spider):        pass            """    这个方法将在一个spider或者一个process_spider_input方法抛出异常的时候被调用    这个方法应该返回None或者一个reponse,dict,item    * response :当前的相应    * exception:抛出的异常    * spider:当前的爬虫    """        process_spider_exception(response, exception, spider):        pass        """    这个方法用来处理首次发往engine的请求,和process_spider_output唯一不同的地方是,不接受response,并且只能返回一个request    """    process_start_requests(start_requests, spider):        pass                    """    如果这个方法存在,将用来创建一个middleware实例,并且应该将改实例返回,这个方法接收一个crawler对象,改对象提供了spider的所有核心配置    这提供了一种方法让middleware可以访问其配置并hook住其他的scrapy组件    """    @classmethod        from_crawler(cls, crawler):        pass复制代码

内置的SpiderMiddleware

scrapy内置的SpiderMiddleware 都在scrapy.spiderMiddlewares下面

看一下HttpErrorMiddleware的源码

class HttpErrorMiddleware(object):    @classmethod    def from_crawler(cls, crawler):        """        这个方法将settings传给构造函数,并返回了创建的实例        """        return cls(crawler.settings)    def __init__(self, settings):        """        构造函数        """        # 获取HTTPERROR_ALLOW_ALL配置,改配置是一个布尔类型,声明是否需要spider自己处理所有的http相应状态码        self.handle_httpstatus_all = settings.getbool('HTTPERROR_ALLOW_ALL')        # 获取HTTPERROR_ALLOWED_CODES配合,该配置是一个list,声明spider需要自己处理的http响应状态码        self.handle_httpstatus_list = settings.getlist('HTTPERROR_ALLOWED_CODES')    def process_spider_input(self, response, spider):        """        处理发往spider的相应        """        # 如果是200-300之间的状态码,之间返回由spider处理        if 200 <= response.status < 300:  # common case            return        # 获取元信息         meta = response.meta                # 如果在元信息里包含handle_httpstatus_all这个参数,        # 则说明当前请求相应的所有状态码都需要自己处理,直接返回        if 'handle_httpstatus_all' in meta:            return                    # 同上,只不过这里变成了list            if 'handle_httpstatus_list' in meta:            allowed_statuses = meta['handle_httpstatus_list']                    # 如果配置里声明了需要处理所有的请求,则直接返回            elif self.handle_httpstatus_all:            return        else:        # 如果上面条件全都不满足,则获取当前spider的handle_httpstatus_list属性            allowed_statuses = getattr(spider, 'handle_httpstatus_list', self.handle_httpstatus_list)                # 如果当前的status在运行自己处理的status列表里,则直接返回        if response.status in allowed_statuses:            return                # 如果上面都没有满足,则说明当前status需要由scrapy框架处理,所以抛出一个异常        raise HttpError(response, 'Ignoring non-200 response')    def process_spider_exception(self, response, exception, spider):        """        处理HttpError的异常        """        # 只处理HttpError的异常        if isinstance(exception, HttpError):            # 当前异常状态码出现次数加1            spider.crawler.stats.inc_value('httperror/response_ignored_count')            spider.crawler.stats.inc_value(                'httperror/response_ignored_status_count/%s' % response.status            )            打印日志            logger.info(                "Ignoring response %(response)r: HTTP status code is not handled or not allowed",                {
'response': response}, extra={
'spider': spider}, ) return []复制代码

转载地址:http://mnwgl.baihongyu.com/

你可能感兴趣的文章
大数据应用安全研究报告(11家公司实践详解)
查看>>
MES之殇和工业IOT之春
查看>>
阿里云网络漏洞扫描系统AVDS(商业化)发布
查看>>
python splinter 小坑说明
查看>>
控制input输入格式
查看>>
一次XEN启动中的错误捕获
查看>>
esxi嵌套华为Fusioncomputer安装VRM几个关键步骤。
查看>>
DNS设置引起的登录延迟
查看>>
saltstack之SLS文件
查看>>
JAVA构建缓存
查看>>
解决:Loading kernel module CAP_SYS_MODULE CAP_NET_ADMIN alias netdev-eth0 instead
查看>>
wav2letter-基于深度学习的语音识别
查看>>
Java class.forname()和newinstance
查看>>
学习计划书
查看>>
[iOS Animation]-CALayer 视觉效果
查看>>
wps的ppt放映时不能完全全屏的解决方法
查看>>
我的友情链接
查看>>
本地存储
查看>>
react-native环境配置入坑指南.
查看>>
使用qemu
查看>>