Scrapy结合Redis实现增量爬取

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Scrapy适合做全量爬取,但是,我们不是一次抓取完就完事了。很多情况,我们需要持续的跟进抓取的站点,增量抓取是最需要的。Scrapy与Redis配合,在写入数据库之前,做唯一性过滤,实现增量爬取。

Scrapy适合做全量爬取,但是,我们不是一次抓取完就完事了。很多情况,我们需要持续的跟进抓取的站点,增量抓取是最需要的。
Scrapy与Redis配合,在写入数据库之前,做唯一性过滤,实现增量爬取。


一、官方的去重Pipeline

官方文档中有一个去重的过滤器:

from scrapy.exceptions import DropItem

class DuplicatesPipeline(object):

    def __init__(self):
        self.ids_seen = set()

    def process_item(self, item, spider):
        if item['id'] in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
        else:
            self.ids_seen.add(item['id'])
            return item

官方的这个过滤器的缺陷是只能确保单次抓取不间断的情况下去重,因为其数据是保存在内存中的,当一个爬虫任务跑完后程序结束,内存就清理掉了。再次运行时就失效了。

二、基于Redis的去重Pipeline

为了能够多次爬取时去重,我们考虑用Redis,其快速的键值存取,对管道处理数据不会产生多少延时。

#pipelines.py

import pandas as pd
import redis
redis_db = redis.Redis(host=settings.REDIS_HOST, port=6379, db=4, password=settings.REDIS_PWD)
redis_data_dict = "f_uuids"

class DuplicatePipeline(object):
    """
    去重(redis)
    """

    def __init__(self):
        if redis_db.hlen(redis_data_dict) == 0:
            sql = "SELECT uuid FROM f_data"
            df = pd.read_sql(sql, engine)
            for uuid in df['uuid'].get_values():
                redis_db.hset(redis_data_dict, uuid, 0)

    def process_item(self, item, spider):

        if redis_db.hexists(redis_data_dict, item['uuid']):
             raise DropItem("Duplicate item found:%s" % item)

        return item
  1. 首先,我们定义一个redis实例: redis_db和redis key:redis_data_dict。
  2. 在DuplicatePipeline的初始化函数init()中,对redis的key值做了初始化。当然,这步不是必须的,你可以不用实现。
  3. 在process_item函数中,判断redis的hash表中存在该值uuid,则为重复item。
    至于redis中为什么没有用list而用hash? 主要是因为速度,hash判断uuid是否存在比list快好几个数据级。
    特别是uuid的数据达到100w+时,hash的hexists函数速度优势更明显。

最后别忘了在settings.py中加上:

# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    'fund_spider.pipelines.DuplicatePipeline': 200,
     #'fund_spider.pipelines.MySQLStorePipeline': 300,
}

三、总结

本文不是真正意义上的增量爬取,而只是在数据存储环节,对数据唯一性作了处理,当然,这样已经满足了大部分的需求。
后续我会实现不需要遍历所有的网页,判断抓取到所有最新的item,就停止抓取。敬请关注!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
7月前
|
NoSQL Redis 数据库
数据传输DTS中金融云跨账号同步Redis,增量校验报错了
【1月更文挑战第16天】【1月更文挑战第80篇】数据传输DTS中金融云跨账号同步Redis,增量校验报错了
108 1
|
7月前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据
|
4月前
|
存储 JSON NoSQL
【redis数据同步】redis-shake数据同步全量+增量
【redis数据同步】redis-shake数据同步全量+增量
|
5月前
|
数据采集 存储 NoSQL
Redis 与 Scrapy:无缝集成的分布式爬虫技术
Redis 与 Scrapy:无缝集成的分布式爬虫技术
|
5月前
|
数据采集 存储 缓存
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
|
6月前
|
Web App开发 iOS开发 Python
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
41 0
|
7月前
|
NoSQL Redis
[Redis]——主从同步原理(全量同步、增量同步)
[Redis]——主从同步原理(全量同步、增量同步)
272 2
|
XML 数据采集 JSON
scrapy_selenium爬取Ajax、JSON、XML网页:豆瓣电影
在网络爬虫的开发过程中,我们经常会遇到一些动态加载的网页,它们的数据不是直接嵌入在HTML中,而是通过Ajax、JSON、XML等方式异步获取的。这些网页对于传统的scrapy爬虫来说,是很难直接解析的。那么,我们该如何使用scrapy_selenium来爬取这些数据格式的网页呢?本文将为你介绍scrapy_selenium的基本原理和使用方法,并给出一个实际的案例。
112 0
|
7月前
|
数据采集 JavaScript 开发者
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
|
7月前
|
数据采集 Python
Scrapy框架 -- 深度爬取并持久化保存图片
Scrapy框架 -- 深度爬取并持久化保存图片
131 0