爬虫工作量由小到大的思维转变---<第七十五章 > Scrapy爬虫回调函数在请求重试中的应用研究

前言:

        在Scrapy框架中,利用回调函数进行请求重试的实践方法与其优劣势,与传统的中间件重试机制进行对比。通过深入分析回调函数的工作原理及其在网络爬虫项目中的应用,旨在提高网络爬虫的效率和稳健性。同时,本文将探讨回调函数在Scrapy中的其他功能以及提供一个实际案例,以展示其在解决复杂网络数据采集问题上的实用性。

        之前有对follow和callback进行过讲解,但是我感觉那篇文章没有讲透:
CSDN

正文:

1. 回调函数与中间件的作用

        在Scrapy这个强大的网络爬虫框架中,回调函数和中间件扮演着两个特别重要但又很不一样的角色。

        咱们先来聊聊回调函数。在Scrapy里,回调函数像是个勤劳的指挥官,它告诉Scrapy:“嘿,当你从这个网页上拿到数据后,别忘了把数据拿给我,我来决定下一步干啥。”简单点说,就是你每做一个请求,Scrapy得到响应后,会把这个响应的处理任务交给回调函数。回调函数基于这个响应可能会做很多事情,比如解析数据,继续发起新的请求,或者就是我们今天要重点谈的,做一些错误处理比如请求重试。

        再看看中间件,这货的作用则宽泛而强大。中间件更像是一个全能的助手,它在Scrapy的请求和响应流程中起着桥梁和调节器的作用。无论是处理请求还是响应,中间件都能在其中做一些手脚,比如设置代理、过滤掉一些无用请求、甚至在请求失败时自动重试。所以,它是一个影响全局行为的配置项。

2. 通过回调函数进行请求重试

2.1 回调函数重试的工作原理

        回调函数进行重试的原理其实挺直观的。就像你玩游戏卡关了,决定重来一次,直到过关为止。在Scrapy中,假设发起了一个请求,但这个请求没成功或者成功了但内容不是你想要的。此时,回调函数能够决定“咱们再来一次”,然后重新发起请求,直至满足某条件,比如获取到正确的数据或达到最大重试次数。

2.2 实现回调函数重试的方法

        实现这个机制,主要是依靠Scrapy的Request对象和回调函数。你在回调函数中收到一个响应后,判断它是否满足你的需要,如果不满足,就在那个回调函数里面再次生成一个Request对象,把它yield回给Scrapy,让Scrapy再去调度这个新的请求。重点在于,你可以在这个新的Request中,通过meta参数传递一些信息,比如当前的重试次数,这样就可以控制重试的行为了。

2.3 回调函数重试的优势

        使用回调函数进行请求重试的一大优势在于它的灵活性。你可以根据每个请求的特性和每次响应的具体内容来决定是否需要重试,以及如何重试。这意味着,即使面对一些特殊情况,比如某个页面偶尔会出现莫名的错误,或者是需要检查内容是否包含某些特定的信息,回调函数都能提供个性化的解决方案。

2.4 回调函数重试的劣势

        然而,这种方法并不是完美的,首先,它会让你的Spider代码变得比较复杂,尤其是当你有很多请求需要在失败时重试,而每个请求的重试逻辑又不太一样时。每个回调函数都要包含判断逻辑,检查是否需要重试,这会让代码变得难以维护。再者,重试机制本身就会让爬虫的运行效率降低,因为你需要花额外的时间去重新发起请求和处理。而且,如果没有正确设置停止条件,比如最大重试次数,那么就可能陷入无限重试的循环中,这显然是我们不希望看到的。

3. 与中间件重试机制的对比分析

3.1 中间件重试机制概述

        在Scrapy框架中,中间件重试机制是指系统自带的一个功能,它能在请求因为某些原因失败时自动进行重试。比如说,如果因为网络问题或者服务器暂时不可用导致请求失败,Scrapy会根据设定的重试次数和重试间隔自动重新发起请求。使用这个机制,你只需要在项目的设置里做些简单的配置,比如设置最大重试次数RETRY_TIMES,而无需在代码中明确编写重试逻辑。

3.2 回调函数重试与中间件重试的差异

两者的主要区别在于控制层面和灵活性上。

  • 控制层面:中间件重试是全局的,适用于所有请求;而回调函数重试则可以精确控制到每个请求,根据不同请求的需要定制不同的重试策略。
  • 灵活性:回调函数重试在逻辑上更灵活,你可以根据响应的具体情况决定是否需要重试;中间件重试则主要基于HTTP状态码或网络错误等比较固定的情况进行重试,无法做出更细致的判断。

3.3 应用场景分析

  • 中间件重试非常适合那些因网络问题或服务器错误而需要重试的通用情况。比如,你的爬虫任务主要面向一些相对稳定的网站,且遇到的错误主要是临时的连接问题或者服务器5XX错误。
  • 回调函数重试则更适用于需要根据响应内容或特定业务逻辑来判断是否重试的情况。例如,某些网页可能返回一个空白页或包含特定错误信息,需要根据这些内容来决定是否重新请求。

4. 回调函数的其他功能

回调函数在Scrapy中不仅能用于请求重试,它还有很多其他强大的功能。

4.1 数据解析与处理

通常,回调函数用于解析响应并提取数据。

import scrapyclass MySpider(scrapy.Spider):name = 'example_spider'def start_requests(self):url = 'http://example.com'yield scrapy.Request(url, callback=self.parse)def parse(self, response):item = {}item['title'] = response.css('h1::text').get()# 其他数据提取逻辑...return item
4.2 动态请求调度

回调函数可以用来动态地发起新的请求。

def parse(self, response):next_page = response.css('a.next::attr(href)').get()if next_page:yield response.follow(next_page, self.parse)
4.3 错误处理与日志记录

你可以在回调函数中捕获异常,进行错误处理或记录。

def parse(self, response):try:# 解析逻辑except Exception as e:self.logger.error(f"解析时发生错误:{e}")
4.4 功能扩展示例

假设网站的内容是基于JavaScript动态加载的,你可以使用回调函数结合Scrapy-Splash或Scrapy-Selenium中间件进行处理。

def parse(self, response):script = """function main(splash)splash:go(splash.args.url)splash:wait(0.5)return splash:html()end""" yield scrapy_splash.SplashRequest(url, self.parse_result, endpoint='execute', args={'lua_source': script})def parse_result(self, response):# 解析从Splash处理后的动态内容

通过使用不同的回调函数和Scrapy框架提供的其他组件,你可以为爬取任务增加各种复杂的功能,让爬虫变得更加智能和高效。记住,理论固然重要,但实践才能让知识发挥真正的价值。这里给出的代码和概念只是一个起点,希望能激发你去尝试更多可能性。

补:不论是通过回调函数进行的重试请求 ,还是通过中间件进行的重试请求,他们都会被放到请求队列里进行重新排列 ;而执行顺序,也是跟自己设置的队列请求规则有关!   当然,可以改造的地方,可以在回调函数的时候,给它设置优先级--->这样更加自定义一些!

5. 真实案例研究

5.1 案例背景介绍

        想象我们现在面对的是一个在线图书商城,该商城的书评信息是通过动态加载的方式展现的,而且每次只能通过修改POST请求的参数来获取不同页码的书评数据。为了有效收集这些分散在不同页码的书评,我们计划使用Scrapy框架,通过在回调函数中不断修改请求参数,从而实现对多个页面的书评数据进行爬取。

5.2 采用回调函数处理复杂数据采集的策略

策略主要涉及两个核心思路:

  1. 动态修改POST请求参数:根据当前爬取到的页面信息,修改下一次请求所需要的POST参数(比如页码)。
  2. 重复回调自身:利用回调函数的方式,不断地向服务器发送新的请求,并在回调函数中处理返回的数据,实现对数据的连续爬取。

5.3 代码实现与效果评估

首先定义我们的Spider代码框架:

import scrapyclass BookReviewSpider(scrapy.Spider):name = 'book_review'allowed_domains = ['example.com/bookreviews']start_urls = ['http://example.com/bookreviews']def start_requests(self):for url in self.start_urls:# 假设初次请求页码为1formdata = {'page': '1'}# 初始请求使用POST方法,第一次请求回调函数为 parse_pageyield scrapy.FormRequest(url, formdata=formdata, callback=self.parse_page)def parse_page(self, response):# 处理响应,提取数据...# 假设我们在响应中提取了需要的书评数据# 确定是否还有更多页,如果有则构造新的请求current_page = response.meta.get('page', 1)next_page = current_page + 1if self.has_more_page(response):  # 假设这是我们的逻辑判断是否还有更多页的方法formdata = {'page': str(next_page)}yield scrapy.FormRequest(response.url, formdata=formdata, callback=self.parse_page, meta={'page': next_page})def has_more_page(self, response):# 这里是判断是否有更多页的逻辑,返回True或Falsepass

评估效果主要基于以下几个方面:

  • 数据完整性:检查爬取的书评数据是否完整,是否包含了所有页面上的数据。
  • 请求效率:评估爬虫执行的总时间,检查是否存在不必要的重复请求或者漏掉的数据页。
  • 代码的扩展性和维护性:考虑如果商城增加了新的书籍分类,添加这些分类的数据爬取是否便捷,以及代码是否易于理解和维护。

5.4 案例总结与反思

通过这个案例,我们深入探索了Scrapy回调函数的强大用法,尤其体现在处理需要连续请求同一资源但请求参数变化的场景中。这种方法的优势在于能动态地按需爬取数据,而不是一次性发送大量请求。这对于遵守网站爬取协议、减轻服务器负担是很有好处的。

但也存在一定的挑战和需要注意的点:

  • 逻辑复杂性:随着爬虫逻辑的复杂,特别是在有多个数据页和多种参数变化的情况下,代码的复杂度会上升,需要仔细设计以保持代码的清晰和高效。
  • 错误处理:在中间件自动重试易于管理的同时,回调函数中进行的重试需要更细致地处理请求失败的情况,例如对响应状态码的检查、异常处理等。

总的来说,回调函数在Scrapy爬虫中提供了一种非常灵活的方式来处理复杂的数据爬取需求。通过本案例的实践,我们可以看到运用Scrapy进行数据爬取的强大能力,同时也意识到在实际开发中需要关注的细节和挑战。

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

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

相关文章

服务攻防——应用协议ssh,rsync,proftpd,openssh,libssh

1.口令猜解 ftp-拿来文件传输的 rdp-windows远程连接 3389 ssh-linux远程连接 工具hydra 口令 1.windows 这就爆破成功了,现在,我们就可以ftp爆破,爆破出ftp的密码 爆破出来后 访问 2.ssh Rsync(配置不当,未授权…

【Docker】docker-compose简单实战

1、首先要准备好Jar包 docker-compose.yml version: "2.2.4" services:redis:image: rediscontainer_name: redisvolumes:- /redis/data:/data- /redis/redis.conf://usr/local/etc/redis/redis.confnetworks:- kewu-networkkewu:build:context: .dockerfile: dock…

[NOI Online #2 入门组] 未了

[NOI Online #2 入门组] 未了 题目描述 由于触犯天神,Sisyphus 将要接受惩罚。 宙斯命 Sisyphus 推一块巨石上长度为 L L L 的山坡。Sisyphus 匀速向上推的速度为每年 v v v 的长度(由于是匀速,故经过 1 2 \frac{1}{2} 21​ 年将能向上…

Gooxi发布最新AI服务器:加速生成式AI落地 更懂AI

近日,Gooxi发布最新训推一体AI服务器,以大容量内存和灵活的高速互连选项满足各种AI应用场景,最大可能支持扩展插槽,从而大幅提升智能算力性能,以最优的性能和成本为企业的模型训练推理落地应用提供更好的通用算力。 AI…

主从Reactor服务器

目录: 目录: 目标: 本文讲解思路: 各模块的功能以及代码: 1.服务器相关模块:服务器模块的功能是对所有的连接以及线程进⾏管理 2.协议相关模块:协议模块是对当前的Reactor模型服务器提供应…

【HarmonyOS】Stage 模型 - 应用配置文件

如图所示: Stage 模型应用配置文件主要有两类: 全局配置文件。放在 AppScope 目录下,app.json5。用来配置应用全局的信息。模块配置文件,放在每个模块里,module.json5。用来配置模块的信息。 一、全局配置文件 示…

python的取余与计算商的关系

在Python中,取余数使用的是 % 运算符。它计算一个数除以另一个数的余数,并将结果返回。 例如,如果你执行 a % b,它将返回 a 除以 b 的余数。 这在编程中有很多用途,其中一些包括: 判断奇偶性&#xff1a…

LeetCode1657确定两个字符串是否接近

题目描述 如果可以使用以下操作从一个字符串得到另一个字符串,则认为两个字符串 接近 : 操作 1:交换任意两个 现有 字符。例如,abcde -> aecdb操作 2:将一个 现有 字符的每次出现转换为另一个 现有 字符&#xff0…

【数据可视化01】matplotlib实例3之数据统计

目录 一、引言二、实例介绍1.百分位数为横条形图2.箱线图定制化3.带有自定义填充颜色的箱线图4.箱线图5.箱线图和小提琴图6.二维数据集的置信椭圆 一、引言 matplotlib库 可以用来创建各种静态、动态、交互式的图形,并广泛应用于数据分析和数据可视化领域。 二、实…

通过Doxygen+Breathe+Sphinx生成代码文档

环境 CentOS Linux 7DoxygenBreathe, Sphinx (安装在同一python 环境下) ➜ build yum install doxygen # 安装最新版本的 Sphinx 及依赖。 # -U 将所有指定的软件包升级到最新的可用版本, 依赖项的处理取决于所使用的升级策略。 ➜ build pip3 install -U Sphinx ➜ buil…

Java并发编程——线程基础

Java并发编程的核心之一就是线程(Thread)。线程是程序执行流的最小单元,Java通过线程来实现并发编程。以下是Java线程的一些基础概念: 1. 线程的创建 在Java中,创建线程主要有两种方式: 继承Thread类&am…

贷款中介CRM管理系统解决方案

一、贷款中介行业背景介绍 随着贷款中介行业的快速发展,贷款中介业务逐渐成为企业和个人融资的重要渠道。然而,贷款中介行业存在信息不对称、风险控制不力等难题。给金融稳定带来潜在风险。 二、方案目的和意义 鑫鹿贷款中介系统解决方案旨在规范贷款中…

蓝桥杯单片机组——国赛1 各模块的基础模板

本文为续写个人专栏:蓝桥杯单片机组基础专栏 由于国赛代码体量较为庞大,各个模块涉及时序、消影、去鬼影、消冲突等操作 因此本文基于小蜜蜂老师代码风格编写,并根据实际有改动 本文用于汇总基础的模块程序,更进阶的操作请查看…

Elasticsearch查看集群信息,设置ES密码,Kibana部署

Elasticsearch查看集群信息,设置ES密码,Kibana部署 查看集群信息查看节点信息查看集群健康状态查看分片信息查看其他集群信息 Kibana部署安装设置ES密码 查看集群信息 查看节点信息 curl http://127.0.0.1:9200/_cat/nodes?v 参数说明: ip…

研究生学习---找工作

规划 研一~研二上学期完成小论文,实习,秋招 竞赛:kaggle? 面试题一般简单且为原题,笔试题目很难,不会出原题 项目 找工作软件

SwiftUI中三大渐变色的介绍

在SwiftUI中,渐变色是一种常用的视觉效果,用于创建平滑过渡的颜色变化。通过使用渐变色,我们可以实现丰富多彩的界面设计,增强用户体验。 1. 渐变色的种类和用途 种类: 线性渐变(Linear Gradient&#x…

【时隙ALOHA,CSMA(载波侦听多路访问)carrier sense mltiple access,无线局域网: CSMA/CA】

文章目录 时隙ALOHA时隙ALOHA的效率( Efficiency )纯ALOHA(非时隙)----效率低CSMA(载波侦听多路访问)carrier sense mltiple accessCSMA冲突CSMA/CD(冲突检测)边说边听(提高了信道利用率)以太网就是用的这个无线局域网: CSMA/CA无线局域网中的 MAC&#…

Transformer+Classification学习笔记

论文名称:An Image is Worth 16x16 Words:Transformers for Image Recognition at Scale [2112.11010] MPViT: Multi-Path Vision Transformer for Dense Prediction (arxiv.org) 参考博客与视频: Vision Transformer 超详细解读 (原理分析代码解读) …

2024年了,Covid19怎么发?PANoptosis程序性死亡,抓紧上车!

说在前面 大家众所周知的新冠,其实早在19年末,20年初的时候很多人都抓住了这个热点发到了好文章,Covid-19,这玩意可以做到让一个期刊从2分飙升到20分,且非预警期刊,不过现在退火了,今年是12.7分…

数据结构(十四)----排序算法(1)

目录 一.排序的基本概念 二.插入排序 1.直接插入排序 2.折半插入排序 三.希尔排序(Shell Sort) 四.交换排序 1.冒泡排序 2.快速排序 快速排序算法的效率: 快速排序算法的稳定性: 这一篇博客的重点主要是快速排序&#x…