
做技術選型的時候最怕的不是“沒有工具”而是“工具太多不知道怎么選”。Python 爬蟲圈子尤其如此GitHub 上每天都有新的爬蟲項目出現有人開源了一個“一鍵采集某平臺數據”的工具有人實現了新的反反爬策略。但真到自己動手寫爬蟲時很多人卻卡住了——收藏夾里存了幾十個項目不知道哪個能解決自己的問題requests 能抓到靜態頁面遇到動態渲染的頁面就束手無策數據量一旦上來單機腳本跑不動又不知道該怎么擴展。這篇文章不打算吹捧某個具體的“爆火項目”而是想聊一個更值得關注的變化Python 爬蟲工具鏈正在從“requests BeautifulSoup 的單點腳本”走向“瀏覽器自動化 任務調度 數據治理”的工程化方案。這個變化決定了你應該選什么工具、怎么搭項目結構、怎么避免把時間浪費在重復造輪子上。讀完你會得到一份能直接落地的工具選型清單、一套完整的示例代碼以及一份常見問題排查清單。1. 爬蟲圈最近在關注什么從“寫請求”到“工程化”很多初學者對爬蟲的理解是“發出 HTTP 請求拿到 HTML用正則或解析庫提取數據”。這個理解本身沒有錯它對應的是最基礎的爬蟲模型。但如果你在 GitHub 上多翻幾個高 star 的爬蟲項目會發現大家討論的重心早就變了如何管理 Cookie、Token 和登錄態如何處理動態渲染的頁面而不是只抓靜態 HTML如何讓爬蟲按頻率、按優先級、按增量去抓取如何把抓到的數據清洗、去重、落庫如何監控爬蟲的健康狀態失敗了怎么重試如何在不影響目標網站的前提下合法合規地抓取數據。這些問題加起來就是“爬蟲工程化”。從材料來看無論是 GitHub 上的開源框架還是社區里的熱門討論都在往這個方向走。單點工具依然有價值但生產級的爬蟲系統靠一個 requests 循環是不夠的。所以你會看到近年熱門的 Python 爬蟲工具不再只有 requests 和 BeautifulSoup。瀏覽器自動化工具、任務調度框架、布隆過濾器、代理池、日志系統都被整合到了爬蟲項目里。對開發者來說這既是好事也是挑戰好處是有成熟方案可以借力壞處是學習曲線變陡了。這篇文章的判斷是2025 年以后的爬蟲選型優先考慮“能工程化”的工具而不是單個功能最強的工具。下面我按這個思路從基礎工具到完整框架做一個梳理。2. 核心概念先把爬蟲工具的分類搞明白在寫代碼之前建議先建立一張“工具地圖”。很多新手學爬蟲今天看一個 requests 教程明天看一個 Scrapy 教程最后混在一起不知道哪個環節該用哪個工具。其實爬蟲工具可以按功能分成四層2.1 請求層負責發起 HTTP 請求、處理響應、管理會話。代表工具是 requests、httpx、aiohttp。requests 適合快速上手httpx 支持 HTTP/2 和異步aiohttp 適合高并發場景。2.2 解析層負責把響應內容轉成結構化數據。代表工具有 BeautifulSoup、lxml、parsel、json。BeautifulSoup API 友好lxml 性能好parsel 是 Scrapy 內部的解析器語法兼容 CSS 和 XPath。2.3 瀏覽器自動化層負責模擬真實瀏覽器解決動態渲染、JavaScript 加密、復雜交互等問題。代表工具有 Selenium、Playwright、DrissionPage。這一層是近年變化最大的部分后面單獨講。2.4 框架與調度層負責把請求、解析、存儲、去重、重試、調度整合成一個完整系統。代表工具有 Scrapy、feapder、crawlab。如果你的爬蟲只需要跑一次、抓幾十頁數據用框架反而笨重但如果要長期運行這一層幾乎必須引入。2.5 按任務類型分類從任務形態上看爬蟲還可以分成三類這有助于你做架構設計類型特點典型使用方式批量型爬蟲一次性抓完存量數據單機腳本或小集群重解析不重調度增量型爬蟲只抓新增或變化的數據需要去重、時間戳或 ID 記錄通常配數據庫垂直型爬蟲針對某類站點深耕需要針對單個站點定制解析和反爬策略明白了分類再回頭看具體工具就不會迷路。接下來我們從環境準備開始逐步跑通一個最小爬蟲再到動態頁面最后說框架選型。3. 環境準備Python 與虛擬環境的基礎配置無論你選哪個爬蟲框架第一步都是把 Python 環境收拾干凈。這里最容易被忽略的是不要用系統全局 Python 直接裝包尤其是 Ubuntu 或 macOS 自帶的環境裝到一半權限報錯、依賴沖突都很常見。3.1 安裝 Python建議使用 Python 3.9 以上版本。macOS/Linux 可以優先看系統是否自帶Windows 用戶從官網下載安裝包。如果你需要多個 Python 版本切換可以考慮使用 pyenv 或 conda 管理。版本細節以你實際安裝的為準本文不指定死版本。安裝完成后在終端驗證python3 --version pip3 --version如果你的系統里同時有多個 Python建議使用python3 -m pip而不是直接pip避免裝錯環境。3.2 創建虛擬環境虛擬環境的作用是隔離項目依賴。一個爬蟲項目用 requests 1.0另一個用 requests 2.0互不干擾。mkdir python-spider-demo cd python-spider-demo python3 -m venv venv source venv/bin/activateWindows 下激活命令是venv\Scripts\activate激活成功后終端會顯示(venv)前綴。接下來安裝本階段需要的包pip install requests beautifulsoup4 lxml國內網絡環境下如果 pip 下載慢可以臨時使用國內鏡像源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests beautifulsoup4 lxml注意這里只是給你一個通用的鏡像配置方式。實際使用哪個源取決于你所在網絡環境的可用性請以能訪問、可信任的源為準。3.3 關于 GitHub 開源項目的下載問題GitHub 本身就是爬蟲開源項目的最大聚集地但很多開發者會遇到倉庫下載慢、release 附件下載不動的情況。這里可以推薦兩種通用思路一是使用 GitHub 鏡像站二是使用倉庫下載加速服務常見的有 ghproxy 這類轉發服務。這些服務的可用性和安全性隨時可能變化使用前注意核對代碼來源生產環境不要使用你不信任的第三方打包。4. 入門級組合requests BeautifulSoup 快速抓取靜態頁面先寫一個最小可運行的示例。示例目標站使用一個公開的爬蟲練習站點quotes.toscrape.com它專門用來教學不涉及敏感數據。新建文件demo_quotes.py# 文件路徑python-spider-demo/demo_quotes.py import requests from bs4 import BeautifulSoup def fetch_page(page: int): url fhttps://quotes.toscrape.com/page/{page}/ try: resp requests.get(url, timeout10) resp.raise_for_status() except requests.RequestException as e: print(f請求失敗: {e}) return [] soup BeautifulSoup(resp.text, html.parser) quotes [] for item in soup.select(.quote): text item.select_one(.text).get_text(stripTrue) author item.select_one(.author).get_text(stripTrue) quotes.append({text: text, author: author}) return quotes if __name__ __main__: for page in range(1, 4): data fetch_page(page) print(f第 {page} 頁獲取到 {len(data)} 條數據) for quote in data[:2]: print(quote[author], quote[text][:30])代碼邏輯說明requests.get負責發起 HTTP 請求timeout10是必加的否則遇到慢接口會一直掛住resp.raise_for_status()會在狀態碼非 200 時拋異常避免拿到錯誤頁面還繼續解析soup.select(.quote)使用 CSS 選擇器定位所有名言節點get_text(stripTrue)去掉首尾空白避免解析出大量換行符。運行方式python demo_quotes.py預期輸出類似第 1 頁獲取到 10 條數據 Albert Einstein “The world as we have created it...” J.K. Rowling “It is our choices, Harry, that show...” 第 2 頁獲取到 10 條數據 ...如果這里能跑通說明你的 requests、BeautifulSoup、Python 環境都沒有問題。這個組合適合目標頁面是服務端渲染、不需要登錄、反爬策略不強的場景。它也是后續學習框架的基礎。5. 動態頁面與反爬場景DrissionPage 和 Playwright 如何選很多真實站點的數據不是寫在靜態 HTML 里的而是通過 JavaScript 請求接口后再渲染。用 requests 直接抓得到的 HTML 里沒有數據。這時候需要瀏覽器自動化工具。老牌方案是 Selenium。但 Selenium 的問題也很明顯需要下載對應版本的 webdriver配置繁瑣啟動瀏覽器時還要處理各種環境問題。近兩年更常用的方案是 Playwright 和 DrissionPage。工具核心特點適用場景Selenium歷史最久文檔多老項目維護、兼容舊瀏覽器測試Playwright微軟開源內置瀏覽器下載支持多種語言跨瀏覽器測試、復雜交互、截圖DrissionPage國產開源把 requests 和瀏覽器控制封裝到一起配置簡單快速做反爬繞過、混合模式采集從社區反饋和工具熱度來看DrissionPage 近年增長很快。它的一個重要設計是同一個代碼里既能用瀏覽器自動化模式去解決登錄和動態渲染也能用類似 requests 的方式直接請求接口。這對于爬蟲場景非常方便因為不需要在 Selenium 和 requests 之間來回切換。下面是一個 DrissionPage 抓取動態頁面示例。注意不同版本的 API 可能略有差異請以官方文檔為準。# 文件路徑python-spider-demo/demo_dynamic.py from DrissionPage import ChromiumPage page ChromiumPage() page.get(https://quotes.toscrape.com/js/) page.wait.load_start() for item in page.eles(.quote): text item.ele(.text).text author item.ele(.author).text print(f{author}: {text[:40]}) page.quit()這段代碼的邏輯是啟動一個 Chromium 瀏覽器實例訪問動態渲染頁面等頁面加載完成后用選擇器提取名言和作者。相比 Selenium不需要手動下載和配置 driver對新手更友好。如果你更傾向 Playwright官方提供了很強的調試工具執行下面命令可以看到操作和頁面狀態pip install playwright playwright install chromium python -m playwright codegen https://quotes.toscrape.com/js/codegen會打開錄制窗口你手動操作頁面它自動生成代碼是一個快速學習選擇器的高效辦法。6. 完整實戰示例從列表頁到詳情頁的數據采集流程前面兩個例子分別處理了靜態頁面和動態頁面。實際項目里通常還需要把數據從列表頁帶到詳情頁再加去重、更新邏輯。這里給一個更完整的工程項目結構示例。假設我們要采集某個公開書籍站點流程是先抓列表頁得到每本書的詳情頁地址再訪問詳情頁拿價格和庫存。這個示例站點也是公開練習用的。推薦的項目結構python-spider-demo/ ├── main.py # 入口 ├── config.py # 配置項 ├── parse.py # 解析邏輯 ├── storage.py # 存儲邏輯 └── requirements.txt # 依賴清單config.py示例# 文件路徑python-spider-demo/config.py BASE_URL https://books.toscrape.com/ REQUEST_INTERVAL 1 # 每次請求間隔秒數避免對目標站點造成壓力 OUTPUT_FILE books.csvparse.py示例# 文件路徑python-spider-demo/parse.py from bs4 import BeautifulSoup def parse_book_list(html: str) - list[dict]: soup BeautifulSoup(html, html.parser) books [] for article in soup.select(article.product_pod): title article.select_one(h3 a).get(title) price article.select_one(.price_color).get_text(stripTrue) detail_url article.select_one(h3 a).get(href) books.append({ title: title, price: price, detail_url: detail_url, }) return booksmain.py示例# 文件路徑python-spider-demo/main.py import time import csv import requests import config import parse def fetch_html(url: str) - str: resp requests.get(url, timeout10) resp.raise_for_status() resp.encoding resp.apparent_encoding return resp.text def main(): books [] for page in range(1, 3): url f{config.BASE_URL}catalogue/page-{page}.html html fetch_html(url) books.extend(parse.parse_book_list(html)) print(f第 {page} 頁累計 {len(books)} 條) time.sleep(config.REQUEST_INTERVAL) with open(config.OUTPUT_FILE, w, newline, encodingutf-8) as f: writer csv.DictWriter(f, fieldnames[title, price, detail_url]) writer.writeheader() writer.writerows(books) print(f已完成寫入 {config.OUTPUT_FILE}) if __name__ __main__: main()這個結構雖然簡單但已經開始體現“工程化”思維配置獨立出來改請求間隔不用改業務代碼解析邏輯單獨成文件后續增強選擇器只改一個地方存儲端先用 CSV后續換成數據庫只需要改storage.py。運行pip install requests beautifulsoup4 python main.py跑完以后可以用瀏覽器或文本編輯器打開books.csv查看是否有正確數據。一個小技巧是先手動用瀏覽器打開目標頁面F12 看一下 HTML 結構和這段代碼的 CSS 選擇器是否匹配。很多時候抓不到數據不是代碼寫錯而是頁面結構和你以為的不一致。7. 運行驗證與失敗排查先看日志再談加功能很多人寫完爬蟲第一次運行發現沒有輸出第一反應是去改選擇器。但更穩妥的順序是先確認請求是否成功再確認解析是否命中最后才懷疑選擇器。建議按這個順序排查確認請求狀態。打印resp.status_code如果不是 200先解決請求層問題。可能原因包括 User-Agent 被攔截、需要登錄、目標站封了 IP。確認頁面內容。打印resp.text[:500]看返回的是不是預期 HTML。有些站點會返回驗證碼頁、安全頁或 JSON 數據說明你的請求模擬成度不夠。確認選擇器命中。在 Python 里先解析并打印len(soup.select(...))如果為 0說明 CSS 選擇器沒有命中。這時候應該回到瀏覽器 F12 重新復制選擇器。確認編碼。如果輸出中文亂碼用resp.encoding resp.apparent_encoding重新指定編碼或者在響應頭里找 charset。確認頻率限制。如果前幾頁正常后面開始超時或 403大概率是請求頻率太高需要增加time.sleep。在第 5 節和第 6 節的代碼里我已經用time.sleep(config.REQUEST_INTERVAL)做了基礎限速。這里想強調爬蟲的穩定性往往不是靠技巧而是靠對請求頻率的控制。真正穩定運行的爬蟲看起來都“不太快”。8. 常見問題與排查思路下面整理一份爬蟲開發過程中最常見的 6 類問題按“現象 - 可能原因 - 排查方式 - 解決方案”給出。這份清單建議收藏后續遇坑可以對照。問題現象可能原因排查方式解決方案狀態碼 403服務端識別出非瀏覽器請求打印請求頭服務端是否要求 UA設置合理 User-Agent或換瀏覽器自動化返回空數據數據由 JavaScript 動態加載查看返回 HTML 是否包含字段使用 Playwright / DrissionPage中文亂碼編碼判斷錯誤查看響應頭 charset設置resp.encoding resp.apparent_encoding爬取到一半超時請求頻率過高被限流查看錯誤日志中的狀態碼增加 sleep 間隔使用代理池GitHub 項目下載慢網絡環境問題查看下載速度使用鏡像站或下載加速服務注意核驗來源依賴版本沖突requests / lxml 等版本不兼容查看 pip 依賴樹創建虛擬環境用 requirements.txt 鎖定版本這里特別提醒一下“代理池”。很多爬蟲教程會說“被封 IP 就上代理”但代理服務和代理池的搭建涉及額外的基礎設施成本對新手來說并不是第一優先級。如果你的爬蟲只是學習或小規模使用控制頻率、添加隨機等待、做好重試比盲目上代理更有效。9. 最佳實踐與學習路線爬蟲項目的工程化建議學爬蟲的人很多但能把爬蟲寫好的人不多。差距往往不在“會不會用某個庫”而在“有沒有工程思維”。下面這幾條經驗來自長時間和爬蟲項目打交道的通用實踐適合所有想從“能跑”走到“能長期跑”的開發者。9.1 從最小項目開始再引入框架不建議一上來就搭 Scrapy 項目。先用 requests BeautifulSoup 跑通一個完整流程理解 HTTP 請求、解析、存儲三個環節。然后當你發現需要處理去重、重試、并發、斷點續爬時再引入 Scrapy 或 feapder。9.2 數據存儲優先考慮 CSV 和 SQLite前期不要急著上 MySQL 或 PostgreSQL。CSV 適合快速查看和調試SQLite 適合單機、結構化查詢。等你真正遇到數據量瓶頸、并發寫庫問題再升級數據庫。這個順序能讓你把精力放在爬蟲本身的邏輯上。9.3 日志是最好的調試工具不要把print當成唯一輸出。做一個簡單的日志文件記錄每次請求的時間、URL、狀態碼、耗時。遇到問題先看日志而不是重新跑一遍。推薦用 Python 自帶的logging模塊不要額外引庫。9.4 學會用瀏覽器 DevTools 看接口很多數據并不需要“爬 HTML”而是直接找到頁面背后的 JSON 接口。打開瀏覽器 F12切換到 Network 面板刷新頁面找到 XHR 請求往往能看到接口返回的干凈 JSON。用 requests 直接請求這個接口比解析 HTML 高效得多。9.5 注意合法合規邊界爬蟲本身是中性技術但使用必須克制。建議始終遵守遵守目標網站的 robots.txt 和使用條款不采集非公開、需要登錄才能訪問且明確禁止的數據控制請求頻率避免影響對方服務學習用途的數據不要用于商業販賣或公開傳播涉及個人信息的采集嚴格遵循最小必要原則。9.6 學習資源清單如果你想深入建議優先看這些官方文檔它們是信息增量最大的來源requests 官方文檔理解 HTTP 會話、重試、代理BeautifulSoup 官方文檔掌握 CSS 選擇器和遍歷Scrapy 官方教程理解框架的 Pipeline、Middleware、SchedulerDrissionPage 官方文檔掌握瀏覽器自動化與請求模式的混合使用Playwright 官方文檔適合復雜交互和調試。練習站點可以使用quotes.toscrape.com、books.toscrape.com、httpbin.org這些公開站點專門用于學習比直接抓取商業站點更穩妥。9.7 增量采集的思路如果你的爬蟲需要長期運行不要每次都全量跑。最簡單的增量方案是記錄上一次抓取的最大 ID 或時間戳下一次抓取只抓比它新的數據。如果做不到那就先抓全量再用數據庫唯一約束去重。再進階一點可以用布隆過濾器或 Redis Set 做 URL 去重但那是后來的事。9.8 關于 GitHub 開源項目的閱讀方法選開源項目時不要只看 star 數。重點看這幾個指標最近一次 commit 時間三年未更新的項目遇到新問題風險高Issue 活躍度有人維護、有人回復才值得深入文檔完整度一份好的 README 包含安裝、示例、常見問題License明確開源協議的項目更安全代碼風格項目里的代碼是否規范、是否容易二次開發。這也是為什么建議你“按需求找項目而不是按熱度找項目”。GitHub 上的爆火項目往往營銷做得好但不一定適合你的業務場景。爬蟲這條路走到后面真正拉開差距的不是你會多少反爬技巧而是你能不能把采集任務拆解成可靠的、可維護的、合法合規的系統。先跑通最小示例再逐步加去重、日志、增量、調度。收藏了那么多開源項目下一步就是挑一個自己熟悉的場景動手寫起來。