當滾動加載遇上"偽動態"頁面,90%的人直接打開了瀏覽器自動化工具——而真相藏在網絡請求里。
1. 看起來需要瀏覽器,實則不然
![]()
Hindwi.org 是印地語文學領域維護較好的數字檔案庫。從8世紀古典詩人到當代作家,數千位詩人、數萬首詩作,時間跨度超過一千年。
作者需要為論文構建一個大型印地語詩歌語料庫,這個網站恰好滿足全部需求。計劃很簡單:抓取數據,然后推進正事。
但頁面交互模式瞬間觸發了工程師的條件反射——訪問 /poets 目錄,詩人列表隨滾動持續加載;點進單個詩人頁面,詩作同樣滾動觸發。內容不在初始 HTML 中,JavaScript 動態注入,典型的"需要瀏覽器"場景。
Selenium 方案迅速落地:無頭 Chrome、模擬滾動、等待元素渲染、提取內容。能跑通,但速度令人窒息。
核心矛盾不是慢,而是瀏覽器自動化天生難以并行化。你無法像 HTTP 請求那樣輕松啟動十個線程同時抓取十位詩人——每個瀏覽器實例自帶渲染引擎、內存空間、JavaScript 運行時,資源成本指數級疊加,實例間協調更是噩夢。粗略估算:2.5萬首詩,天數級而非小時級。
必須換條路。
2. 網絡層面的真相:純 GET 請求,零驗證
在繼續寫 Selenium 代碼之前,作者打開了瀏覽器開發者工具的 Network 標簽頁——這是提交瀏覽器自動化方案前的必要步驟。
前端呈現的"動態"行為,在網絡層歸根結底仍是 HTTP 請求。瀏覽器必須從某處獲取數據,問題在于這個"某處"是否可直接訪問。
滾動到詩人列表底部時,瀏覽器發出的請求如下:
https://www.hindwi.org/PoetCollection?lang=2&pageNumber=2&Info=poet&StartsWith=&keyword=&typeID=659186cb-44e7-4d94-8b1a-ffc70f939a733&TypeSlug=poets&contentFilter=&_=1777462454692
純 GET 請求。請求體無認證令牌,無加密簽名,無 WebSocket 握手,只有查詢參數。末尾的 _=1777462454692 是瀏覽器自動追加的緩存破壞時間戳——服務器并不校驗,爬蟲可直接忽略。
返回的是原始 HTML,非 JSON、非 XML,而是可直接注入 DOM 的卡片結構:詩人姓名、生卒年份、個人頁鏈接。網站未提供正規 API,但交付了結構化、分頁化、純 HTTP 可達的數據。
截圖:開發者工具 Network 標簽頁顯示 /PoetCollection 請求及其 HTML 響應體
3. 從 URL 構造到全站抓取:逆向工程的三層遞進
下一個問題:瀏覽器如何知道請求哪個 URL?
觀察發現規律:初始頁面加載時,JavaScript 從當前 URL 提取參數(如 typeID、TypeSlug),滾動時遞增 pageNumber。這些參數是硬編碼在頁面中的常量,非動態生成。這意味著爬蟲可以跳過瀏覽器,直接構造請求序列。
作者用 Python 的 requests 庫配合 BeautifulSoup 重寫了抓取邏輯。循環遞增頁碼,解析返回的 HTML,提取詩人信息。單個詩人頁面的詩作列表同理——滾動觸發的請求結構完全一致,只是端點變為 PoemCollection,參數中的詩人 ID 來自前一步抓取結果。
并行化瞬間變得廉價。線程池同時處理多個分頁請求,內存占用從瀏覽器實例的數百兆降至單個 Python 進程的幾十兆。原本預估數天的任務,實際運行時間壓縮到兩小時以內。
關鍵認知:網站的"動態感"是前端框架(此處為 jQuery 驅動的無限滾動)制造的幻覺,數據層并未設防。這種架構在 2010 年代中期的內容站點中極為常見——開發者追求交互體驗,卻未在 API 層實施任何訪問控制。
4. 為什么工程師會集體誤判:認知捷徑的代價
這個案例暴露了一個行業慣性:滾動加載 ≈ 需要瀏覽器,已成為許多爬蟲工程師的默認假設。
誤判的根源在于工具鏈的成熟度。Selenium、Playwright、Puppeteer 的文檔豐富,社區方案成熟,遇到動態內容時啟動瀏覽器是"安全選擇"。相比之下,分析網絡請求需要更多調試時間,且存在"網站確實做了加密/驗證"的風險。
但 Hindwi 的架構提供了反例:無限滾動的視覺反饋與數據獲取方式完全解耦。前端用 JavaScript 管理狀態、觸發請求、渲染 DOM,后端卻暴露著無鑒權的分頁端點——這種設計在當年降低了開發成本,卻為爬蟲留下了敞開的后門。
作者指出,這一模式具有普遍性。"任何看起來像需要瀏覽器自動化的網站,都值得先用開發者工具檢查網絡請求。動態行為在前端,但數據獲取在網絡層——而網絡層往往比想象中更裸露。"
資源消耗的對比數據說明了問題:25 個并行 HTTP 線程的內存 footprint,約等于單個無頭 Chrome 實例;而前者可處理的吞吐量是后者的數十倍。當數據規模達到萬級,這種差距直接決定項目可行性。
5. 產品設計的隱性債務:當用戶體驗成為安全漏洞
Hindwi 的案例并非技術失敗,而是產品決策的副產品。
2015 年前后,無限滾動成為內容站點的標準交互范式。它提升了用戶停留時長,降低了跳出率,卻將數據獲取邏輯暴露在前端 JavaScript 中。任何具備基礎網絡調試能力的用戶,都能逆向出數據端點。
更深層的問題在于:網站運營方是否意識到這種暴露?印地語文學檔案的維護者顯然將資源投入在內容數字化上,而非反爬蟲機制。這解釋了為何 typeID 等參數以明文硬編碼、為何分頁端點無速率限制、為何時間戳參數可被忽略——這些"漏洞"在工程優先級中從未被正視。
對研究者而言,這是幸運。作者的論文因此獲得了 2.5 萬首詩歌的語料基礎,而成本僅為一臺筆記本電腦的兩小時運行時間。
但對同類站點的運營者,這是警示。當數據資產具有商業價值或版權敏感性時,前端框架的"便利"可能轉化為法律風險的敞口。區分"公開訪問"與"可批量獲取"的邊界,需要架構層面的主動設計,而非依賴用戶的善意。
作者最終沒有使用任何瀏覽器自動化工具。整個語料庫的構建基于 30 行 Python 代碼:構造 URL、并發請求、解析 HTML、存儲結果。代碼已開源,作為"看起來需要 Selenium 的網站"的參考實現。
這件事的核心教訓:技術選型前的五分鐘網絡分析,可能節省數天的工程時間。在數據抓取領域,最昂貴的成本往往不是計算資源,而是未經審視的假設。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.