分布式爬蟲去重:Python + Redis實現高效URL去重

1. 引言

在互聯網數據采集(爬蟲)過程中,URL去重是一個關鍵問題。如果不對URL進行去重,爬蟲可能會重復抓取相同頁面,導致資源浪費、數據冗余,甚至觸發目標網站的反爬機制。

對于單機爬蟲,可以使用Python內置的**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">set()</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">dict</font>**進行去重,但在分布式爬蟲環境下,多個爬蟲節點同時工作時,內存級的去重方式不再適用。此時,需要一個共享存儲來管理已爬取的URL,而Redis憑借其高性能、低延遲和分布式支持,成為理想選擇。

2. URL去重的常見方法

2.1 基于內存的去重(單機適用)

Python **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">set()</font>**
最簡單的去重方式,適用于小規模數據,但無法持久化,重啟后數據丟失。

visited_urls = set()
if url not in visited_urls:visited_urls.add(url)# 抓取邏輯
  • Bloom Filter(布隆過濾器)
    節省內存,但有一定誤判率(可能誤判未訪問的URL為已訪問),適用于海量URL去重。

2.2 基于數據庫的去重(分布式適用)

  • Redis Set / Redis HyperLogLog
    • **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">SET</font>** 結構存儲URL,精確去重(100%準確)。
    • **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">HyperLogLog</font>** 適用于統計不重復元素數量(有一定誤差,但占用內存極小)。
  • 關系型數據庫(MySQL, PostgreSQL)
    通過**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">UNIQUE</font>**約束去重,但性能較低,不適合高并發爬蟲。
  • 分布式鍵值存儲(如Memcached)
    類似Redis,但功能較少,通常僅用于緩存。

3. Redis 在分布式爬蟲去重中的優勢

Redis 是一個高性能的內存數據庫,支持多種數據結構,適用于分布式爬蟲去重,主要優勢包括:

  1. 高性能:數據存儲在內存中,讀寫速度極快(10萬+ QPS)。
  2. 持久化:支持RDB/AOF持久化,避免數據丟失。
  3. 分布式支持:可通過集群模式擴展,支持多爬蟲節點共享數據。
  4. 豐富的數據結構**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">SET</font>**(精確去重)、**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">HyperLogLog</font>**(近似去重)、**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Bitmap</font>**(位圖去重)等。

4. Python + Redis 實現分布式URL去重

4.1 方案1:使用 Redis Set 精確去重

import redisclass RedisUrlDedupe:def __init__(self, redis_host='localhost', redis_port=6379, redis_db=0):self.redis = redis.StrictRedis(host=redis_host, port=redis_port, db=redis_db)self.key = "visited_urls"def is_visited(self, url):"""檢查URL是否已訪問"""return self.redis.sismember(self.key, url)def mark_visited(self, url):"""標記URL為已訪問"""self.redis.sadd(self.key, url)# 示例用法
deduper = RedisUrlDedupe()
url = "https://example.com/page1"if not deduper.is_visited(url):deduper.mark_visited(url)print(f"抓取: {url}")
else:print(f"已訪問: {url}")

優點

  • 100% 準確,無誤差。
  • 適用于中小規模爬蟲(百萬級URL)。

缺點

  • 存儲所有URL,內存占用較高。

4.2 方案2:使用 Redis HyperLogLog 近似去重

如果允許少量誤差(~0.8%),可使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">HyperLogLog</font>**節省內存:

class RedisHyperLogLogDedupe:def __init__(self, redis_host='localhost', redis_port=6379, redis_db=0):self.redis = redis.StrictRedis(host=redis_host, port=redis_port, db=redis_db)self.key = "hll_visited_urls"def is_visited(self, url):"""檢查URL是否可能已訪問(可能有誤判)"""before = self.redis.pfcount(self.key)after = self.redis.pfadd(self.key, url)return after == 0  # 如果添加后計數未變,說明可能已存在# 示例用法
hll_deduper = RedisHyperLogLogDedupe()
url = "https://example.com/page1"if not hll_deduper.is_visited(url):print(f"抓取: {url}")
else:print(f"可能已訪問: {url}")

優點

  • 內存占用極低(12KB可存儲數億URL)。
  • 適用于超大規模爬蟲(如全網爬取)。

缺點

  • 有少量誤判(可能將未訪問的URL誤判為已訪問)。

4.3 方案3:使用 Redis Bloom Filter(需安裝RedisBloom模塊)

Redis 官方提供 RedisBloom 模塊,支持布隆過濾器(需額外安裝):

# 需確保Redis服務器加載了RedisBloom模塊
class RedisBloomFilterDedupe:def __init__(self, redis_host='localhost', redis_port=6379, redis_db=0):self.redis = redis.StrictRedis(host=redis_host, port=redis_port, db=redis_db)self.key = "bloom_visited_urls"def is_visited(self, url):"""檢查URL是否可能已訪問(可能有誤判)"""return self.redis.execute_command("BF.EXISTS", self.key, url)def mark_visited(self, url):"""標記URL為已訪問"""self.redis.execute_command("BF.ADD", self.key, url)# 示例用法
bloom_deduper = RedisBloomFilterDedupe()
url = "https://example.com/page1"if not bloom_deduper.is_visited(url):bloom_deduper.mark_visited(url)print(f"抓取: {url}")
else:print(f"可能已訪問: {url}")

優點

  • 內存占用低,誤判率可控。
  • 適用于海量URL去重。

缺點

  • 需要額外安裝RedisBloom模塊。

5. 性能優化與對比

方法準確率內存占用適用場景
Redis Set100%中小規模爬蟲(<1000萬URL)
Redis HyperLogLog~99.2%極低超大規模爬蟲(允許少量誤判)
Redis Bloom Filter可調海量URL(需額外模塊)

優化建議

  1. 短URL優化:存儲URL的MD5或SHA1哈希值(減少內存占用)。
  2. 分片存儲:按域名或哈希分片,避免單個Key過大。
  3. TTL過期:設置過期時間,避免長期累積無用URL。

6. 結論

在分布式爬蟲中,Redis 是URL去重的理想選擇,支持多種數據結構:

  • 精確去重**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Redis Set</font>**
  • 低內存消耗**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">HyperLogLog</font>**
  • 可控誤判率**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Bloom Filter</font>**

通過合理選擇方案,可以顯著提升爬蟲效率,避免重復抓取。本文提供的Python代碼可直接集成到Scrapy或其他爬蟲框架中,助力高效數據采集。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904985.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904985.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904985.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# WPF 顏色拾取器

x:Name=Color Picker 語言:C# WPF 下載:https://download.csdn.net/download/polloo2012/90780640 主界面 顏色庫 關于我們 顏色拾取器是一種能夠幫助用戶獲取顏色信息,并進行顏色選擇、識別和調整的工具,以下將從其常見類型、使用場景及部分軟件工具這幾個維度展開介紹…

Git 使用的全流程以及SourceTree工具的使用操作和忽略文件的配置

1. 安裝 Git 要使用 Git&#xff0c;首先得在你的系統上安裝它。你可以按照不同操作系統的安裝指南來操作&#xff1a; Windows&#xff1a;訪問 Git 官方下載頁面&#xff0c;下載安裝程序并運行。 macOS&#xff1a;可以使用 Homebrew 來安裝&#xff0c;命令為 brew inst…

《深入理解Linux網絡》筆記

《深入理解Linux網絡》筆記 前言參考 前言 前段時間看了《深入理解Linux網絡》這本書&#xff0c;雖然有些地方有以代碼充篇幅的嫌疑&#xff0c;但總體來說還是值得一看的。在這里簡單記錄一下筆記&#xff0c;記錄下對網絡新的理解。 內核是如果接受網絡包的&#xff1f; 如…

數倉-可累計,半累加,不可累加指標,是什么,舉例說明及解決方案

目錄 1. 可累計指標定義&#xff1a;舉例&#xff1a;解決方案&#xff1a; 2. 半累加指標定義&#xff1a;舉例&#xff1a;解決方案&#xff1a; 3. 不可累加指標定義&#xff1a;舉例&#xff1a;解決方案&#xff1a; 4. 總結對比5. 實際場景中的注意事項 這是數據倉庫設計…

NestJS 的核心構建塊有哪些?請簡要描述它們的作用(例如,Modules, Controllers, Providers)

NestJS 核心構建塊解析&#xff08;Modules、Controllers、Providers&#xff09; NestJS 是一個基于 TypeScript 的漸進式 Node.js 框架&#xff0c;核心設計借鑒了 Angular 的模塊化思想。下面從實際開發角度解析它的三大核心構建塊&#xff0c;并附代碼示例和避坑指南。 一…

vue2 上傳pdf,拖拽蓋章,下載圖片

效果圖片&#xff1a; 不多廢話上代碼&#xff1a; <template><div class"pdf-stamp" onbeforecopyreturn false onselectdocument.selection.empty() ondragstartreturn false onselectstart return false ><div class"scroll-box" scro…

理性地傾聽與表達:檢索算法的語言學改進

論文標題 Rational Retrieval Acts: Leveraging Pragmatic Reasoning to Improve Sparse Retrieval 論文地址 https://arxiv.org/pdf/2505.03676 代碼地址 https://github.com/arthur-75/Rational-Retrieval-Acts 作者背景 巴黎薩克雷大學&#xff0c;索邦大學&#xff…

MySQL及線程關于鎖的面試題

目錄 1.了解過 MySQL 死鎖問題嗎&#xff1f; 2.什么是線程死鎖&#xff1f;死鎖相關面試題 2.1 什么是死鎖&#xff1a; 2.2 形成死鎖的四個必要條件是什么&#xff1f; 2.3 如何避免線程死鎖&#xff1f; 3. MySQL 怎么排查死鎖問題&#xff1f; 4.Java線上死鎖問題如…

【Reality Capture 】Reality Capture1.5中文版安裝教程(附安裝包下載)

文章目錄 一、Reality Capture1.5中文版安裝教程二、拷貝中文補丁三、Reality Capture1.5中文版下載地址一、Reality Capture1.5中文版安裝教程 1. Reality Capture v1.4.0漢化版安裝包下載并解壓 2. 運行EpicInstaller-15.17.1-4a91a118786f4c2aa3c0093b23f83863.msi 3. 更改…

SVG數據可視化設計(AI)完全工作流解讀|計育韜

AI 的 SVG 創作極限在哪里&#xff1f;絕不是那些初級的流程圖生成和粗糙的商業模型設計。以下是由我們 JZ Creative Studio 通過 Claude 和 Deepseek 開展的專業級 SVG Data Visualization 創作&#xff0c;應廣大讀者強烈要求&#xff0c;專程直播講授了一期 AI 工作流分享。…

not a genuine st device abort connection的問題

1.魔法棒里面電機Settings 2.然后在Other里面把Enabled的鉤子去掉

uv簡單使用

通過uv創建項目和虛擬環境 初始化項目 uv init --package my-project 初始化一個名為 my-project 的新項目&#xff0c;并生成必要的文件結構。 創建虛擬環境 uv venv .venv 激活虛擬環境 # For Windows .venv\Scripts\activate# For macOS/Linux source .venv/bin/acti…

測試左移系列-產品經理實戰-實戰認知1

課程&#xff1a;B站大學 記錄產品經理實戰項目系統性學習&#xff0c;從產品思維&#xff0c;用戶畫像&#xff0c;用戶體驗&#xff0c;增長數據驅動等不同方向理解產品&#xff0c;從0到1去理解產品從需求到落地的全過程&#xff0c;測試左移方向&#xff08;靠近需求、設計…

從需求到用例的AI路徑:準確率與挑戰

用工作流生成測試用例和自動化測試腳本&#xff01; 引言&#xff1a;用例的黃金起點 在軟件工程中&#xff0c;“測試用例”是連接需求理解與質量保障之間的關鍵橋梁。一份高質量的測試用例&#xff0c;不僅是驗證功能實現是否符合需求的工具&#xff0c;更是產品風險感知、用…

大語言模型中的“溫度”參數到底是什么?如何正確設置?

近年來&#xff0c;市面上涌現了大量調用大模型的工具&#xff0c;如 Dify、Cherry Studio 等開源或自研平臺&#xff0c;幾乎都提供了 “溫度”&#xff08;Temperature&#xff09; 選項。然而&#xff0c;很多人在使用時并不清楚該如何選擇合適的溫度值。 今天&#xff0c;…

如何刪除網上下載的資源后面的文字

這是我在愛給網上下載的音效資源&#xff0c;但是發現資源后面跟了一大段無關緊要的文本&#xff0c;但是修改資源名稱后還是有。解決辦法是打開屬性然后刪掉資源的標簽即可。

hot100-子串-JS

一、560.和為k的子串 560. 和為 K 的子數組 提示 給你一個整數數組 nums 和一個整數 k &#xff0c;請你統計并返回 該數組中和為 k 的子數組的個數 。 子數組是數組中元素的連續非空序列。 示例 1&#xff1a; 輸入&#xff1a;nums [1,1,1], k 2 輸出&#xff1a;2示例 2…

01背包類問題

文章目錄 [模版]01背包1. 第一問: 背包不一定能裝滿(1) 狀態表示(2) 狀態轉移方程(3) 初始化(4) 填表順序(5) 返回值 2. 第二問: 背包恰好裝滿3. 空間優化 416.分割等和子集1. 狀態表示2. 狀態轉移方程3. 初始化4. 填表順序5. 返回值 [494. 目標和](https://leetcode.cn/proble…

解鎖 DevOps 新境界 :使用 Flux 進行 GitOps 現場演示 – 自動化您的 Kubernetes 部署

前言 GitOps 是實現持續部署的云原生方式。它的名字來源于標準且占主導地位的版本控制系統 Git。GitOps 的 Git 在某種程度上類似于 Kubernetes 的 etcd&#xff0c;但更進一步&#xff0c;因為 etcd 本身不保存版本歷史記錄。毋庸置疑&#xff0c;任何源代碼管理服務&#xf…

將Docker鏡像變為可執行文件?體驗docker2exe帶來的便捷!

在現代軟件開發中,容器化技術極大地改變了應用程序部署和管理的方式。Docker,作為領先的容器化平臺,已經成為開發者不可或缺的工具。然而,對于不熟悉Docker的用戶來說,接觸和運行Docker鏡像可能會是一個復雜的過程。為了解決這一問題,docker2exe項目應運而生。它提供了一…