Python爬虫去重策略:增量爬取与历史数据比对

小白学大数据
• 阅读 23
  1. 引言 在数据采集过程中,爬虫经常需要面对 重复数据 的问题。如果每次爬取都全量抓取,不仅浪费资源,还可能导致数据冗余。增量爬取(Incremental Crawling) 是一种高效策略,它仅抓取 新增或更新 的数据,而跳过已采集的旧数据。 本文将详细介绍 Python爬虫的增量爬取与历史数据比对 策略,涵盖以下内容:
  2. 增量爬取的核心思路
  3. 去重方案对比(数据库、文件、内存)
  4. 基于时间戳、哈希、数据库比对的实现方法
  5. 完整代码示例(Scrapy + MySQL 增量爬取)
  6. 增量爬取的核心思路 增量爬取的核心是 识别哪些数据是新的或已更新的,通常采用以下方式: ● 基于时间戳(Last-Modified / Update-Time) ● 基于内容哈希(MD5/SHA1) ● 基于数据库比对(MySQL/Redis/MongoDB)
  7. 1 基于时间戳的增量爬取 适用于数据源带有 发布时间(如新闻、博客) 的场景:
  8. 记录上次爬取的 最新时间戳
  9. 下次爬取时,只抓取 晚于该时间戳的数据 优点:简单高效,适用于结构化数据 缺点:依赖数据源的时间字段,不适用于无时间戳的网页
  10. 2 基于内容哈希的去重 适用于 内容可能更新但URL不变 的页面(如电商价格):
  11. 计算页面内容的 哈希值(如MD5)
  12. 比对哈希值,若变化则视为更新 优点:适用于动态内容 缺点:计算开销较大
  13. 3 基于数据库比对的增量爬取 适用于 大规模数据管理:
  14. 将已爬取的 URL 或关键字段 存入数据库(MySQL/Redis)
  15. 每次爬取前查询数据库,判断是否已存在 优点:支持分布式去重 缺点:需要额外存储
  16. 去重方案对比 方案 适用场景 优点 缺点 内存去重 单机小规模爬虫 速度快(set() ) 重启后数据丢失 文件存储 中小规模爬虫 简单(CSV/JSON) 性能较低 SQL数据库 结构化数据管理 支持复杂查询(MySQL) 需要数据库维护 NoSQL数据库 高并发分布式爬虫 高性能(Redis/MongoDB) 内存占用较高
  17. 增量爬取实现方法
  18. 1 基于时间戳的增量爬取(示例)
    from datetime import datetime
    

class NewsSpider(scrapy.Spider): name = "news_spider" last_crawl_time = None # 上次爬取的最新时间

def start_requests(self):
    # 从文件/DB加载上次爬取时间
    self.last_crawl_time = self.load_last_crawl_time()

    # 设置代理信息
    proxy = "http://www.16yun.cn:5445"
    proxy_auth = "16QMSOML:280651"

    # 添加代理到请求中
    yield scrapy.Request(
        url="https://news.example.com/latest",
        meta={
            'proxy': proxy,
            'proxy_user_pass': proxy_auth
        }
    )

def parse(self, response):
    # 检查响应状态码,判断是否成功获取数据
    if response.status != 200:
        self.logger.error(f"Failed to fetch data from {response.url}. Status code: {response.status}")
        self.logger.error("This might be due to network issues or an invalid URL. Please check the URL and try again.")
        return

    for article in response.css(".article"):
        pub_time = datetime.strptime(
            article.css(".time::text").get(), 
            "%Y-%m-%d %H:%M:%S"
        )
        if self.last_crawl_time and pub_time <= self.last_crawl_time:
            continue  # 跳过旧文章

        yield {
            "title": article.css("h2::text").get(),
            "time": pub_time,
        }

    # 更新最新爬取时间
    self.save_last_crawl_time(datetime.now())

def load_last_crawl_time(self):
    try:
        with open("last_crawl.txt", "r") as f:
            return datetime.strptime(f.read(), "%Y-%m-%d %H:%M:%S")
    except FileNotFoundError:
        return None

def save_last_crawl_time(self, time):
    with open("last_crawl.txt", "w") as f:
        f.write(time.strftime("%Y-%m-%d %H:%M:%S"))
4.2 基于内容哈希的去重(示例)
``` import hashlib

class ContentHashSpider(scrapy.Spider):
    name = "hash_spider"
    seen_hashes = set()  # 存储已爬取的哈希

    def parse(self, response):
        content = response.css("body").get()
        content_hash = hashlib.md5(content.encode()).hexdigest()

        if content_hash in self.seen_hashes:
            return  # 跳过重复内容

        self.seen_hashes.add(content_hash)
        yield {"url": response.url, "content": content}

4.3 基于MySQL的增量爬取(完整示例) (1)MySQL 表结构

    id INT AUTO_INCREMENT PRIMARY KEY,
    url VARCHAR(255) UNIQUE,
    content_hash CHAR(32),
    last_updated TIMESTAMP
);

(2)Scrapy 爬虫代码

import hashlib
from scrapy import Spider, Request

class MySQLIncrementalSpider(Spider):
    name = "mysql_incremental"
    start_urls = ["https://example.com"]

    def __init__(self):
        self.conn = pymysql.connect(
            host="localhost",
            user="root",
            password="123456",
            db="crawler_db"
        )
        self.cursor = self.conn.cursor()

    def parse(self, response):
        url = response.url
        content = response.text
        content_hash = hashlib.md5(content.encode()).hexdigest()

        # 检查是否已爬取
        self.cursor.execute(
            "SELECT content_hash FROM crawled_data WHERE url=%s",
            (url,)
        )
        result = self.cursor.fetchone()

        if result and result[0] == content_hash:
            return  # 内容未更新

        # 插入或更新数据库
        self.cursor.execute(
            """INSERT INTO crawled_data (url, content_hash, last_updated)
               VALUES (%s, %s, NOW())
               ON DUPLICATE KEY UPDATE 
               content_hash=%s, last_updated=NOW()""",
            (url, content_hash, content_hash)
        )
        self.conn.commit()

        yield {"url": url, "content": content}

    def close(self, reason):
        self.cursor.close()
        self.conn.close()
  1. 结论 策略 适用场景 推荐存储方案 时间戳比对 新闻、博客等带时间的数据 文件/MySQL 内容哈希 动态内容(如商品价格) Redis/内存 数据库去重 结构化数据管理 MySQL/MongoDB 最佳实践: ● 小型爬虫 → 内存去重(set()) ● 中型爬虫 → 文件存储(JSON/CSV) ● 大型分布式爬虫 → Redis + MySQL 通过合理选择增量爬取策略,可以显著提升爬虫效率,减少资源浪费。
点赞
收藏
评论区
推荐文章
Irene181 Irene181
3年前
3000字 “婴儿级” 爬虫图文教学 | 手把手教你用Python爬取 “实习网”!
1\.为"你"而写这篇文章,是专门为那些"刚学习"Python爬虫的朋友,而专门准备的文章。希望你看过这篇文章后,能够清晰的知道整个"爬虫流程"。从而能够"独立自主"的去完成,某个简单网站的数据爬取。好了,咱们就开始整个“爬虫教学”之旅吧!2\.页面分析①你要爬取的网站是什么?首先,我们应该清楚你要爬去的网站是什么?由于这里我们想要
python知道 python知道
3年前
《Python3网络爬虫开发实战》
提取码:1028内容简介······本书介绍了如何利用Python3开发网络爬虫,书中首先介绍了环境配置和基础知识,然后讨论了urllib、requests、正则表达式、BeautifulSoup、XPath、pyquery、数据存储、Ajax数据爬取等内容,接着通过多个案例介绍了不同场景下如何实现数据爬取,后介绍了pyspider框架、S
python爬虫增加多线程获取数据
Python爬虫应用领域广泛,并且在数据爬取领域处于霸主位置,并且拥有很多性能好的框架,像Scrapy、Request、BeautifuSoap、urlib等框架可以实现爬行自如的功能,只要有能爬取的数据,Python爬虫均可实现。数据信息采集离不开Pyt
Karen110 Karen110
3年前
实战|手把手教你用Python爬取存储数据,还能自动在Excel中可视化!
大家好,在之前我们讲过如何用Python构建一个带有GUI的爬虫小程序,很多本文将迎合热点,延续上次的NBA爬虫GUI,探讨如何爬取虎扑NBA官网数据。 并且将数据写入Excel中同时自动生成折线图,主要有以下几个步骤。本文将分为以下两个部分进行讲解在虎扑NBA官网球员页面中进行爬虫,获取球员数据。清洗整理爬取的球员数据,对其进行可视化。
把帆帆喂饱 把帆帆喂饱
3年前
爬虫
爬虫什么是爬虫使用编程语言所编写的一个用于爬取web或app数据的应用程序怎么爬取数据1.找到要爬取的目标网站、发起请求2.分析URL是如何变化的和提取有用的URL3.提取有用的数据爬虫数据能随便爬取吗?遵守robots.txt协议爬虫的分类通用网络爬虫百度,Google等搜索引擎,从一些初识的URL扩展到整个网站,主要为门户站点搜索引擎和大型网站服务采
Stella981 Stella981
3年前
Scrapy笔记(1)
Scrapy笔记01入门篇  Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。其最初是为了页面抓取(更确切来说,网络抓取)所设计的,也可以应用在获取API所返回的数据(比如WebServices)或者通用的网络爬虫。  Scr
Python爬虫过程中DNS解析错误解决策略
在Python爬虫开发中,经常会遇到DNS解析错误,这是一个常见且也令人头疼的问题。DNS解析错误可能会导致爬虫失败,但幸运的是,我们可以采取一些策略来处理这些错误,确保爬虫能够正常运行。本文将介绍什么是DNS解析错误,可能的原因,以及在爬取过程中遇到DN
小白学大数据 小白学大数据
11个月前
Scrapy爬虫:利用代理服务器爬取热门网站数据
在当今数字化时代,互联网上充斥着大量宝贵的数据资源,而爬虫技术作为一种高效获取网络数据的方式,受到了广泛的关注和应用。本文将介绍如何使用Scrapy爬虫框架,结合代理服务器,实现对热门网站数据的高效爬取,以抖音为案例进行说明。1.简介Scrapy是一个强大
小白学大数据 小白学大数据
1星期前
Python爬虫多次请求后被要求验证码的应对策略
在互联网数据采集领域,Python爬虫是一种强大的工具,能够帮助我们高效地获取网页数据。然而,在实际应用中,许多网站为了防止恶意爬取,会在检测到频繁请求时要求用户输入验证码。这无疑给爬虫的正常运行带来了挑战。本文将详细介绍Python爬虫在多次请求后被要求
小白学大数据
小白学大数据
Lv1
男 · 亿牛云 · python技术
宁为代码类弯腰,不为bug点提交!
文章
104
粉丝
5
获赞
18