爬虫工作量由小到大的思维转变---<第二十八章 Scrapy中间件说明书>

news2024/11/20 13:46:01

爬虫工作量由小到大的思维转变---<第二十六章 Scrapy通一通中间件的问题>-CSDN博客

前言:

(书接上面链接)自定义中间件玩不明白? 好吧,写个翻译的文档+点笔记,让中间件更通俗一点!!!

正文:

全局图:

爬虫中间件--->翻译+笔记:

from scrapy import signals

# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter


class XXXSpiderMiddleware:
    # 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.

    #--翻译-># 并非所有方法都需要被定义。如果某个方法没有被定义,
    # Scrapy 将会假设蜘蛛中间件不会修改传递的对象。

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        #这个方法被用于创建你的Scrapy蜘蛛。
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_spider_input(self, response, spider):
        # Called for each response that goes through the spider
        # middleware and into the spider.

        # Should return None or raise an exception.

        # --翻译--># 这个方法由Scrapy用于创建你的蜘蛛。
        # 对于每个通过蜘蛛中间件到达蜘蛛的响应,会被调用。
        # 应该返回None或引发异常。

        # --->笔记:可以用它
        # 预处理响应数据,例如解析、提取信息、清洗数据等;
        # 对响应进行过滤或过程控制;
        # 处理错误或异常情况;
        # 添加自定义的功能或逻辑。
        # 如果你不希望对响应进行任何修改或处理,你可以简单地返回None。
        return None

    def process_spider_output(self, response, result, spider):
        # Called with the results returned from the Spider, after
        # it has processed the response.

        # Must return an iterable of Request, or item objects.

        #---翻译-->该方法在蜘蛛处理响应并返回结果后被调用。
        # 必须返回一个可迭代的Request对象或item对象。

        '''
        笔记:
        这个方法允许你从蜘蛛处理的结果中进一步操作和处理数据。你可以修改结果,添加、
        删除或筛选特定的数据,或者在结果中创建新的Request对象来进行进一步的爬取。你
        可以通过yield语句将处理后的结果返回。
        总之,process_spider_output方法提供了一个在蜘蛛处理响应结果后对结果进行额外处理的机会,用于进一步定制和控制爬取过程。
        '''
        for i in result:
            yield i

    def process_spider_exception(self, response, exception, spider):
        # 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.
        '''
        翻译:当蜘蛛或 process_spider_input() 方法(来自其他爬虫中间件)引发异常时调用。
        应该返回 None 或者一个可迭代的 Request 或 item 对象。

        笔记:
        1.用于处理当蜘蛛或其他爬虫中间件的 process_spider_input() 方法引发异常时的情况
        2.你可以针对异常情况进行任何处理。可以根据具体需求进行错误处理、记录日志、重新发送请求等操作。
        -->通俗地说,这个方法允许你在蜘蛛或其他爬虫中间件的输入方法引发异常时进行自定义处理。
        你可以根据具体的异常情况进行相应的处理操作,如重新发送请求、记录日志等。

        '''
        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).
        '''
        翻译: 在蜘蛛开始请求时被调用,与 process_spider_output() 方法相似,
             不同之处在于它没有与之关联的响应。

        笔记:
        这个方法允许你在蜘蛛开始请求之前对初始请求进行自定义处理。你可以修改请求对象的属性,
        添加额外的请求,或者根据需求生成新的请求对象
        --->在爬虫开始请求之前提供了一个自定义处理初始请求的机会,用于修改请求参数或生成新的请求对象。
        '''

        for r in start_requests:
            yield r

    def spider_opened(self, spider):
        '''
        翻译:在爬虫开始运行时被调用;

        笔记:你可以用它
        1.初始化一些资源或状态;
        2.打开数据库连接或文件;
        3.设置爬虫的日志输出。..等
        --->可以在这里进行一些准备工作,以确保爬虫在运行时具备必要的环境和配置


        '''
        spider.logger.info("Spider opened: %s" % spider.name)

下载中间件--->翻译+笔记:

class JihaiEndDownloaderMiddleware:
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.
    # -->翻译:# 并非所有方法都需要被定义。如果某个方法没有被定义,
    # # Scrapy 将会假设下载中间件不会修改传递的对象。

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

    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
        #   installed downloader middleware will be called

        '''

         # 对每个通过下载中间件的请求进行处理。

        # 必须返回以下之一:
        # - 返回 None:继续处理该请求
        # - 或返回一个 Response 对象
        # - 或返回一个 Request 对象
        # - 或引发 IgnoreRequest:将调用已安装的下载中间件的 process_exception() 方法
        '''
        return None

    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
        # print(f'中间件接收:{response.text}')

        '''
        # 对从下载器返回的响应进行处理。

        # 必须返回以下之一:
        # - 返回一个 Response 对象
        # - 或返回一个 Request 对象
        # - 或引发 IgnoreRequest
        # print(f'中间件接收:{response.text}')

        '''

        return response

    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

        '''
         # 当下载处理程序或 process_request() 方法(来自其他下载中间件)引发异常时调用。

        # 必须返回以下之一:
        # - 返回 None:继续处理该异常
        # - 返回一个 Response 对象:停止 process_exception() 链
        # - 返回一个 Request 对象:停止 process_exception() 链
        '''
        pass

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

from_crawler(cls, crawler) 方法:

  • 该方法被 Scrapy 用于创建下载中间件实例。
  • 通常用于进行初始化操作和设置信号(Signal)。
  • 推荐用于在下载中间件创建时进行一些必要的准备工作或设置。

process_request(self, request, spider) 方法:

  • 对每个经过下载中间件的请求进行处理。
  • 必须返回以下之一:
  • 返回 None:继续处理该请求

-1.继续处理该请求,将会继续传递给后续的下载中间件处理,直到请求被发送到下载器。
-2.后续的下载中间件将有机会进一步处理请求或对请求进行修改。

  • 或返回一个 Response 对象

-1.将会终止后续的下载中间件的处理,并将该响应传递回爬虫进行处理(即交给响应处理函数)。
-2.后续的下载中间件的 process_request 和 process_response 方法不会再被调用。

  • 或返回一个 Request 对象

-1.将会终止后续的下载中间件的处理,并将该请求重新发送到引擎进行处理。
-2.该请求会经过中间件的处理流程,包括其他的下载中间件。
-3.可以用于对请求进行修改或生成新的请求来重新发起爬取。

  • 或引发 IgnoreRequest,将调用已安装的下载中间件的 process_exception() 方法。

-1.将会停止处理该请求,并调用已安装的其他下载中间件的 process_exception 方法。
-2.这是一个特殊情况,用于处理特定的异常情况或错误。
-3.通常用于处理某个请求无法继续处理的情况,可以选择忽略该请求,或者在 process_exception 方法中进行处理。

  • 用于自定义处理请求的行为,例如添加通用的请求信息、修改请求参数等。

--->补充:   (如果请求有问题)你想让一个request彻底从队列中消失,减少他接下来的生命周期;最直接的办法是引发异常; 如果返回了None他还是会传给spider的;关键取决于你怎么处理你的异常(要不要记录,在哪里记录); 最直接的还是给他引发异常~这样他就直接用日志记录了,不用再脱了裤子放屁跑spider里面去报异常!


process_response(self, request, response, spider) 方法:

  • 对从下载器返回的响应进行处理。
  • 必须返回以下之一:
  • 返回一个 Response 对象

-1.继续处理该响应,将其传递给后续的下载中间件进行处理。
-2.后续的下载中间件将有机会对响应进行进一步处理或对其进行修改。
-3.当没有其他中间件对响应进行进一步处理时,将会将响应传递给爬虫进行处理(即交给响应处理函数)。

  • 或返回一个 Request 对象

-1.将会将该请求重新发送到引擎进行处理,并再次经过下载中间件的处理流程。
-2.可以用于对响应进行处理后生成新的请求,或根据响应内容进行重定向等操作。

补充:重试用它;最好再+一个队列优先级,让这个重试的跑队列前面去,快点消掉关于他附带的(例如item)数据;然后还要注意别让这个请求被重复的url给筛掉了;

案例说明:(`+优先级`和`不去重属性`)

from scrapy import Request

class RetryMiddleware:
    def process_response(self, request, response, spider):
        # 如果返回的响应状态码不是200,则进行重试
        if response.status != 200:
            # 修改原始的请求,并设置新的优先级和去重属性
            retry_request = request.copy()
            retry_request.priority += 1
            retry_request.dont_filter = True  # 设置不进行去重
            return retry_request
        
        return response
  • 或引发 IgnoreRequest。
from scrapy.exceptions import IgnoreRequest

def process_response(self, request, response, spider):
        if response.status >= 400:
           
                   
           raise IgnoreRequest  # 引发 IgnoreRequest 异常

             
        return response

引发 scrapy.exceptions.IgnoreRequest 异常,那么在引发异常后,Scrapy 将会终止当前请求的处理,并跳过后续的中间件和处理流程。--->通俗点:在 Scrapy 中,引发 scrapy.exceptions.IgnoreRequest 异常后,请求将不会传递给后续的中间件和爬虫进行处理。相当于告诉 Scrapy 忽略该请求,并继续处理下一个请求。     (----12月27日补)

  • 用于自定义处理响应的行为,例如解析、提取数据等。


process_exception(self, request, exception, spider) 方法:

  • 当下载处理程序或其他下载中间件的 process_request() 方法引发异常时调用。
  • 必须返回以下之一:
  • 返回 None:继续处理该异常

-1.如果希望继续处理异常并将其传递给其他下载中间件来处理,可以在 process_exception 方法中返回 None,让异常继续传递给后续的处理程序。

补:能给出来异常,这时候最好给他加个记录;然后返回None完事了!

案例:

class CustomDownloaderMiddleware:
    def process_exception(self, request, exception, spider):
        # 其他处理代码...
        
        # 获取异常的URL
        url = request.url
        
        # 使用日志记录器记录异常的URL
        spider.logger.error(f"这个鬼url有问题,咱不要了;给他记一笔: {url}")
        
        return None

  • 返回一个 Response 对象:停止 process_exception() 链
  • 返回一个 Request 对象:停止 process_exception() 链

补:这俩在这方法里,我一般是不搁这处理的;你要自定义玩法,随你...就是用来重试和返回个别的给spider或者队列的

  • 用于自定义处理异常情况,例如处理超时、处理错误状态码等。

spider_opened(self, spider) 方法:

补:--->每次请求开一个spider?怕是有病吧.鸡肋的设计;直接去爬虫中间件里面整这玩意,这里直接给他过掉~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1337722.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ES慢查询分析——性能提升6 倍

问题 生产环境频繁报警。查询跨度91天的数据,请求耗时已经来到了30s。报警的阈值为5s。 背景 查询关键词简单,为‘北京’ 单次仅检索两个字段 查询时间跨度为91天,覆盖数据为450亿数据 问题分析 使用profle分析,复现监控报警的…

Go在Win10上接收UDP组播数据

第一步、绑定本机某张网卡的IP和端口,本代码选择IP为0.0.0.0,端口为8000;第二步、加入组播,组播地址为“224.0.0.1”;第三步、循环接收UDP组播数据; 代码 package mainimport ("fmt""golang…

从 Linux Crontab 到 K8s CronJob,定时任务正在经历怎样的变革

作者:黄晓萌(学仁) 背景 Job 表示短周期的作业,定时 Job 表示按照预定的时间运行Job,或者按照某一频率周期性的运行 Job。比如: 许多传统企业使用 Linux 自带的 crontab 来做定时任务的方案,该方案非常简单&#xff…

“巴渝工匠杯”2022年重庆市职业院校技能大赛(高职组)云计算样题

“巴渝工匠杯”2022年重庆市职业院校技能大赛(高职组)云计算样题 需要软件包环境可私信博主 【赛程名称】云计算赛项第一场次-私有云 某企业拟使用OpenStack搭建一个企业云平台,以实现资源池化弹性管理、企业应用集中管理、统一安全认证和授…

PostGIS学习教程十五:几何图形的有效性

PostGIS学习教程十五:几何图形的有效性 在90%的情况下,“为什么我的查询给了我一个’TopologyException’错误"的问题的答案是"一个或多个输入的几何图形是无效的”,这就引出了这样一个问题:几何图形"无效"是什么意思&a…

从计算机内存结构到iOS

一、冯.诺伊曼结构 当前计算机都是冯.诺伊曼结构(Von Neumann architecture),是指存储器存放程序的指令以及数据,在程序运行时根据需要提供给CPU使用。 冯.诺伊曼瓶颈 在目前的科技水平之下,CPU与存储器之间的读写速…

【C Primer Plus第六版 学习笔记】第十四章 结构和其他数据形式

有基础,进阶用,个人查漏补缺 建立结构声明:描述该对象由什么组成,即结构布局 格式: 关键字 标记(可选){结构 }; 举例: struct book{char title[2];char author[4];float …

Xcode 编译速度慢是什么原因?如何提高编译速度?

作为一个开发者,我们都希望能够高效地开发应用程序,而编译速度是影响开发效率的重要因素之一。然而,有时候我们会发现在使用 Xcode 进行开发时,译速度非常慢,这给我们带来了不少困扰。那么,为什么 Xcode 的…

分页合理化是什么?

一、前言 大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 只要是干过后台系统的同学应该都做过分页查…

神经网络介绍

目录 知识点介绍 知识点介绍 前馈神经网络:(前馈网络的数据只向一个方向传播) RNN循环神经网络,下图中多个 RNN 层都是“同一个层”,这一点与之前的神经网络是不一样的。

怎么下载landsat 8影像并在ArcGIS Pro中进行波段组合

Landsat 8(前身为Landsat数据连续性任务,或 LDCM)于2013年2月11日由 Atlas-V火箭从加利福尼亚州范登堡空军基地发射升空,这里为大家介绍一下该数据的下载的方法,希望能对你有所帮助。 注册账号 如果之前已经注册过的…

5、IDEA集成Git

IDEA集成Git 1. 配置Git忽略文件2. 定位Git程序3. 初始化本地库、添加暂存区、提交到本地库4. 切换版本5. 创建分支和切换分支6. 合并分支7. 解决冲突 1. 配置Git忽略文件 问题1:为什么要忽略他们? 与项目的实际功能无关,不参与服务器上部署…

学习笔记12——Spring的注解配置

学习笔记系列开头惯例发布一些寻亲消息 链接:https://baobeihuijia.com/bbhj/contents/3/192486.html SSM框架——注解配置(Component Autowired 加载SpringConfig) 注解开发(Component注解、config扫描 加载SpringConfig&a…

https密钥认证、上传镜像实验

一、第一台主机通过https密钥对认证 1、安装docker服务 (1)安装环境依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 (2)设置阿里云镜像源 yum-config-manager --add-repo http://mirrors.aliyun.com/do…

EB tresos 配置I2c - 实现与PF8200的读写操作

文章目录 前言一、EB工具链配置1、I2c模块1)新建模块2)配置General3)配置I2cChannel 2、Port模块1)配置SDA2)配置SCL 二、代码分析1、申明一个I2c配置结构体数组,用于I2c所有读操作。2、搭建读操作函数 三、…

GitLab 删除或移动项目

首先明说,删除后无法恢复 第一步:找到要删除的项目 第二步:进入目录后,左侧菜单,设置 >>> 通用,拉到最下面找到“高级”,点击右侧“展开” 第三步:点击“展开”后往下拉&a…

亚马逊云科技 re:Invent 2023 产品体验:亚马逊云科技产品应用实践 王炸产品 Amazon Q,你的 AI 助手

意料之中 2023年9月25日,亚马逊宣布与 Anthropic 正式展开战略合作,结合双方在更安全的生成式 AI 领域的先进技术和专业知识,加速 Anthropic 未来基础模型的开发,并将其广泛提供给亚马逊云科技的客户使用。 亚马逊云科技开发者社…

Python 实现Excel和CSV之间的相互转换

通过使用Python编程语言,编写脚本来自动化Excel和CSV之间的转换过程,可以批量处理大量文件,定期更新数据,并集成转换过程到自动化工作流程中。本文将介绍如何使用第三方库Spire.XLS for Python 实现: 使用Python将Exc…

ServletConfig对象.

是什么 ServletConfig是javax.servlet.包下的一个接口,ServletConfig它是Servlet的一个配置对象; ServletConfig是由tomcat容器创建,通过init方法传入给Servlet; ServletConfig对象如何获取? 在GenericServlet里面定义了&#x…

根据DCT特征训练CNN

记录一次改代码的挣扎经历: 看了几篇关于DCT频域的深度模型文献,尤其是21年FcaNet:基于DCT 的attention model,咱就是说想试试将我模型的输入改为分组的DCT系数,然后就开始下面的波折了。 第一次尝试&#xf…