9回答

4收藏

Scrapy 中有哪些方法可以实现 断点续爬 。

问答交流 问答交流 4510 人阅读 | 9 人回复 | 2019-11-27








考虑到帖子的价值和留存,版主决定保留这位兄台提出的问题。

以下为版主复现:

需要实现的功能:爬虫出现异常停止后,重启爬虫不会重复提取已经爬取过的 URL。

1、现在的实现方式是通过在 pipeline 中调用 bloom 方式判重 URL,如果重复就不写入数据库,但感觉效率不高。(对这种调用方式表示严重怀疑)

每次爬取过程中都会重复全量爬取。

2、查找资料后已知可以通过重写dupefilter 的方式实现:

https://www.cnblogs.com/Alexephor/p/11437061.html

请问有通用方法吗?

脑阔痛!





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
分享到:
回复

使用道具 举报

回答|共 9 个

sfhfpc

发表于 2019-11-27 20:57:48 | 显示全部楼层

你这也太简单了吧,清晰描述需求和自身条件才能得到最优回答啊
回复

使用道具 举报

dirty_dan

发表于 2019-11-27 21:28:38 | 显示全部楼层

url判重很好做的,你这边数据量有多大?
回复

使用道具 举报

yeyang

发表于 2019-11-27 21:31:09 | 显示全部楼层

100万 左右,
回复

使用道具 举报

yeyang

发表于 2019-11-27 21:36:33 | 显示全部楼层

谢了老哥,我这个问题没问对。我先去试试链接里面的方法。 幸苦
回复

使用道具 举报

sfhfpc

发表于 2019-11-27 22:29:46 | 显示全部楼层


要在 Scrapy 框架基础上实现断点续爬,首先要搞清楚的是:为什么 Scrapy 没有自带断点续爬功能?







上面是 Scrapy 框架的结构与工作流程。程序按照规则获取到想要爬的 URL 后会放进待爬队列,然后由 Scheduler 从待爬队列中取出 URL,向这个 URL 发出请求后将它放到已爬队列




由于待爬队列和已爬队列的存在,爬虫程序就知道了哪些是没爬过的,哪些又是已经爬过的,不会三番四次地去敲同一个门。那么问题来了,Scrapy 的队列由程序申请而来,例如 Python 中的 Set 结构。当程序运行完毕或者异常退出后,内存随即被释放掉,待爬队列和已爬队列自然也被释放掉。失去记忆的爬虫在下次启动时自然不会记得泡过哪个妞,敲过哪个门。




如果想要让它保持长久记忆,不会因为程序退出就释放队列,只需要选择那些可以持久存储的容器作为待爬队列和已爬队列。持久存储,MySQL、MongoDB、Redis 甚至 txt 都可以。




以上就是断点续爬的现状和解决思路。



灵魂拷问:如何做呢?



如果比较懒或者时间紧,可以用成熟的库实现,例如 ScrapyRedis。它将待爬队列和已爬队列存储在 Redis 中,这样就算爬虫所在的计算机被水淹了也不会影响存储在云端(你想放在女朋友家也可以)的 Redis,自然就实现了断点续爬。




如果时间比较丰富,喜欢动手鼓捣,那么研究透彻 Scrapy 用到的这两个队列后可以亲手对其进行改造。






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

sfhfpc

发表于 2019-11-27 22:37:55 | 显示全部楼层

至于 bloom fitler 方面,它的主要用途是降低空间复杂度,时间上并不会产生好的效果。
回复

使用道具 举报

yeyang

发表于 2020-3-4 19:25:24 | 显示全部楼层





如果你有判断重复和断点续爬的需求尝试在 settings 里面添加下面的设置



实现需求:

本地需要设置 Redis

安装 scrapy_redis_bloomfilter 库依赖

注意 redis 存储 url 对服务器存储的占用情况






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

鸢公子

发表于 2021-6-25 12:23:55 | 显示全部楼层

# 续爬模式,会自动生成一个crawls文件夹,用于存放断点文件
cmdline.execute('scrapy crawl mySpider -s JOBDIR=crawls/storemySpider'.split())
回复

使用道具 举报

鸢公子

发表于 2021-6-25 12:30:55 | 显示全部楼层





数量少可以用本地文件做续爬

数量多可以用 redis 做(scrapy_redis 的一部分就行)
# ---------------------------------------- 增量/分布式爬虫配置(redis) --------------------------------------
SCHEDULER_PERSIST = True  # 是否持久化(断点续爬)
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"  # Redis 指纹去重
SCHEDULER = "scrapy_redis.scheduler.Scheduler"  # Redis 调度器
REDIS_URL = r"redis://192.168.1.159:6379/2"  # redis_url 配置



spider 里还用原来的 Spider 类就行,如果想改 redis 里的名称就这类属性里加个 redis_key,

要是用 ReidsSpider 就是类似于分布式了,增量用不到,(分布式爬虫本身就是增量式爬虫)



回复

使用道具 举报