手把手教你寫網路爬蟲(2):迷你爬蟲架構

来源:https://www.cnblogs.com/tuohai666/archive/2018/04/16/8853601.html
-Advertisement-
Play Games

手把手教你寫網路爬蟲(2) 作者:拓海 摘要:從零開始寫爬蟲,初學者的速成指南! 封面: 介紹 大家好!回顧上一期,我們在介紹了爬蟲的基本概念之後,就利用各種工具橫衝直撞的完成了一個小爬蟲,目的就是猛、糙、快,方便初學者上手,建立信心。對於有一定基礎的讀者,請不要著急,以後我們會學習主流的開源框架, ...


 

手把手教你寫網路爬蟲(2)

作者:拓海

摘要:從零開始寫爬蟲,初學者的速成指南!

封面:

 

 

介紹

大家好!回顧上一期,我們在介紹了爬蟲的基本概念之後,就利用各種工具橫衝直撞的完成了一個小爬蟲,目的就是猛、糙、快,方便初學者上手,建立信心。對於有一定基礎的讀者,請不要著急,以後我們會學習主流的開源框架,打造出一個強大專業的爬蟲系統!不過在此之前,要繼續打好基礎,本期我們先介紹爬蟲的種類,然後選取最典型的通用網路爬蟲,為其設計一個迷你框架。有了自己對框架的思考後,再學習複雜的開源框架就有頭緒了。

今天我們會把更多的時間用在思考上,而不是一根筋的coding。用80%的時間思考,20%的時間敲鍵盤,這樣更有利於進步。

 

 

語言&環境

語言:帶足彈葯,繼續用Python開路!

 

 

 

threadingthreading庫可以在單獨的線程中執行任何的在Python中可以調用的對象。Python 2.x中的thread模塊已被廢棄,用戶可以使用threading模塊代替。在Python 3中不能再使用thread模塊。為了相容性,Python 3將thread重命名為_thread。

 

queuequeue模塊中提供了同步的、線程安全的隊列類,包括FIFO(先入先出)隊列Queue,LIFO(後入先出)隊列LifoQueue,和優先順序隊列PriorityQueue。這些隊列都實現了鎖原語,能夠在多線程中直接使用。可以使用隊列來實現線程間的同步。

 

rePython 自1.5版本起增加了re模塊,它提供Perl風格的正則表達式模式。re模塊使 Python語言擁有全部的正則表達式功能。

 

argparsePython用於解析命令行參數和選項的標準模塊,用於代替已經過時的optparse模塊。argparse模塊的作用是用於解析命令行參數。

 

configparser讀取配置文件的模塊。

 

爬蟲的種類

 

 

網路爬蟲按照系統結構和實現技術,大致可以分為以下幾種類型:通用網路爬蟲(General Purpose Web Crawler)、聚焦網路爬蟲(Focused Web Crawler)、增量式網路爬蟲(Incremental Web Crawler)、深層網路爬蟲(Deep Web Crawler)。實際的網路爬蟲系統通常是幾種爬蟲技術相結合實現的。

 

通用網路爬蟲

通用網路爬蟲又稱全網爬蟲(Scalable Web Crawler),爬取對象從一些種子 URL 擴充到整個 Web。主要為門戶站點搜索引擎和大型 Web 服務提供商採集數據。

通用網路爬蟲的結構大致可以分為頁面爬取模塊 、頁面分析模塊、鏈接過濾模塊、頁面存儲模塊、URL 隊列、初始 URL 集合幾個部分。為提高工作效率,通用網路爬蟲會採取一定的爬取策略。 常用的爬取策略有:深度優先策略、廣度優先策略。

1) 深度優先策略(DFS):其基本方法是按照深度由低到高的順序,依次訪問下一級網頁鏈接,直到不能再深入為止。

2) 廣度優先策略(BFS):此策略按照網頁內容目錄層次深淺來爬取頁面,處於較淺目錄層次的頁面首先被爬取。 當同一層次中的頁面爬取完畢後,爬蟲再深入下一層繼續爬取。

 

聚焦網路爬蟲

聚焦網路爬蟲(Focused Crawler),又稱主題網路爬蟲(Topical Crawler),是指選擇性地爬取那些與預先定義好的主題相關頁面的網路爬蟲。 和通用網路爬蟲相比,聚焦爬蟲只需要爬取與主題相關的頁面,極大地節省了硬體和網路資源,保存的頁面也由於數量少而更新快,還可以很好地滿足一些特定人群對特定領域信息的需求。我們之前爬的歌單就屬於這一種。

 

增量式網路爬蟲

增量式網路爬蟲(Incremental Web Crawler)是 指 對 已 下 載 網 頁 採 取 增 量式更新和只爬取新產生的或者已經發生變化網頁的爬蟲,它能夠在一定程度上保證所爬取的頁面是儘可能新的頁面。 和周期性爬取和刷新頁面的網路爬蟲相比,增量式爬蟲只會在需要的時候爬取新產生或發生更新的頁面 ,並不重新下載沒有發生變化的頁面,可有效減少數據下載量,及時更新已爬取的網頁,減小時間和空間上的耗費,但是增加了爬取演算法的複雜度和實現難度。現在比較火的輿情爬蟲一般都是增量式網路爬蟲。

 

深網爬蟲

Web 頁面按存在方式可以分為表層網頁(Surface Web)和深層網頁(Deep Web,也稱 Invisible Web Pages 或 Hidden Web)。 表層網頁是指傳統搜索引擎可以索引的頁面,以超鏈接可以到達的靜態網頁為主構成的 Web 頁面。Deep Web 是那些大部分內容不能通過靜態鏈接獲取的、隱藏在搜索表單後的,只有用戶提交一些關鍵詞才能獲得的 Web 頁面。例如那些用戶註冊後內容才可見的網頁就屬於 Deep Web。

 

一個迷你框架

下麵以比較典型的通用爬蟲為例,分析其工程要點,設計並實現一個迷你框架。架構圖如下:

 

代碼結構:

 

 

config_load.py    配置文件載入

crawl_thread.py    爬取線程

mini_spider.py    主線程

spider.conf    配置文件

url_table.py    url隊列、url表

urls.txt    種子url集合

webpage_parse.py    網頁分析

webpage_save.py    網頁存儲

 

看看配置文件里有什麼內容:

spider.conf

 

 

Step 1. 採用BFS還是DFS?

理論上,這兩個演算法都能夠在大致相同的時間里爬取整個互聯網上的內容。但顯然各個網站最重要的網頁應該是它的首頁。在極端情況下,如果只能下載非常有限的網頁,那麼應該下載的所有網站的首頁,如果把爬蟲再擴大些,應該爬取從首頁直接鏈接的網頁,因為這些網頁是網站設計者自己認為相當重要的網頁。在這個前提下,顯然BFS明顯優於DFS。事實上在搜索引擎的爬蟲里,主要採用的就是BFS。我們的框架採取這種策略。

抓取深度可以通過配置文件中的max_depth設置,只要沒到達指定深度,程式就會不停的將解析出的url放入隊列中:

mini_spider.py

 

 

Step 2. 初始URL集合、URL隊列

我們來看看通用爬蟲如何下載整個互聯網。假設從一家門戶網站的首頁出發,先下載這個網頁(深度=0),然後通過分析這個網頁,可以找到頁面里的所有超鏈接,也就等於知道了這家門戶網站首頁所直接連接的全部網頁,諸如京東理財、京東白條,京東眾籌等(深度=1)。接下來訪問、下載並分析京東理財等網頁,又能找到其他相連的網頁(深度=2)。讓電腦不停的做下去,就能下載整個網站。

在這個過程中,我們需要一個“初始URL集合”保存門戶的首頁,還需要一個“URL隊列”保存分析網頁得到的超鏈接。

mini_spider.py

 

 

url_table.py

 

Step 3. 記錄哪些網頁已經下載過的小本本——URL表。

在互聯網上,一個網頁可能被多個網頁中的超鏈接所指向。這樣在遍歷互聯網這張圖的時候,這個網頁可能被多次訪問到。為了防止一個網頁被下載和解析多次,需要一個URL表記錄哪些網頁已經下載過。再遇到這個網頁的時候,我們就可以跳過它。

crawl_thread.py

 

 

Step 4. 多個抓取線程

為了提升爬蟲性能,需要多個抓取線程,從URL隊列獲取鏈接進行處理。多線程並沒什麼毛病,但Python的多線程可能會引起很多人的質疑,這源於Python設計之初的考慮:GIL。GIL的全稱是Global Interpreter Lock(全局解釋器鎖),某個線程想要執行,必須先拿到GIL,並且在一個Python進程中,GIL只有一個。結果就是Python里一個進程永遠只能同時執行一個線程,這就是為什麼在多核CPU上,Python的多線程效率並不高。那麼我們為什麼還要用Python多線程呢?

CPU密集型代碼(各種迴圈處理、編解碼等等),在這種情況下,由於計算工作多,ticks計數很快就會達到閾值,然後觸發GIL的釋放與再競爭(多個線程來回切換當然是需要消耗資源的),Python下的多線程對CPU密集型代碼並不友好。

IO密集型代碼(文件處理、網路爬蟲等),多線程能夠有效提升效率(單線程下有IO操作會進行IO等待,造成不必要的時間浪費,而開啟多線程能線上程A等待時,自動切換到線程B,可以不浪費CPU的資源,從而能提升程式執行效率)。Python的多線程對IO密集型代碼比較友好。

所以,對於IO密集的爬蟲程式,使用Python多線程是沒問題的。

crawl_thread.py

 

 

Step 5. 頁面分析模塊

從網頁中解析出URLs或者其他有用的數據。這個是上期重點介紹的,可以參考之前的代碼。

 

Step 6. 頁面存儲模塊

保存頁面的模塊,目前將文件保存為文件,以後可以擴展出多種存儲方式,如mysql,mongodb,hbase等等。

webpage_save.py

 

 

寫到這裡,整個框架已經清晰的呈現在大家眼前了,千萬不要小看它,不管多麼複雜的框架都是在這些基本要素上擴展出來的。

 

下一步

基礎知識的學習暫時告一段落,希望能夠幫助大家打下一定的基礎。下期開始為大家介紹強大成熟的爬蟲框架Scrapy,它提供了很多強大的特性來使得爬取更為簡單高效,更多精彩,敬請期待!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <!--strong語氣著重加強--> lorem亂序銘文 <!--em斜體--> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nesciunt, nihil? Lorem ipsum dolor sit amet, conse ...
  • 問題 在使用echart去創建圖表時,發現圖表只占了容器的一個角落,如圖,並沒有充滿容器。 第一反應是容器元素的樣式有問題,於是我把容器的寬高都改為px指定的(之前是百分比設定的,查詢資料發現說echart容器寬高要明確指定),修改之後,還是和上面一樣的展示,依舊有問題。 定位 於是我想是不是渲染圖 ...
  • css選擇器 有通配符選擇器書寫格式:*+{聲名塊} 並集選擇器/組合選擇器 書寫格式;元素或類或id+“”+元素或類或id+“,”+元素或類或id{聲明塊} 列:h1,h2,h3{color:red;} 層次選擇器 : 子集選擇器: 格式:父級元素名稱+">"+子級元素名稱+{聲明塊} 例:div ...
  • 一、概述 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用於構建單頁面應用。 vue的單頁面應用是基於路由和組件的,路由用於設定訪問路徑,並將路徑和組件映射起來。 而傳統的多頁面應用,是用一些超鏈接來實現頁面切換和跳轉的。在vue-router單頁面應用中,則是 ...
  • 使用靜態關鍵字實現單例模式 單例模式:只能獲得某個類的唯一一個實例 單例模式,不管什麼時間點得到的對象都是同一個對象 看下麵代碼: 將構造方法私有,以便實現外部無法使用new進行實例化的效果,達到任何時候其實都是同一個對象的效果 測試代碼如下: 結果如下: 該結果表明:single、single2、 ...
  • 最小生成樹 下圖標明瞭六個城市(A~F)之間的公路(每條公路旁標註了其長度公裡數)。為將部分公路改造成高速公路,使各個城市之間均通過高速公路通達,至少要改造共計()公裡的公路,這種總公裡數最少的改造方案共有()個。 解析: (1)普里姆演算法 任取一點,例如A,將其納入已完成部分。點A與其他各點中的最... ...
  • Web應用中常用的HTTP方法有四種: 1.PUT方法用來添加的資源 2.GET方法用來獲取已有的資源 3.POST方法用來對資源進行狀態轉換 4.DELETE方法用來刪除已有的資源 Spring MVC最新的版本中提供了一種更加簡潔的配置HTTP方法的方式,增加了四個標註: @PutMapping ...
  • 1、page作用域也是最小的作用域,它只能在當前頁面中使用。 2、request作用域主要是發送請求,但只能在兩個頁面之間發送一次請求。 3、session作用域是一個會話,也就是一個瀏覽器,意思是說只能在當前會話中傳值,如果換個瀏覽器就不行了。 4、application作用域,這個就牛逼了,它是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...