Scrapy深度爬取:优化内部链接与分页处理,避免重复与数据丢失

Scrapy深度爬取:优化内部链接与分页处理,避免重复与数据丢失

本教程旨在解决scrapy爬虫在处理页面内部多层链接和分页时常见的重复数据、数据丢失及不完整问题。通过深入分析`dont_filter`参数滥用、分页逻辑缺陷以及不当的item提交时机,提供一套优化方案,包括启用scrapy内置去重、精确控制分页请求以及确保数据完整性后提交item,从而提高数据抓取的准确性和效率。

Scrapy深度爬取挑战:重复与不完整数据

在使用Scrapy进行网站深度爬取时,尤其当页面包含多层嵌套的内部链接(例如,一个事件页面链接到受害者、恶意软件和威胁源的详细页面),并且网站还采用分页机制时,开发者常常会遇到以下问题:

数据重复: 爬取结果中出现大量重复的记录。数据丢失或跳过: 部分期望抓取的数据(如特定类型的内部链接内容)未能被正确抓取或被意外跳过。数据不完整: 最终导出的数据项缺少部分字段,因为数据在不同回调函数中被分步收集,但未能在正确时机完全合并。

这些问题不仅影响数据质量,也浪费了爬取资源,降低了效率。

问题根源深度剖析

上述问题的出现,往往源于对Scrapy框架机制的误解或不当使用。以下是几个常见且关键的根源:

1. dont_filter=True的滥用

Scrapy内置了一个强大的去重过滤器,它通过记录已访问的请求URL来避免重复爬取。当你在scrapy.Request或response.follow中设置dont_filter=True时,你实际上禁用了这一重要的去重机制。这会导致:

重复请求: 即使某个URL之前已被访问过,Scrapy也会再次发送请求。重复数据: 相同的页面内容可能被多次解析并生成重复的Item。性能下降: 无谓的重复请求增加了服务器负载和爬虫自身的资源消耗。

在处理内部链接时,如果多个路径指向同一个详情页,dont_filter=True会确保这些详情页被重复访问,从而导致数据重复。

2. 不合理的分页处理机制

原始代码中处理分页的逻辑存在效率和正确性问题。它在每次parse方法运行时,都重新获取页面上的所有分页链接,并为它们全部发送请求。这种做法会导致:

无限循环或大量重复请求: 每次进入parse方法,都会重新请求所有已知的分页,包括当前页和之前已处理的页。内存消耗: 维护和处理大量的重复请求会占用不必要的内存。逻辑混乱: 难以追踪哪些页面已被处理,哪些是新页面。

正确的分页处理通常是只请求“下一页”或“未处理的页”。

3. Item提交时机不当

在Scrapy中,yield item操作意味着将一个完整的Item发送到Item Pipeline进行处理。如果在一个Item尚未收集完所有必要数据时就将其yield,或者在后续的回调函数中重复yield同一个Item的不同版本,将导致:

不完整数据: Item在某些字段未填充时就被提交,导致数据缺失。数据重复与覆盖: 同一个逻辑上的数据项,在不同的回调函数中被yield多次,或者部分字段被覆盖,最终在输出中出现多条记录,且每条记录可能只包含部分信息。复杂的状态管理: 在回调链中传递Item并通过meta参数逐步填充是可行的,但这要求严格控制yield的时机,确保只在Item完全构建完毕后才进行。

Scrapy优化策略与最佳实践

针对上述问题,以下是Scrapy爬虫优化的关键策略:

1. 启用Scrapy内置重复请求过滤

核心原则: 除非有非常明确的理由,否则不要禁用Scrapy的去重过滤器。

操作: 从所有scrapy.Request和response.follow调用中移除dont_filter=True参数。Scrapy默认会启用去重,确保每个URL只被请求一次。优势: 自动避免重复爬取相同的页面,显著减少网络请求和数据重复。

2. 精确控制分页逻辑

核心原则: 仅请求下一页,而不是所有分页链接。

操作: 在parse方法中,定位当前页面的“下一页”链接。如果存在,则发送一个针对该链接的请求。示例: 通常可以通过CSS选择器或XPath找到当前页的兄弟节点中的下一页链接。

import scrapyclass IcsstriveSpider(scrapy.Spider):    name = "icsstrive"    start_urls = ['https://icsstrive.com/']    baseUrl = "https://icsstrive.com"    def parse(self, response):        # 1. 提取当前页面的主内容链接并跟进        for link in response.css('div.search-r-title a::attr(href)').getall():            yield response.follow(link, self.parse_icsstrive)        # 2. 精确处理分页:查找并请求下一页        # 假设当前页的
  • 元素有一个特定的class,如'wpv_page_current' # 然后查找其后面的兄弟
  • 元素中的链接 current_page_li = response.css('li.wpv_page_current') next_page_link = current_page_li.xpath("./following-sibling::li/a/@href").get() if next_page_link: # 使用response.urljoin处理相对URL,确保生成完整的URL yield scrapy.Request(response.urljoin(next_page_link), callback=self.parse)
  • 上述代码中,current_page_li.xpath(“./following-sibling::li/a/@href”).get() 能够准确地找到当前页码

    元素后的第一个兄弟元素中的链接,即下一页的链接。通过response.urljoin()可以确保相对路径被正确地转换为绝对路径。

    3. 确保Item完整性后提交

    核心原则: 只有当一个Item的所有预期字段都已收集完毕时,才将其yield。

    针对原问题中多层嵌套链接(受害者、恶意软件、威胁源)的抓取,有两种主要策略:

    策略一:简化Item结构(推荐,如果适用)

    如果目标是收集主页面信息以及所有相关内部链接的列表(而不是深入每个内部链接并将其数据合并到主Item中),可以直接在主解析函数中提取这些链接及其文本,并将其作为列表添加到Item中。这种方法避免了复杂的链式回调和状态管理。

    import scrapyclass IcsstriveSpider(scrapy.Spider):    name = "icsstrive"    start_urls = ['https://icsstrive.com/']    baseUrl = "https://icsstrive.com"    def parse(self, response):        # 提取当前页面的主内容链接并跟进        for link in response.css('div.search-r-title a::attr(href)').getall():            yield response.follow(link, self.parse_icsstrive)        # 分页逻辑(同上)        current_page_li = response.css('li.wpv_page_current')        next_page_link = current_page_li.xpath("./following-sibling::li/a/@href").get()        if next_page_link:            yield scrapy.Request(response.urljoin(next_page_link), callback=self.parse)    def parse_icsstrive(self, response):        # 直接从主页面提取所有相关链接和文本        victims_links = response.xpath("//div[h3[text()='Victims']]//li/a/@href").getall()        victims_text = response.xpath("//div[h3[text()='Victims']]//li//text()").getall() # 提取所有文本,可能需要进一步清洗        malware_links = response.xpath("//div[h3[text()='Type of Malware']]//li/a/@href").getall()        malware_text = response.xpath("//div[h3[text()='Type of Malware']]//li//text()").getall()        threat_source_links = response.xpath("//div[h3[text()='Threat Source']]//li/a/@href").getall()        threat_source_text = response.xpath("//div[h3[text()='Threat Source']]//li/a/text()").getall() # 仅提取链接文本        title = response.xpath('//h1[@class="entry-title"]/text()').get()        # 在所有数据收集完毕后,一次性yield完整的Item        yield {            "title": title,            "victims": victims_text,            "victims_links": victims_links,            "malware": malware_text,            "malware_links": malware_links,            "threat_source_links": threat_source_links,            "threat_source": threat_source_text        }

    这种方法将所有内部链接的URL和显示文本作为列表收集到主Item中,避免了对每个内部链接进行深度爬取并合并数据的复杂性。它适用于当内部链接的详细内容并非必须合并到主Item,或者只需要链接本身信息的情况。

    策略二:链式回调与数据累积(适用于深度合并数据)

    如果确实需要访问每个内部链接,并将其详细内容合并到主Item中,则需要更精细地管理meta参数和yield时机。

    初始化Item: 在parse_icsstrive中创建基础Item,并提取主页面的所有信息。启动链式请求: 如果有victims_url,则发起对第一个victim的请求,并将当前Item和所有剩余的URL列表(包括malwares_urls和threat_source_urls)通过meta传递。逐步填充: 在parse_victims中,填充受害者信息,然后根据meta中的malwares_urls发起对第一个malware的请求,继续传递Item和剩余的URL列表。最终提交: 只有在所有类型的内部链接都被处理完毕(即所有列表都为空)的最后一个回调函数中,才yield最终的、完整的Item。

    这种策略需要更复杂的逻辑来管理meta中的状态和URL列表,确保每次只处理一个子链接,并在其完成后继续处理下一个类型。同时,需要处理列表为空的边缘情况,以确保Item最终能被yield。

    总结与注意事项

    去重是基石: 始终信任并利用Scrapy的内置去重机制,避免滥用dont_filter=True。分页的艺术: 采用“只请求下一页”的策略,避免重复爬取和无限循环。Item的完整性: 明确Item的边界,只在数据完全收集后才yield。对于复杂的多层数据,考虑是直接收集链接列表,还是通过链式回调进行深度合并。如果选择深度合并,务必精心设计meta参数传递和yield时机。XPath/CSS选择器的精确性: 确保选择器能够准确地定位到目标数据,尤其是在处理分页和内部链接时。错误处理: 在实际项目中,还应考虑网络请求失败、页面结构变化等情况,加入适当的错误处理和日志记录。

    通过遵循这些优化策略,Scrapy爬虫将能更高效、准确地完成深度爬取任务,避免常见的重复数据和数据不完整问题。

    以上就是Scrapy深度爬取:优化内部链接与分页处理,避免重复与数据丢失的详细内容,更多请关注创想鸟其它相关文章!

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
    发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1381118.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    深入理解 NumPy reshape:方法与函数的差异及最佳实践
    上一篇 2025年12月14日 22:40:45
    Python子进程的非阻塞I/O与生命周期管理
    下一篇 2025年12月14日 22:41:00

    相关推荐

    • 告别繁琐的字符串处理:使用 nicolasbize/magicsuggest 提升用户体验

      最近,我负责开发一个网站的搜索功能。为了提升用户体验,我需要一个能够提供自动建议的输入框,并且允许用户多选关键词。我尝试过一些其他的自动完成插件,但是它们要么功能不够强大,要么使用起来过于复杂。这时,我发现了nicolasbize/magicsuggest 这个库。 nicolasbize/magi…

      用户投稿 2026年9月3日
      300
    • 微软解释Windows 10 v1809文件覆盖Bug:下月发补丁

      windows 10 版本 1809(2018 年 10 月更新)尽管已被撤回,但依然有部分用户已安装该版本,尤其是在 insiders 内测通道中,因此成为了发现 bug 的测试平台。其中一些 bug 还显得比较基础,例如从 zip 压缩包解压文件时,遇到同名文件不会弹出提示,而是直接覆盖。 微软…

      2026年9月3日
      000
    • win10下载东西被阻止怎么处理

      当您在使用windows 10系统时,有时会遇到下载文件被意外拦截的情况。win10下载文件被拦截怎么办?通常这是由于系统自带的防火墙或安全软件引起的。您可以尝试通过调整注册表设置、切换兼容模式或调整安全选项等方法来解决这个问题。 Win10下载文件被拦截如何解决 方法一:使用兼容模式 右键点击目标…

      2026年9月3日
      100
    • Win7系统关不了机怎么回事?

      Win7系统关不了机怎么回事?Win7系统关不了机怎么回事?Win7系统关不了机怎么回事?Win7系统关不了机怎么回事?

      win7系统是微软推出的一款较为稳定的操作系统,相信不少用户仍在使用它。然而,即便如此,偶尔也会遇到一些小问题,比如关机失败的情况。如果遇到这种情况,不用着急,接下来就为大家介绍win7无法正常关机的一些原因及其解决办法。 许多用户从win10系统切换回win7系统后,可能会发现win7系统偶尔会出…

      2026年9月3日 用户投稿
      000
    • 认识基本的mfc控件

      在#%#$#%@%@%$#%$#%#%#$%@_0f4137ed1502b5045d6083aa258b5c++42程序中,常见的界面元素包括按钮、复选框、文本框和下拉列表等,这些元素被称为控件。许多常用的控件已被集成到操作系统中,在visual c++中,这些控件的使用简便到可以直接通过“拖放”方…

      2026年9月3日
      000
    • win10电脑重启快捷键是哪个

      win10电脑重启快捷键是哪个win10电脑重启快捷键是哪个win10电脑重启快捷键是哪个win10电脑重启快捷键是哪个

      有时我们可能需要重新启动电脑,对于windows 10系统来说,最常见的方式是点击开始菜单中的电源按钮。当然,也可以通过快捷键来快速重启系统。那么,windows 10的电脑重启快捷键是什么呢?接下来,小编就为大家分享这些快捷键。 电脑重启快捷键 方法一 首先打开Windows 10的桌面,确保已经…

      2026年9月3日 用户投稿
      000
    • win10正式版安装后上网速度变慢怎么办

      在使用windows 10正式版的过程中,难免会碰到一些令人头疼的问题,例如升级系统后无法联网、音效消失、程序兼容性差等。这些问题确实会影响我们的使用体验。近期有用户反馈,在升级至windows 10之后,发现网络连接速度明显下降,这无疑会影响到系统的运行效率。那么,面对这一情况,我们应该如何应对呢…

      2026年9月3日
      100
    • Win10怎么重置edge浏览器?

      微软公司推出的edge浏览器是一款相对较新的产品,虽然它与ie浏览器同属一家,但由于其问世时间较短,难免会出现一些小问题。这时,通常会选择重置edge浏览器以解决问题。接下来,让我们一起来看看如何操作吧! 首先,点击屏幕左下角的Windows图标,接着选择“设置”选项。 随后,在设置界面中找到“应用…

      2026年9月3日
      100
    • win10专业版系统打开组策略弹出管理模板提示框?

      win10专业版系统打开组策略弹出管理模板提示框?win10专业版系统打开组策略弹出管理模板提示框?win10专业版系统打开组策略弹出管理模板提示框?win10专业版系统打开组策略弹出管理模板提示框?

      当您使用win10专业版系统时,如果尝试打开组策略编辑器却发现出现了“管理模板”提示框的问题,可以通过以下步骤来修复这一情况。按照下面的操作方法,您可以轻松解决问题。 操作步骤如下: 首先,访问C盘中的Windows文件夹,定位到PolicyDefinitions文件夹。在此文件夹下找到名为“Mic…

      2026年9月3日 用户投稿
      000
    • 百度浏览器广告拦截教程 打造清爽无广告的浏览体验

      百度浏览器广告拦截可通过五种方法实现:1. 使用浏览器自带拦截功能,开启后可屏蔽部分广告,但效果有限;2. 安装adblock、ublock origin等广告拦截插件,拦截效果更强,但可能误杀内容需手动添加白名单;3. 修改hosts文件,通过屏蔽广告域名实现高效拦截,但操作复杂且需管理员权限;4…

      2026年9月3日
      600
    • Win10提示“telnet不是内部或外部命令”怎么办?

      Win10提示“telnet不是内部或外部命令”怎么办?Win10提示“telnet不是内部或外部命令”怎么办?Win10提示“telnet不是内部或外部命令”怎么办?Win10提示“telnet不是内部或外部命令”怎么办?

      最近有部分使用win10系统的用户反馈,在尝试执行telnet命令时,系统会返回提示信息“telnet不是内部或外部命令”。这种情况让许多用户感到困惑,甚至有些不知所措。实际上,这种问题通常源于系统未安装“telnet客户端”功能所致。那么,当win10出现“telnet不是内部或外部命令”的提示时…

      2026年9月3日 用户投稿
      000
    • ntfs和fat32的区别是什么?

      使用过xp和win7系统的朋友们可能会注意到,xp系统的磁盘格式通常是fat32的,而win7系统则是ntfs的。那么,ntfs和fat32之间到底有什么区别呢?别急,今天就让小编来为大家详细讲解一下。 fat32是一种分区格式。它采用32位的文件分配表,这使得fat32在磁盘管理方面的能力得到了显…

      2026年9月3日
      000
    • JavaScript中for循环与onclick事件冲突:如何正确关联循环变量和点击事件?

      JavaScript for循环和onclick事件冲突详解及解决方案 本文分析JavaScript中for循环与onclick事件结合使用时,循环变量值无法正确关联到点击事件的常见问题,并提供解决方案。 问题根源在于onclick事件处理函数的执行时机和JavaScript闭包机制。 问题描述 我…

      2026年9月3日
      000
    • win10电脑怎么连接打印机

      win10电脑怎么连接打印机win10电脑怎么连接打印机win10电脑怎么连接打印机win10电脑怎么连接打印机

      如何连接打印机?在日常工作中,打印机是我们不可或缺的工具之一。那么,在win10系统下如何将打印机与电脑连接起来呢?接下来,就让小编来教大家具体的操作步骤吧。 win10电脑连接打印机 首先,在电脑桌面左下角点击windows图标,然后选择“设置”选项。 进入设置界面后,找到并点击“设备”选项。 在…

      2026年9月3日 用户投稿
      300
    • Win7系统提示“文件丢失”导致无法自动安装驱动怎么办?

      新购置的电脑通常都需要安装驱动程序,但在安装的过程中,有时会出现一些问题。例如,有使用windows 7系统的用户反馈,在安装驱动时突然弹出“文件丢失”或者“找不到指定模块”的提示,从而导致驱动安装中断,只能选择手动安装。而造成“文件丢失”现象的主要原因通常是.dll文件缺失所引发的。 以下是具体的…

      2026年9月3日
      300
    • 深度系统教你解决win10引导坏道修复方法

      深度系统教你解决win10引导坏道修复方法深度系统教你解决win10引导坏道修复方法深度系统教你解决win10引导坏道修复方法深度系统教你解决win10引导坏道修复方法

      在使用电脑的过程中,用户可能会遇到硬盘出现坏道的情况,尤其是win10系统引导区出现问题时,该如何修复呢?通常情况下,逻辑性坏道是可以通过格式化分区来解决的。今天,小编为大家整理了一些相关的解决方案,有需要的朋友可以参考一下。 Win10引导坏道修复方法 第一步,打开“此电脑”窗口。 第二步,点击顶…

      2026年9月3日 用户投稿
      100
    • app制作网站有哪些(手机网页设计制作软件推荐)

      php小编柚子带您了解app制作网站的推荐软件。在如今移动应用繁荣的时代,手机网页设计制作软件至关重要。从专业工具到简单易用的平台,各类软件应有尽有。本文将为您推荐几款优秀的app制作网站工具,让您轻松打造出色的手机网页设计! 1.利用微信小程序开发 如果你想要拥有一个响应式的网站,因为它们开发的网…

      2026年9月3日
      000
    • Win7设备管理器中出现未知设备msft0101的解决方法

      在win7系统里,默认会自动查找并安装驱动程序,然而部分深度技术爱好者可能会注意到,在设备管理器中存在一个带有感叹号的未知设备未成功安装驱动,进一步查看属性时会发现其硬件id显示为“msft0101”。面对这种情况,今天就为大家介绍一种解决win7设备管理器中出现未知设备msft0101的有效办法。…

      2026年9月3日
      100
    • 微软悄悄向Win10 Insider推送新通知选项

      一名 reddit 用户注意到,自 windows 10 build 18917 起,微软已经开始悄然为内测用户提供几项全新的通知设置选项。作为计划于 2020 年春季发布的 windows 10 20h1 更新的一部分,这些改动旨在使 windows 10 的通知功能更加直观易用。 在最新版的预览…

      2026年9月3日
      100
    • windows怎么重启任务栏

      重启Windows任务栏最有效的方法是通过任务管理器结束“Windows资源管理器”进程,系统会自动重启该进程,恢复任务栏功能。此操作可快速解决任务栏无响应、图标消失等问题,无需重启电脑。若问题反复出现,需排查第三方软件冲突、驱动问题或系统文件损坏,并可通过更新驱动、运行SFC/DISM命令、禁用启…

      2026年9月3日
      200

    发表回复

    登录后才能评论
    关注微信