首页 > 其他分享 >scrapy框架之中间件

scrapy框架之中间件

时间:2024-04-06 16:00:56浏览次数:25  
标签:框架 process request 中间件 spider 爬虫 scrapy response

一、中间件介绍

中间件是 Scrapy 里面的一个核心概念。使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫。

“中间件”这个中文名字和前面章节讲到的“中间人”只有一字之差。它们做的事情确实也非常相似。中间件和中间人都能在中途劫持数据,做一些修改再把数据传递出去。不同点在于,中间件是开发者主动加进去的组件,而中间人是被动的,一般是恶意地加进去的环节。中间件主要用来辅助开发,而中间人却多被用来进行数据的窃取、伪造甚至攻击。

在Scrapy中有两种中间件:下载器中间件(Downloader Middleware)和爬虫中间件(Spider Middleware)。

ps:中间件离哪个模块近就称为什么中间件,另外平时主要用下载中间件,因为爬虫中间件使用方法和下载中间件相同,且功能重复,所以通常使用下载中间件。

二、中间件的作用

中间件可以用于修改Scrapy请求和响应的行为,例如更改请求头、处理代理、处理cookies、实现自定义的重试策略、实现自定义的下载延迟逻辑等。

  1. 修改请求和响应:中间件可以拦截请求和响应,对其进行修改或添加额外信息,如修改请求头、添加代理、处理cookies等。
  2. 处理异常:中间件可以捕获和处理请求过程中的异常,实现自定义的异常处理逻辑。
  3. 实现下载延迟:可以在中间件中实现自定义的下载延迟逻辑,控制请求发送的时间间隔。
  4. 实现自定义的重试策略:通过中间件可以实现自定义的重试逻辑,例如根据特定的条件决定是否重新发送请求。
  5. 处理HTTP代理:中间件可以实现代理的切换和管理,以便在爬取过程中使用不同的代理IP。
  6. 日志记录:中间件可以用于记录请求、响应的信息,方便调试和监控爬虫的运行状态。
  7. 数据处理:可以在中间件中对爬取到的数据进行处理,如数据清洗、格式转换等。

通过编写自定义的中间件,用户可以灵活地扩展和定制Scrapy框架的功能,以满足特定的爬取需求和处理逻辑。 Scrapy提供了一系列的中间件接口,用户可以根据自己的需求实现这些接口来编写自己的中间件

三、爬虫中间件

1、源码

# 爬虫中间件
class ScrapydemmoSpiderMiddleware:
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the spider middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # 该方法是Scrapy用于创建爬虫实例的方法。
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_spider_input(self, response, spider):
        # 当响应从爬虫中间件进入爬虫时,调用该方法进行处理。
        # 应返回None或引发异常。
        # Called for each response that goes through the spider
        # middleware and into the spider.
        # Should return None or raise an exception.
        return None

    def process_spider_output(self, response, result, spider):
        # 当爬虫处理完响应后,调用该方法对处理结果进行处理。
        # 必须返回一个可迭代的Request对象或item对象。
        # Called with the results returned from the Spider, after
        # it has processed the response.

        # Must return an iterable of Request, or item objects.
        for i in result:
            yield i

    def process_spider_exception(self, response, exception, spider):
        # 当爬虫中抛出异常时,调用该方法进行处理。
        # 应返回None或者一个可迭代的Request对象或item对象。
        # Called when a spider or process_spider_input() method
        # (from other spider middleware) raises an exception.

        # Should return either None or an iterable of Request or item objects.
        pass

    def process_start_requests(self, start_requests, spider):
        # 在爬虫启动时,对初始请求进行处理。
        # Called with the start requests of the spider, and works
        # similarly to the process_spider_output() method, except
        # that it doesn’t have a response associated.

        # Must return only requests (not items).
        for r in start_requests:
            yield r

    def spider_opened(self, spider):
        spider.logger.info("Spider opened: %s" % spider.name)

2、方法介绍

(1)def from_crawler(cls, crawler)

from_crawler 方法是一个类方法,它会在创建爬虫实例时被Scrapy调用,用于初始化爬虫中间件的实例。在该方法中,首先创建了一个中间件实例 s,然后通过 crawler.signals.connect 方法连接了 spider_opened 信号和对应的处理方法。

(2)def process_spider_input(self, response, spider)

process_spider_input 方法会在响应从爬虫中间件传递到爬虫之前调用。它接收两个参数:response 是响应对象,spider 是当前爬虫实例。这个方法可以用来对响应进行预处理或检查。应该返回 None 或引发异常。

(3)def process_spider_output(self, response, result, spider)

process_spider_output 方法在爬虫处理完响应后会被调用。它接收三个参数:response 是爬虫处理后的响应对象,result 是爬虫的处理结果,spider 是当前爬虫实例。这个方法主要用于对爬虫处理结果进行进一步处理或过滤,并将处理结果返回。必须返回一个可迭代的Request对象或item对象。

(4)def process_spider_exception(self, response, exception, spider)

process_spider_exception 方法在爬虫或 process_spider_input() 方法中抛出异常时会被调用。它接收三个参数:response 是发生异常的响应对象,exception 是抛出的异常对象,spider 是当前爬虫实例。这个方法可以用来对爬虫处理过程中的异常进行处理,可以返回 None 或一个可迭代的Request对象或item对象。

(5)def process_start_requests(self, start_requests, spider)

process_start_requests 方法在爬虫启动时被调用,用于对初始请求进行处理。它接收两个参数:start_requests 是初始请求的列表,spider 是当前爬虫实例。这个方法必须返回一个可迭代的Request对象,而不能返回item对象。

(6)def spider_opened(self, spider)

spider_opened 方法在爬虫打开时被调用。它接收一个参数 spider,表示当前爬虫实例。在这个方法中,通过日志记录器(logger)输出 "Spider opened: 爬虫名称" 的信息。

(7)激活SpiderMiddleware

SPIDER_MIDDLEWARES = {
   "ScrapyDemmo.middlewares.ScrapydemmoSpiderMiddleware": 543,
}

四、下载中间件

1、源码

# 下载中间件
class ScrapydemmoDownloaderMiddleware:
    # 不是所有的方法都需要定义。如果某个方法没有被定义,
    # Scrapy会认为这个下载中间件不会修改传递的对象。

    @classmethod
    def from_crawler(cls, crawler):
        # Scrapy使用该方法创建您的爬虫。
        s = cls()
        # 通过signals连接spider_opened信号和spider_opened方法
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s
	
    # 拦截处理所有的请求对象
    # 参数:request就是拦截到的请求对象,spider爬虫文件中爬虫类实例化的对象
    # spider参数的作用可以实现爬虫类和中间类的数据交互
    def process_request(self, request, spider):
        # 返回None:继续处理本次请求,执行下一个中间件的process_request方法
        # 返回一个Response对象:执行当前中间件的process_response方法,重新回到引擎,被调度
        # 返回一个Request对象:直接返回给引擎,被调度。进入调度器等待下次被调用
        # 抛出IgnoreRequest异常:调用已安装的下载中间件的process_exception方法
        return None
	
    # 拦截处理所有的响应对象
    # 参数:response就是拦截到的响应对象,request就是被拦截到响应对象对应的唯一的一个请求对象
    def process_response(self, request, response, spider):
        # - 返回一个Response对象:继续执行,进入引擎,被调度到爬虫进行解析
        # - 返回一个Request对象:进入引擎,返回到调度器被重新调用
        # - 或者抛出IgnoreRequest异常:抛出异常
        return response
	
    # 拦截和处理发生异常的请求对象
    # 参数:reqeust就是拦截到的发生异常的请求对象
    # 方法存在的意义:将发生异常的请求拦截到,然后对其进行修正
    def process_exception(self, request, exception, spider):
        # 当下载处理程序或process_request()方法(来自其他下载中间件)引发异常时调用。

        # 必须返回以下之一:
        # - 返回None:继续处理该异常
        # - 返回一个Response对象:停止process_exception()链
        # - 返回一个Request对象:停止process_exception()链
        pass
	
    # 控制日志数据的(忽略)
    def spider_opened(self, spider):
        spider.logger.info("Spider opened: %s" % spider.name)

2、方法介绍

(1)process_request(self, request, spider)

【此方法是用的最多的】

  • 当每个request通过下载中间件时,该方法被调用。
  • 返回None值:没有return也是返回None,该request对象传递给下载器,或通过引擎传递给其他权重低的process_request方法 【如果所有的下载器中间件都返回为None,则请求最终被交给下载器处理】
  • 返回Response对象:不再请求,把response返回给引擎 【如果返回为请求,则将请求交给调度器】
  • 返回Request对象:把request对象通过引擎交给调度器,此时将不通过其他权重低的process_request方法 【将响应对象交给spider进行解析】

参数

  • request(Request 对象)–处理的request
  • spider(Spider 对象)–该request对应的spider

(2)process_response(self, request, response, spider)

  • 当下载器完成http请求,传递响应给引擎的时候调用
  • 返回Resposne:通过引擎交给爬虫处理或交给权重更低的其他下载中间件的process_response方法 【如果返回为请求,则将请求交给调度器】
  • 返回Request对象:通过引擎交给调取器继续请求,此时将不通过其他权重低的process_request方法 【将响应对象交给spider进行解析】
  • 在settings.py中配置开启中间件,权重值越小越优先执行 【同管道的注册使用】

参数

  • request (Request 对象) – response所对应的request
  • response (Response 对象) – 被处理的response
  • spider (Spider 对象) – response所对应的spider

(3)process_exception(request, exception, spider)

当下载处理器(download handler)或 process_request() (下载中间件)抛出异常(包括IgnoreRequest异常)时,Scrapy调用 process_exception() 。

process_exception() 应该返回以下之一: 返回 None 、 一个 Response 对象、或者一个 Request 对象。

  • 如果其返回 None ,Scrapy将会继续处理该异常,接着调用已安装的其他中间件的 process_exception() 方法,直到所有中间件都被调用完毕,则调用默认的异常处理。
  • 如果其返回一个 Response 对象,则已安装的中间件链的 process_response() 方法被调用。Scrapy将不会调用任何其他中间件的 process_exception() 方法。
  • 如果其返回一个 Request 对象, 则返回的request将会被重新调用下载。这将停止中间件的 process_exception() 方法执行,就如返回一个response的那样。

参数

  • request (是 Request 对象) – 产生异常的request
  • exception (Exception 对象) – 抛出的异常
  • spider (Spider 对象) – request对应的spider

(4)激活Downloader Middleware

DOWNLOADER_MIDDLEWARES = {
    "ScrapyDemmo.middlewares.ScrapydemmoDownloaderMiddleware": 543,
}

标签:框架,process,request,中间件,spider,爬虫,scrapy,response
From: https://www.cnblogs.com/xiao01/p/18117502

相关文章

  • Golang中的强大Web框架Fiber详解
    Golang 取消首页编程手机软件硬件安卓苹果手游教程平面服务器首页 > 脚本专栏 > Golang >Golang Web框架FiberGolang中的强大Web框架Fiber详解2023-10-2410:31:51 作者:技术的游戏在不断发展的Web开发领域中,选择正确的框架可以极大地影响项目的效......
  • 中间件 ZK分布式专题与Dubbo微服务入门 8-2 dubbo 入门简介
    0课程地址https://coding.imooc.com/lesson/201.html#mid=12740 1重点关注1.1本节内容dubbo环境搭建版本及入门简介 1.2环境版本要求dubbo2.5.3及其以上jdk6及其以上maven3及其以上 1.3为什么要用dubbo......
  • selenium框架之无头浏览器
    一、无头浏览器介绍无头浏览器(HeadlessBrowser)是一种没有图形用户界面(GUI)的网络浏览器,它可以在后台运行并执行网页操作,而不需要打开一个可见的浏览器窗口。无头浏览器可以模拟用户在浏览器中执行的各种操作,例如加载网页、点击链接、填写表单等,但所有这些操作都在不可见的情况下......
  • scrapy框架之持久化存储
    一、为什么需要持久化存储?持久化存储是指将数据在程序结束后仍然保持在存储介质中的能力。这种存储方式对于许多应用程序和系统至关重要,原因如下:数据持久性:持久化存储确保数据在程序关闭后不会丢失。这对于需要长期保存数据的应用程序至关重要,如数据库系统、文件存储等。......
  • scrapy框架之基本使用
    一、需要了解的命令1、查看帮助scrapy-hscrapy<command>-h第一个命令用于查看全部可用命令的帮助信息第二个命令用于查看特定命令的帮助信息2、全局命令和项目命令Project-only必须切到项目文件夹下才能执行Global的命令则不需要Globalcommands:startproject#......
  • scrapy框架之介绍与安装
    一、Scrapy前言Scrapy是由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据,只需要实现少量的代码,就能够快速的抓取。目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(......
  • 上海天翼云代理商:分布式消息服务Kafka高吞吐、高可用的消息中间件服务
    上海天翼云代理商:分布式消息服务Kafka高吞吐、高可用的消息中间件服务简介:飞机@luotuoemo本文由(天翼云代理商:【金推云】www.jintui.cn)撰写天翼云:领航分布式消息服务的行业先锋在当前的大数据时代,如何有效地处理和管理海量数据已成为企业的关键挑战之一。这里,我们要引入一......
  • 从0到1搭建一个Vue3+Electron的框架
    1.前言:上篇文章中使用到了Vue+Electron框架,这一篇文章主要讲解这个框架如何搭建2.Vue3+Vite项目搭建执行命令行,创建Vue3+Vite脚手架:npmcreatevite或yarncreatevite修改脚手架中的无用部分删除src/components下的所有文件修改src/App.vue内容<!--*@......
  • Java毕业设计-基于SSM框架的高校二手交易平台系统项目实战(附源码+LW+演示视频)
    大家好!我是岛上程序猿,感谢您阅读本文,欢迎一键三连哦。......
  • Vue前端框架
     1.vue基本使用11.vue环境搭建一般创建vue项目是在cmd命令中用:vueui命令,采用ui图形界面的方式直观创建项目。2.vue基本使用方式:vue组件3.文本插值4.属性绑定5.事件绑定6.双向绑定7.条件渲染2.vue基本使用21.axios安装axios命令:npminstallaxios......