習(xí)框架2023:從請(qǐng)求到入庫的完整知識(shí)地圖)
簡介這份PDF面向零基礎(chǔ)到進(jìn)階的Python爬蟲學(xué)習(xí)者系統(tǒng)梳理了從入門到實(shí)戰(zhàn)的完整知識(shí)框架幫助初學(xué)者解決“學(xué)什么、怎么學(xué)、在哪里學(xué)”的困惑。內(nèi)容圍繞爬蟲三部曲展開獲取數(shù)據(jù)環(huán)節(jié)講解urllib、requests、aiohttp等請(qǐng)求庫及異步抓取思路解析數(shù)據(jù)環(huán)節(jié)對(duì)比pyquery、BeautifulSoup、XPath與正則表達(dá)式的適用場(chǎng)景數(shù)據(jù)存儲(chǔ)環(huán)節(jié)則涉及TXT、JSON、CSV及MySQL、MongoDB等方案并補(bǔ)充代理IP、請(qǐng)求頭偽裝、Selenium動(dòng)態(tài)渲染與分布式爬取等進(jìn)階技巧同時(shí)提醒Robots協(xié)議與合規(guī)邊界。資源為單個(gè)PDF文件壓縮包約2.1MB輕量便攜適合隨時(shí)查閱。目前已有174人學(xué)習(xí)可作為搭建爬蟲知識(shí)體系、按圖索驥查漏補(bǔ)缺的參考框架。1. 爬蟲學(xué)習(xí)框架總覽從請(qǐng)求到入庫的完整知識(shí)地圖很多人學(xué) Python 爬蟲第一反應(yīng)是去找一個(gè)“萬能模板”復(fù)制粘貼跑通一個(gè)網(wǎng)站就覺得自己會(huì)了。但真到換一個(gè)目標(biāo)站點(diǎn)面對(duì)異步加載、登錄校驗(yàn)、數(shù)據(jù)量暴漲的時(shí)候立刻翻車。問題不在于代碼寫得少而在于腦子里沒有一張完整的知識(shí)地圖。這份 2023 年最新 Python 爬蟲的完整學(xué)習(xí)框架核心價(jià)值就是先把地圖給你畫出來爬蟲的本質(zhì)是模擬瀏覽器發(fā)送請(qǐng)求、下載網(wǎng)頁代碼、提取有用數(shù)據(jù)、存入數(shù)據(jù)庫或文件對(duì)應(yīng)“獲取數(shù)據(jù) → 解析數(shù)據(jù) → 存儲(chǔ)數(shù)據(jù)”三部曲。圍繞這條主線知識(shí)被拆成輕量級(jí)爬蟲、工程化爬蟲兩大階段每個(gè)階段再細(xì)分請(qǐng)求庫、解析庫、數(shù)據(jù)庫、框架選型。適合已經(jīng)能寫幾行 Python、想系統(tǒng)梳理一遍爬蟲體系的人也適合復(fù)習(xí)時(shí)快速定位自己卡在哪一層。先看清全貌再逐個(gè)模塊啃比盲目追新庫高效得多。2. 輕量級(jí)爬蟲三件套請(qǐng)求、解析、存儲(chǔ)的復(fù)習(xí)重點(diǎn)輕量級(jí)爬蟲是絕大多數(shù)人入門的第一站也是面試和實(shí)際小項(xiàng)目里最??嫉牟糠?。它不要求你理解 HTTP、TCP、IP 的底層網(wǎng)絡(luò)傳輸結(jié)構(gòu)因?yàn)?Python 提供了功能齊全的類庫幫你完成請(qǐng)求。但“會(huì)用”和“知道為什么這么用”之間差的就是這一章要梳理的內(nèi)容。下面按請(qǐng)求庫、解析庫、數(shù)據(jù)庫三個(gè)模塊拆開每個(gè)模塊都給出選型邏輯和容易忽略的細(xì)節(jié)。2.1 請(qǐng)求庫選型urllib、requests、aiohttp 怎么選請(qǐng)求是爬蟲的第一步模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求。Python 自帶的標(biāo)準(zhǔn)庫 urllib 系列是內(nèi)置的 HTTP 請(qǐng)求庫如果只進(jìn)行基本的網(wǎng)頁抓取它足夠用。但實(shí)際寫起來urllib 處理編碼、異常、會(huì)話維持都比較繁瑣。Requests 的定位就是“為人類設(shè)計(jì)的 HTTP 庫”相對(duì) urllib 簡潔很多并且自帶 JSON 解析器是日常同步爬蟲的首選。當(dāng)目標(biāo)站點(diǎn)是異步加載的動(dòng)態(tài)網(wǎng)站時(shí)有兩種思路一是用瀏覽器抓包分析真實(shí)請(qǐng)求直接請(qǐng)求數(shù)據(jù)接口二是用 Selenium 模擬瀏覽器操作支持頁面交互和動(dòng)態(tài)加載的爬取。如果追求速度aiohttp 是值得掌握的異步請(qǐng)求庫借助 async/await 關(guān)鍵字寫法比傳統(tǒng)回調(diào)清晰很多。有數(shù)據(jù)統(tǒng)計(jì)正常情況下請(qǐng)求同一個(gè)頁面 100 次同步方式最少要 30 秒左右而異步請(qǐng)求只需要 3 秒左右差距非常明顯。選型建議很明確先從 urllib 開始理解請(qǐng)求的本質(zhì)再過渡到 requests 作為主力遇到動(dòng)態(tài)頁面先抓包、抓不到再上 Selenium最后在需要高并發(fā)采集時(shí)引入 aiohttp。不要一上來就 all in 異步調(diào)試成本會(huì)讓你懷疑人生。import requests # 設(shè)置請(qǐng)求頭模擬真實(shí)瀏覽器降低被識(shí)別為爬蟲的概率 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Accept-Language: zh-CN,zh;q0.9, } # 帶超時(shí)和狀態(tài)碼檢查的請(qǐng)求避免程序卡死 resp requests.get(https://example.com/list, headersheaders, timeout10) resp.raise_for_status() # 非 2xx 狀態(tài)碼直接拋異常 resp.encoding resp.apparent_encoding # 自動(dòng)推斷編碼防止中文亂碼 html resp.text這段代碼里headers里的 User-Agent 是最基礎(chǔ)的偽裝timeout防止請(qǐng)求無限等待raise_for_status讓錯(cuò)誤盡早暴露apparent_encoding解決中文站點(diǎn)常見的亂碼問題。參數(shù)看著簡單但每一條都是踩坑之后加上的。2.2 解析庫對(duì)比BeautifulSoup、PyQuery、XPath、正則的適用場(chǎng)景爬回來的網(wǎng)頁代碼里只有一部分?jǐn)?shù)據(jù)是有用的解析就是定位并提取這部分?jǐn)?shù)據(jù)。從 Web 上采集回來的數(shù)據(jù)類型主要有 HTML、JavaScript、JSON、XML 等格式。解析庫的選擇本質(zhì)上是在“定位精度”和“編寫成本”之間做權(quán)衡。BeautifulSoup 借助網(wǎng)頁的結(jié)構(gòu)和屬性來解析能自動(dòng)轉(zhuǎn)換編碼支持 Python 標(biāo)準(zhǔn)庫的 HTML 解析器也支持第三方解析器容錯(cuò)性好適合結(jié)構(gòu)不太規(guī)整的頁面。PyQuery 使用 lxml 解析器提供和 jQuery 類似的語法支持 CSS 選擇器前端基礎(chǔ)扎實(shí)的人用起來非常順手。XPath 最初用于搜尋 XML 文檔同樣適用于 HTML提供了超過 100 個(gè)內(nèi)建函數(shù)用于字符串、數(shù)值、日期時(shí)間比較、節(jié)點(diǎn)處理、序列處理、邏輯值等定位能力強(qiáng)表達(dá)式寫熟了效率極高。正則表達(dá)式 re 通常用來檢索、替換符合某個(gè)模式的文本速度比較快但寫正則比較麻煩可讀性差適合提取格式非常固定的零散信息。梳理下來會(huì)發(fā)現(xiàn)沒有哪個(gè)解析庫能通吃。常見組合是結(jié)構(gòu)清晰的頁面用 PyQuery 或 XPath結(jié)構(gòu)混亂的用 BeautifulSoup 兜底JSON 接口直接用 requests 自帶的解析器只有極少數(shù)格式固定的場(chǎng)景才動(dòng)用正則。解析庫核心優(yōu)勢(shì)適合場(chǎng)景主要短板BeautifulSoup容錯(cuò)好、自動(dòng)編碼轉(zhuǎn)換結(jié)構(gòu)不規(guī)整的 HTML速度相對(duì)慢PyQueryjQuery 語法、CSS 選擇器前端基礎(chǔ)好的人依賴 lxmlXPath函數(shù)豐富、定位精準(zhǔn)復(fù)雜層級(jí)、XML/HTML表達(dá)式學(xué)習(xí)曲線陡re 正則速度快格式固定的零散文本可讀性差、易寫錯(cuò)2.3 數(shù)據(jù)存儲(chǔ)TXT、CSV、MySQL、MongoDB、Redis 的分層使用數(shù)據(jù)量小的時(shí)候用文檔形式存儲(chǔ)完全夠用支持 TXT、JSON、CSV 等格式。但數(shù)據(jù)量一大文檔方式就行不通了掌握一種數(shù)據(jù)庫是必須的。MySQL 作為關(guān)系型數(shù)據(jù)庫的代表體系成熟適合存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)但在海量數(shù)據(jù)處理時(shí)效率會(huì)顯著變慢。MongoDB 相對(duì) MySQL可以方便地存儲(chǔ)非結(jié)構(gòu)化數(shù)據(jù)比如各種評(píng)論文本、圖片鏈接配合 PyMongo 能在 Python 中更方便地操作。Redis 是內(nèi)存數(shù)據(jù)庫支持 hash、set、list 等豐富的數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)全部存在內(nèi)存訪問速度快一般應(yīng)用于分布式爬蟲的數(shù)據(jù)存儲(chǔ)和去重隊(duì)列。這里最容易忽略的是數(shù)據(jù)庫知識(shí)在爬蟲里用到的其實(shí)非常簡單主要是數(shù)據(jù)如何入庫、如何提取不需要一開始就系統(tǒng)學(xué)完數(shù)據(jù)庫課程在需要的時(shí)候再學(xué)就行。選型邏輯可以記成一句話小數(shù)據(jù)走文件結(jié)構(gòu)化走 MySQL非結(jié)構(gòu)化走 MongoDB高并發(fā)去重和緩存走 Redis。3. 工程化爬蟲框架Scrapy、PySpider、Nutch 的定位差異當(dāng)你掌握了前面的技術(shù)就能實(shí)現(xiàn)輕量級(jí)爬蟲一般量級(jí)的數(shù)據(jù)和代碼基本沒有問題。但在面對(duì)復(fù)雜情況時(shí)比如需要分布式抓取、任務(wù)調(diào)度、斷點(diǎn)續(xù)爬、大規(guī)模去重手寫腳本的表現(xiàn)就力不從心了。這時(shí)候工程化爬蟲框架的價(jià)值就體現(xiàn)出來。這一章梳理三個(gè)最有代表性的框架重點(diǎn)不是比較誰更好而是搞清楚它們各自解決什么問題以及學(xué)習(xí)順序怎么安排。3.1 Scrapy最靈活的定制化爬取框架Scrapy 是 GitHub 上 star 數(shù)很高的爬蟲框架功能非常強(qiáng)大。它不僅能便捷地構(gòu)建 request還有強(qiáng)大的 selector 方便解析 response最讓人驚喜的是超高的性能讓你可以將爬蟲工程化、模塊化。學(xué)會(huì) Scrapy你可以自己去搭建一些爬蟲框架基本就具備爬蟲工程師的思維了。Scrapy 的核心概念包括 Spider定義抓取邏輯、Item定義數(shù)據(jù)結(jié)構(gòu)、Pipeline定義存儲(chǔ)邏輯、Middleware定義請(qǐng)求和響應(yīng)的處理邏輯。這套抽象一開始會(huì)覺得繞但一旦理解就能把“抓取—解析—存儲(chǔ)”拆成獨(dú)立模塊各自維護(hù)。它適合需要長期運(yùn)行、規(guī)則復(fù)雜、數(shù)據(jù)量大的采集任務(wù)。import scrapy class BookSpider(scrapy.Spider): name book start_urls [https://example.com/books] def parse(self, response): # 用 CSS 選擇器定位列表項(xiàng)逐個(gè)提取字段 for item in response.css(div.book-item): yield { title: item.css(h3::text).get(), price: item.css(span.price::text).get(), link: item.css(a::attr(href)).get(), } # 翻頁找到下一頁鏈接并繼續(xù)請(qǐng)求 next_page response.css(a.next::attr(href)).get() if next_page: yield response.follow(next_page, self.parse)這段 Spider 展示了 Scrapy 的基本寫法start_urls定義入口parse方法處理響應(yīng)yield返回?cái)?shù)據(jù)或新的請(qǐng)求。response.follow會(huì)自動(dòng)處理相對(duì)鏈接比手動(dòng)拼接 URL 省事。實(shí)際項(xiàng)目中字段提取規(guī)則、翻頁邏輯、去重策略都會(huì)比這個(gè)復(fù)雜但骨架就是這些。3.2 PySpider產(chǎn)品級(jí) WebUI 的調(diào)度框架PySpider 是人氣很高的國產(chǎn)框架滿足了絕大多數(shù) Python 爬蟲的需求主打定向抓取和結(jié)構(gòu)化解析。它最大的特點(diǎn)是能在瀏覽器界面上進(jìn)行腳本編寫、功能調(diào)度和爬取結(jié)果的實(shí)時(shí)查看后端使用常用數(shù)據(jù)庫進(jìn)行結(jié)果存儲(chǔ)。功能強(qiáng)大到更像一個(gè)產(chǎn)品而不是一個(gè)框架。對(duì)于不習(xí)慣純代碼調(diào)試、希望可視化看到任務(wù)隊(duì)列和抓取結(jié)果的人來說PySpider 的上手體驗(yàn)很好。它適合快速搭建中小型采集任務(wù)尤其是需要頻繁調(diào)整規(guī)則、實(shí)時(shí)觀察抓取狀態(tài)的場(chǎng)景。但它的定制化能力不如 Scrapy 靈活超大規(guī)模分布式場(chǎng)景下也不是首選。3.3 Nutch為搜索引擎而生的分布式方案Nutch 是 Apache 頂級(jí)項(xiàng)目提供了運(yùn)行自己的搜索引擎所需的全部工具。它支持分布式抓取并有 Hadoop 支持可以進(jìn)行多機(jī)分布抓取、存儲(chǔ)和索引。很吸引人的一點(diǎn)是它提供了一種插件框架使得對(duì)各種網(wǎng)頁內(nèi)容的解析、各種數(shù)據(jù)的采集、查詢、集群、過濾等功能能夠方便地進(jìn)行擴(kuò)展。Nutch 的定位非常明確不是通用爬蟲框架而是搜索引擎解決方案的一部分。如果你要做的是全網(wǎng)級(jí)或站內(nèi)搜索索引Nutch 是繞不開的選項(xiàng)如果只是采集電商價(jià)格、新聞列表用 Nutch 就是殺雞用牛刀。三個(gè)框架的學(xué)習(xí)順序建議先從最接近爬蟲本質(zhì)的 Scrapy 學(xué)起理解工程化爬蟲的模塊劃分和調(diào)度邏輯再去接觸人性化的 PySpider感受可視化調(diào)度的便利最后如果有搜索引擎相關(guān)的需求再研究 Nutch。這個(gè)順序能讓你每一步都建立在已有認(rèn)知上而不是被各種新概念同時(shí)轟炸。4. 易漏點(diǎn)與易錯(cuò)點(diǎn)請(qǐng)求頭、編碼、反爬、存儲(chǔ)的常見翻車現(xiàn)場(chǎng)這一章專門整理復(fù)習(xí)時(shí)最容易漏掉、實(shí)際寫代碼時(shí)最容易翻車的地方。每一條都按“易漏點(diǎn) → 為什么漏 → 怎么補(bǔ)”的結(jié)構(gòu)寫方便對(duì)照檢查。易漏點(diǎn)一請(qǐng)求頭只寫 User-Agent忽略 Referer 和 Cookie。為什么漏因?yàn)槿腴T教程通常只教加 User-Agent跑通一個(gè)簡單站點(diǎn)后就以為萬事大吉。怎么補(bǔ)遇到 403 或返回空數(shù)據(jù)時(shí)用瀏覽器開發(fā)者工具抓完整請(qǐng)求頭把 Referer、Accept、Accept-Language 甚至 Cookie 都帶上再逐步刪減找到最小必要集合。易漏點(diǎn)二編碼處理想當(dāng)然中文亂碼后才回頭找原因。為什么漏因?yàn)?requests 的resp.text在部分站點(diǎn)會(huì)自動(dòng)猜錯(cuò)編碼而初學(xué)者往往直接.text就用。怎么補(bǔ)統(tǒng)一用resp.apparent_encoding或手動(dòng)指定resp.encoding utf-8存儲(chǔ)前打印前 200 個(gè)字符確認(rèn)沒有亂碼。易漏點(diǎn)三忽略 Robots 協(xié)議和訪問頻率導(dǎo)致 IP 被限制。為什么漏因?yàn)楸镜販y(cè)試請(qǐng)求量小感覺不到壓力上線后并發(fā)一開就被目標(biāo)站點(diǎn)攔截。怎么補(bǔ)先看目標(biāo)站點(diǎn)根目錄下的 robots.txt了解哪些頁面允許抓取請(qǐng)求之間加隨機(jī)延時(shí)必要時(shí)使用代理 IP 池輪換但代理本身也要做可用性檢測(cè)。易漏點(diǎn)四數(shù)據(jù)存儲(chǔ)不做去重重復(fù)入庫浪費(fèi)空間。為什么漏因?yàn)樾?shù)據(jù)量時(shí)重復(fù)不明顯數(shù)據(jù)量上來后才發(fā)現(xiàn)大量重復(fù)記錄。怎么補(bǔ)入庫前用唯一鍵如 URL 的哈希值做去重Redis 的 set 結(jié)構(gòu)非常適合這個(gè)場(chǎng)景或者用數(shù)據(jù)庫的唯一索引兜底。易漏點(diǎn)五異常處理只寫 try-except 不寫重試網(wǎng)絡(luò)抖動(dòng)就丟數(shù)據(jù)。為什么漏因?yàn)楸镜鼐W(wǎng)絡(luò)穩(wěn)定體會(huì)不到超時(shí)和連接重置的頻繁程度。怎么補(bǔ)對(duì)請(qǐng)求封裝重試邏輯設(shè)置最大重試次數(shù)和退避策略記錄失敗 URL 以便后續(xù)補(bǔ)爬。5. 復(fù)習(xí)清單與查漏補(bǔ)缺從請(qǐng)求到入庫的自檢流程復(fù)習(xí)爬蟲知識(shí)最怕的是“感覺都會(huì)一寫就廢”。下面這份自檢清單按爬蟲執(zhí)行流程排列每一項(xiàng)都對(duì)應(yīng)一個(gè)可以動(dòng)手驗(yàn)證的動(dòng)作。你可以拿一個(gè)自己熟悉的站點(diǎn)從第一步走到最后一步卡在哪一步就回去補(bǔ)對(duì)應(yīng)章節(jié)。檢查項(xiàng)自檢動(dòng)作對(duì)應(yīng)模塊請(qǐng)求能否成功用 requests 帶完整請(qǐng)求頭訪問目標(biāo)頁打印狀態(tài)碼和前 200 字符請(qǐng)求庫編碼是否正確檢查中文是否亂碼確認(rèn) encoding 設(shè)置請(qǐng)求庫解析是否精準(zhǔn)用 PyQuery 或 XPath 提取目標(biāo)字段打印條數(shù)和樣例解析庫翻頁是否完整檢查是否漏掉最后一頁或重復(fù)抓取第一頁解析庫存儲(chǔ)是否去重連續(xù)跑兩次檢查數(shù)據(jù)庫記錄數(shù)是否翻倍存儲(chǔ)異常是否兜底斷網(wǎng)或改錯(cuò) URL觀察程序是否優(yōu)雅報(bào)錯(cuò)并記錄異常處理頻率是否合規(guī)檢查請(qǐng)求間隔確認(rèn)沒有對(duì)目標(biāo)站點(diǎn)造成壓力反爬與合規(guī)這份清單的價(jià)值在于它把“復(fù)習(xí)”變成了“可執(zhí)行的驗(yàn)證”。每通過一項(xiàng)就說明對(duì)應(yīng)的知識(shí)模塊真正掌握了哪一項(xiàng)卡住就回到對(duì)應(yīng)章節(jié)重新梳理。比起反復(fù)看書動(dòng)手跑一遍流程的記憶效果好得多。從那以后我每次接手一個(gè)新的采集任務(wù)都強(qiáng)制走一遍這個(gè)清單先確認(rèn)請(qǐng)求通、編碼對(duì)、解析準(zhǔn)再考慮并發(fā)和分布式。很多翻車現(xiàn)場(chǎng)其實(shí)在第一步就能避免。希望這份梳理能幫到你讓你在爬蟲學(xué)習(xí)路上少走一些彎路。本文還有配套的精品資源點(diǎn)擊獲取