異步爬蟲---

代碼結構分析

這是一個同步新聞爬蟲程序,主要包含以下幾個部分:

們把爬蟲設計為一個類,類在初始化時,連接數據庫,初始化logger,創建網址池,加載hubs并設置到網址池。

爬蟲開始運行的入口就是run(),它是一個while循環,設計為永不停息的爬。先從網址池獲取一定數量的url,然后對每個url進行處理,

處理url也就是實施抓取任務的是process(),它先通過downloader下載網頁,然后在網址池中設置該url的狀態。接著,從下載得到的html提取網址,并對得到的網址進行過濾(filter_good()),過濾的原則是,它們的host必須是hubs的host。最后把下載得到的html存儲到數據。

運行這個新聞爬蟲很簡單,生成一個NewsCrawlerSync的對象,然后調用run()即可。當然,在運行之前,要先在config.py里面配置MySQL的用戶名和密碼,也要在crawler_hub表里面添加幾個hub網址才行。

##思考題: 如何收集大量hub列表

比如,我想要抓新浪新聞?news.sina.com.cn?, 其首頁是一個hub頁面,但是,如何通過它獲得新浪新聞更多的hub頁面呢?小猿們不妨思考一下這個問題,并用代碼來實現一下。

這個時候已經抓取到很多網頁了,但是怎么抽取網頁里的文字呢?

1. 異步的downloader

還記得我們之前使用requests實現的那個downloader嗎?同步情況下,它很好用,但不適合異步,所以我們要先改造它。幸運的是,已經有aiohttp模塊來支持異步http請求了,那么我們就用aiohttp來實現異步downloader。

async def fetch(session, url, headers=None, timeout=9):_headers = {'User-Agent': ('Mozilla/5.0 (compatible; MSIE 9.0; ''Windows NT 6.1; Win64; x64; Trident/5.0)'),}if headers:_headers = headerstry:async with session.get(url, headers=_headers, timeout=timeout) as response:status = response.statushtml = await response.read()encoding = response.get_encoding()if encoding == 'gb2312':encoding = 'gbk'html = html.decode(encoding, errors='ignore')redirected_url = str(response.url)except Exception as e:msg = 'Failed download: {} | exception: {}, {}'.format(url, str(type(e)), str(e))print(msg)html = ''status = 0redirected_url = urlreturn status, html, redirected_url

這個異步的downloader,我們稱之為fetch(),它有兩個必須參數:

  • seesion: 這是一個aiohttp.ClientSession的對象,這個對象的初始化在crawler里面完成,每次調用fetch()時,作為參數傳遞。
  • url:這是需要下載的網址。

實現中使用了異步上下文管理器(async with),編碼的判斷我們還是用cchardet來實現。
有了異步下載器,我們的異步爬蟲就可以寫起來啦~

  1. 導入部分:引入必要的庫和模塊
  2. 主類定義:NewsCrawlerSync?類,包含爬蟲的主要功能
  3. 初始化方法:__init__?方法,初始化數據庫連接、日志和 URL 池
  4. 輔助方法:如加載樞紐 URL、保存數據到數據庫、過濾 URL 等
  5. 核心處理方法:process?方法處理 URL 下載和內容提取
  6. 運行方法:run?方法實現爬蟲的主循環

涉及的知識點

  1. 網絡爬蟲基礎:URL 處理、HTML 下載和解析
  2. 數據庫操作:使用 MySQL 存儲爬取的 URL 和 HTML 內容
  3. 數據壓縮:使用 LZMA 算法壓縮 HTML 內容
  4. 哈希算法:使用 farmhash 生成 URL 的哈希值
  5. 日志記錄:使用自定義日志函數記錄操作
  6. URL 管理:使用自定義的 UrlPool 類管理 URL 隊列
  7. 網頁解析:使用正則表達式提取鏈接

執行流程

  1. 初始化爬蟲對象,建立數據庫連接,初始化日志和 URL 池
  2. 從數據庫加載樞紐 URL,并將它們添加到 URL 池
  3. 進入主循環,每次從 URL 池取出 5 個 URL
  4. 對每個 URL,下載其內容并處理
  5. 如果是樞紐頁面,提取其中的鏈接并過濾,將有效鏈接添加到 URL 池
  6. 如果是普通新聞頁面,將其內容保存到數據庫
  7. 重復步驟 3-6,直到程序停止

現在我將按照這個思路來詳細分析代碼的結構、知識點和流程。

新聞爬蟲代碼分析

一、整體結構

這是一個同步新聞爬蟲程序,采用面向對象設計,核心類為?NewsCrawlerSync,主要包含以下模塊:

  1. 數據存儲模塊:通過?ezpymysql.Connection?連接 MySQL 數據庫,存儲 URL 和 HTML 內容
  2. URL 管理模塊:使用?UrlPool?類管理待爬取 URL 隊列
  3. 下載處理模塊:通過?fn.downloader?下載網頁內容
  4. 鏈接提取模塊:通過?fn.extract_links_re?從 HTML 中提取鏈接
  5. 日志記錄模塊:使用?fn.init_file_logger?記錄操作日志
二、核心知識點
1. 數據庫操作
  • 數據去重:通過farmhash.hash64(url)生成 URL 哈希值,避免重復存儲相同內容
  • SQL 執行:使用參數化查詢防止 SQL 注入(如db.execute(sql, urlhash, url, html_lzma)
  • 異常處理:捕獲 1062 錯誤(唯一鍵沖突),處理數據重復情況
2. 網頁處理
  • URL 解析:使用urllib.parse.urlparse解析 URL 的 host 部分
  • 內容壓縮:通過lzma.compress壓縮 HTML 內容,減少存儲體積
  • 鏈接提取:通過正則表達式從 HTML 中提取鏈接(fn.extract_links_re
3. 爬蟲架構
  • 樞紐頁面機制:從crawler_hub表加載樞紐 URL,作為爬蟲入口
  • URL 過濾:只爬取樞紐頁面關聯的域名(self.hub_hosts集合)
  • 狀態管理:通過UrlPool.set_status記錄 URL 爬取狀態
三、執行流程詳解
1. 初始化階段

圖片

代碼

創建NewsCrawlerSync實例

初始化數據庫連接

初始化日志記錄器

初始化UrlPool

調用load_hubs加載樞紐URL

創建NewsCrawlerSync實例

初始化數據庫連接

初始化日志記錄器

初始化UrlPool

調用load_hubs加載樞紐URL

豆包

你的 AI 助手,助力每日工作學習

  • crawler_hub表讀取樞紐 URL,提取域名存入hub_hosts集合
  • 將樞紐 URL 添加到 UrlPool,設置 300 秒的重復爬取間隔
2. 主爬取循環

圖片

代碼

開始run循環

從UrlPool取出5個URL

是否有URL?

遍歷每個URL

調用process處理URL

開始run循環

從UrlPool取出5個URL

是否有URL?

遍歷每個URL

調用process處理URL

豆包

你的 AI 助手,助力每日工作學習

3. 單 URL 處理流程

圖片

代碼

process方法

下載URL內容

記錄URL狀態

是否為樞紐頁面?

提取頁面所有鏈接

過濾出樞紐域名的鏈接

將有效鏈接添加到UrlPool

保存HTML到數據庫

process方法

下載URL內容

記錄URL狀態

是否為樞紐頁面?

提取頁面所有鏈接

過濾出樞紐域名的鏈接

將有效鏈接添加到UrlPool

保存HTML到數據庫

豆包

你的 AI 助手,助力每日工作學習

四、關鍵方法解析
1. save_to_db - 數據存儲核心

python

運行

def save_to_db(self, url, html):# 生成URL哈希值urlhash = farmhash.hash64(url)# 檢查是否已存在相同哈希的記錄d = self.db.get('select url from crawler_html where urlhash=%s', urlhash)if d:# 處理哈希沖突if d['url'] != url:self.logger.error('farmhash collision')return True# 壓縮HTML內容if isinstance(html, str):html = html.encode('utf8')html_lzma = lzma.compress(html)# 插入數據庫,處理唯一鍵沖突try:self.db.execute('insert into crawler_html(urlhash, url, html_lzma) values(%s, %s, %s)',urlhash, url, html_lzma)return Trueexcept Exception as e:if e.args[0] == 1062:  # 重復記錄return Trueelse:traceback.print_exc()raise e
2. process - 爬蟲核心邏輯

python

運行

def process(self, url, ishub):# 下載網頁內容status, html, redirected_url = fn.downloader(url)# 更新URL狀態self.urlpool.set_status(url, status)if redirected_url != url:self.urlpool.set_status(redirected_url, status)# 處理非200狀態碼if status != 200:return# 處理樞紐頁面if ishub:newlinks = fn.extract_links_re(redirected_url, html)  # 提取所有鏈接goodlinks = self.filter_good(newlinks)  # 過濾樞紐域名鏈接self.urlpool.addmany(goodlinks)  # 添加到URL池# 處理新聞頁面else:self.save_to_db(redirected_url, html)  # 保存到數據庫
五、技術特點與注意事項
  1. 同步爬蟲特性

    • 單線程執行,通過循環依次處理 URL
    • 適合小規模爬取,大規模爬取需改造為異步模式
  2. 去重機制

    • 基于 farmhash 哈希值去重,可能存在哈希沖突(代碼中已處理)
    • 數據庫中通過urlhash建立唯一索引強化去重
  3. 可優化點

    • 改為異步爬蟲(使用asyncio)提升并發效率
    • 添加 User-Agent 輪換和請求延遲,避免被封 IP
    • 完善代理 IP 池機制,應對反爬措施

通過這個爬蟲框架,可以實現對指定新聞網站的持續爬取,并將內容結構化存儲到數據庫中,適合作為入門級爬蟲系統的參考

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

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

相關文章

微服務架構中的 Kafka:異步通信與服務解耦(二)

三、Kafka 基礎入門 3.1 Kafka 是什么 Kafka 最初由 LinkedIn 公司開發,是一個開源的分布式事件流平臺,后成為 Apache 基金會的頂級項目 。它不僅僅是一個簡單的消息隊列,更是一個分布式流處理平臺,具備強大的消息隊列、存儲系統…

Lighthouse與首屏優化

之前提到首屏優化,想到的就是Vue項目首頁打開很慢需要優化。一般都是肉眼看看,對當前的加載速度并沒有一個準確的衡量標準,也沒有很清晰的解決思路。 前兩天我想給自己的網站申請谷歌廣告,聽說審核對網站的性能要求很高。于是網上…

Maven 之 打包項目時沒有使用本地倉庫依賴問題

背景 pom 中使用了第三方jar包,遠程倉庫設置的是阿里云,之前運行很好,今天不知道怎么的,打包總是報錯,阿里云倉庫無法找到依賴包(本來也沒有),按理來說,編譯打包時會優先選擇本地倉庫的包才對&a…

Mysql基礎入門\期末速成

DDL 操作數據庫語句 創建&刪除數據庫語句 創建數據庫 create database 數據庫名稱; -- 直接創建 create database if not exists 數據庫名稱; -- 如果不存在,則創建 create database 數據庫名稱 default charset utf8mb4; -- 創建編譯類型utf8的數據類型 cre…

SCADA|KingSCADA4.0中歷史趨勢控件與之前版本的差異

哈嘍,你好啊,我是雷工! 最近用到KingSCADA4.0信創版本,也算嘗鮮使用。 在使用的過程中發現有些功能或多或少存在一些差異, 這里將遇到的一些不同總結一下,便于后期更好的使用。 01 歷史趨勢控件 在KingSCADA中有一個歷史趨勢曲線控件KSHTrend。 該控件既可以連接King…

ubuntu 拒絕ssh連接,連不上ssh,無法遠程登錄: Connection failed.

目錄 問題描述視窗 可視化桌面命令行 問題描述 [C:\~]$ Connecting to 192.166.8.85:22... Could not connect to 192.166.8.85 (port 22): Connection failed.Type help to learn how to use Xshell prompt. [C:\~]$ Connecting to 192.166.8.85:22... Could not connect to …

【大模型應用開發】向量數據庫向量檢索方法存在問題及優化

一、檢索結果重復 1. 問題分析 在構建向量數據庫時,對文檔分割會存在重復塊(chunk_overlap:指兩個塊之間共享的字符數量,用于保持上下文的連貫性,避免分割丟失上下文信息),如下圖所示&#xf…

MySQL常用函數詳解之數值函數

MySQL常用函數詳解之數值函數 一、數值函數概述1.1 數值函數的作用1.2 數值函數分類 二、算術運算函數2.1 加法運算()2.2 減法運算(-)2.3 乘法運算(*)2.4 除法運算(/ 或 DIV)2.5 取模…

13、Redis進階二之Redis數據安全性分析

? 、Redis性能壓測腳本介紹 Redis的所有數據是保存在內存當中的, 得益于內存?效的讀寫性能, Redis的性能是?常強悍的 。但 是,內存的缺點是斷電即丟失,所以 ,在實際項?中, Redis—旦需要保存—些重要的…

【系統分析師】2011年真題:綜合知識-答案及詳解

文章目錄 【第1題】【第2~3題】【第4~5題】【第6題】【第7~8題】【第9題】【第10題】【第11題】【第12題】【第13題】【第14題】【第15題】【第16題】【第17題】【第18題】【第19~20題】【第21題】【第22題】【第23題】【第24~25題】【第26題】【第27題】【第28題】【第29題】【…

FastAPI-MCP構建自定義MCP工具實操指南

一、簡介 ? FastAPI-MCP是一個基于python FastAPI框架開發的開源項目,可以自動識別并暴露FastAPI接口為MCP工具 ? 擁有FastAPI框架的所有優點,如異步高并發、獨立遠程部署、OpenAPI文檔 ? 提供SSE、mcp-remote接入方式,支持設置授權訪問…

LLMs之Memory:《LLMs Do Not Have Human-Like Working Memory》翻譯與解讀

LLMs之Memory:《LLMs Do Not Have Human-Like Working Memory》翻譯與解讀 導讀:該論文通過三個精心設計的實驗,證明了當前的大型語言模型(LLMs)缺乏類似人類的工作記憶。實驗結果表明,LLMs無法在沒有明確外…

Node.js驗證碼:從生成到驗證的趣味之旅

文章目錄 Node.js驗證碼:從生成到驗證的趣味之旅📜 引言:為什么需要驗證碼?1. 驗證碼的基本原理 🧠驗證碼工作流程示意圖 2. 技術棧準備 🛠?3. 驗證碼生成詳解 🎨3.1 生成SVG驗證碼3.2 轉換為P…

芯科科技攜最新Matter演示和參考應用精彩亮相Matter開放日和開發者大會

全面展示賦能Matter設備實現跨協議和跨海內外生態的技術能力 作為Matter標準創始廠商之一和其解決方案的領先供應商,Silicon Labs(亦稱“芯科科技”)于6月12至13日參加由連接標準聯盟中國成員組(CMGC)主辦的Matter年度…

AndroidStudio下載的SDK沒有tool目錄,或者想要使用uiautomatorviewer工具

1.如果沒有tool目錄可以使用下面的地址進行下載 https://dl.google.com/android/repository/tools_r25.2.5-windows.zip 2.并且把下載的文件解壓到放在AndroidStudio的目錄中 3.如果使用uiautomatorviewer.bat出現下面的錯誤 Unable to connect to adb.Check if adb is instal…

FastJSON等工具序列化特殊字符時會加轉義字符\

在Java中JSON數據格式用String接收時,此時在FastJSON層面看來該JSON只是普通字符串,所以對原字符串序列化會得到轉義字符\ 得到轉義后字符串,再反序列化轉義后字符串會得到原字符串 String json"{\"name\": \"張三\&quo…

數據結構 學習 隊列 2025年6月14日 11點22分

循環隊列 循環隊列是一種線性數據結構,它遵循FIFO(先進先出)原則,但與普通隊列不同的是,循環隊列的最后一個元素連接回第一個元素,形成一個環形結構。這種設計有效解決了普通隊列的"假溢出"問題&…

打造絲滑滾動體驗:Scroll-driven Animations 正式上線!

🌀 打造絲滑滾動體驗:Scroll-driven Animations 正式上線! 🚨 告別 JS 手動監聽滾動條,CSS 新能力讓你用兩行代碼實現高級滾動動效。 🔍 什么是 Scroll-driven Animations? Scroll-driven anim…

知識體系_研究模型_價格敏感度測試模型(PSM)

1 概述 價格敏感度測試模型(Price Sensitivity Measurement,PSM) ,通過調研潛在用戶對于不同價格的滿意或接受程度,從而制定出合適的產品價格。 價格敏感度PSM模型的分析一般分為以下幾個步驟: (1)確定多個價格 (2)通過一定的方式(通常是問卷)收集目標客戶對不同價…