結合Splash與Scrapy:高效爬取動態JavaScript網站

在當今的Web開發中,JavaScript的廣泛應用使得許多網站的內容無法通過傳統的請求-響應模式直接獲取。為了解決這個問題,Scrapy開發者經常需要集成像Splash這樣的JavaScript渲染引擎。本文將詳細介紹Splash JS引擎的工作原理,并探討如何將其與Scrapy框架無縫結合使用。

什么是Splash?

Splash是一個輕量級的瀏覽器服務,專門為Python爬蟲設計,用于渲染JavaScript內容。它基于WebKit引擎,提供了簡單的HTTP API,使開發者能夠通過發送請求來獲取已渲染的頁面內容。

Splash的主要特點

  1. JavaScript渲染:能夠執行頁面中的JavaScript代碼,加載動態內容
  2. HTTP API:通過簡單的RESTful接口控制瀏覽器行為
  3. Lua腳本支持:可以使用Lua編寫復雜的抓取邏輯
  4. 多進程架構:支持并行渲染請求
  5. Scrapy集成:提供官方的Scrapy-Splash插件,方便與Scrapy集成

為什么Scrapy需要Splash?

Scrapy作為強大的爬蟲框架,對于靜態網站有極好的處理能力,但對于動態JavaScript渲染的網站則顯得力不從心。傳統Scrapy只能獲取初始HTML,無法處理:

  • 無限滾動內容
  • 單頁應用(SPA)
  • 需要點擊或交互才能顯示的內容
  • 基于AJAX動態加載的數據

安裝Splash

首先需要安裝Splash服務。有幾種方式可以選擇:

Docker方式(推薦)

docker run -p 8050:8050 scrapinghub/splash

這將在本地的8050端口啟動Splash服務。

手動安裝

也可以從Splash官方倉庫下載源碼編譯安裝。

Scrapy集成Splash

Scrapy官方提供了scrapy-splash包來簡化集成過程。

在這里插入圖片描述

安裝依賴

pip install scrapy-splash

配置Splash

在Scrapy項目的settings.py中添加以下配置:

# 啟用Splash下載器中間件
DOWNLOADER_MIDDLEWARES = {'scrapy_splash.SplashCookiesMiddleware': 723,'scrapy_splash.SplashMiddleware': 725,'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}# 啟用Splash的DUPEFILTER_CLASS
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'# 使用Splash的HTTPCache
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'# Splash服務器設置
SPLASH_URL = 'http://localhost:8050'

使用SplashRequest

在Spider中,使用SplashRequest替代普通的Request

import scrapy
from scrapy_splash import SplashRequestclass JavaScriptSpider(scrapy.Spider):name = 'javascript_spider'start_urls = ['https://example.com']def start_requests(self):for url in self.start_urls:yield SplashRequest(url,self.parse,endpoint='render.html',  # 使用Splash的渲染端點args={'wait': 2,  # 等待2秒讓JS執行'timeout': 30,  # 超時設置'images': 0,  # 禁用圖片加載提高速度})def parse(self, response):# 此處的response已包含渲染后的HTMLtitle = response.css('title::text').get()yield {'title': title}

使用Lua腳本

對于更復雜的場景,可以編寫Lua腳本控制Splash行為:

-- 示例Lua腳本
function main(splash, args)assert(splash:go(args.url))assert(splash:wait(2))return {html = splash:html(),url = splash:url(),}
end

在Scrapy中使用:

yield SplashRequest(url,self.parse,endpoint='execute',  # 使用執行Lua的端點args={'lua_source': lua_script,'wait': 2,}
)

高級技巧

  1. 處理AJAX請求

    • 使用wait參數等待特定時間
    • 或者使用execute端點編寫精確等待條件
  2. 模擬用戶交互

    yield SplashRequest(url,args={'lua_source': '''function main(splash, args)assert(splash:go(args.url))assert(splash:wait(2))splash:runjs("document.querySelector('#search').value='scrapy';")assert(splash:wait(1))splash:mouse_click(100, 200)assert(splash:wait(2))return splash:html()end''','url': url,}
    )
    
  3. 表單提交

    yield SplashRequest(url,args={'lua_source': '''function main(splash, args)assert(splash:go(args.url))assert(splash:wait(2))splash:send_text('username', 'myuser')splash:send_text('password', 'mypassword')splash:runjs("document.querySelector('#login').click();")assert(splash:wait(3))return splash:html()end''','url': login_url,}
    )
    

性能優化

  1. 啟用緩存
    • 配置HTTP緩存中間件
    • 設置合理的緩存過期時間
  2. 并行請求
    • 增加Splash的并發實例(通過Docker -p參數或手動配置)
    • 在Scrapy中增加并發請求數
  3. 選擇性渲染
    • 對不需要JS的頁面使用普通請求
    • 通過dont_filter參數避免重復渲染

常見問題解決

  1. Splash無法加載某些頁面
    • 檢查是否有反爬機制(如Cloudflare)
    • 嘗試設置User-Agent或使用代理
  2. 性能問題
    • 減少不必要的wait時間
    • 禁用圖片加載('images': 0
    • 增加Splash的內存和CPU資源
  3. Lua腳本錯誤
    • 使用Splash的日志功能調試
    • 逐步測試Lua腳本的每個部分

替代方案比較

雖然Splash是一個優秀的選擇,但也可以考慮其他方案:

工具優點缺點
Splash輕量級,Scrapy集成好需要額外服務
Selenium功能強大資源消耗大,速度慢
Playwright現代API,多瀏覽器支持設置較復雜
Puppeteer性能好,Node.js方案需要非Python環境

結論

Splash為Scrapy提供了強大的JavaScript渲染能力,使得爬取動態網站變得可行甚至簡單。雖然它需要額外的服務配置,但對于需要處理現代Web應用的爬蟲項目來說,這是一個值得投資的工具。通過合理配置和優化,可以構建高效、穩定的動態網站爬蟲系統。

對于需要處理大量動態內容的爬蟲項目,建議采用Splash與Scrapy的組合方案,并根據具體需求調整Lua腳本和請求參數。隨著Web技術的發展,掌握這樣的動態爬取技術將成為爬蟲工程師的重要技能。

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

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

相關文章

企業級可觀測性實現:OpenObserve云原生平臺的本地化部署與遠程訪問解析

文章目錄 前言1. 安裝Docker2. 創建并啟動OpenObserve容器3. 本地訪問測試4. 公網訪問本地部署的OpenObserve4.1 內網穿透工具安裝4.2 創建公網地址 5. 配置固定公網地址 前言 嘿,各位小伙伴們,今天要給大家揭秘一個在云原生領域里橫掃千軍的秘密法寶—…

將本地項目提交到新建的git倉庫

方式一: # 登錄git,新建git倉庫和指定的分支,如master、dev# 下載代碼,默認下載master分支 git clone http://10.*.*.67/performance_library/pfme-*.git # 切換到想要提交代碼的dev分支 git checkout dev# 添加想要提交的文件 git add .#…

.NET平臺用C#在PDF中創建可交互的表單域(Form Field)

在日常辦公系統開發中,涉及 PDF 處理相關的開發時,生成可填寫的 PDF 表單是一種常見需求,例如員工信息登記表、用戶注冊表、問卷調查或協議確認頁等。與靜態 PDF 不同,帶有**表單域(Form Field)**的文檔支持…

在macOS上安裝windows系統

使用Boot Camp 1. 準備工作:確認Mac滿足Boot Camp系統要求,準備好Windows安裝光盤或ISO映像文件,以及一個至少8GB的空白USB閃存驅動器用于保存驅動程序。 2. 打開Boot Camp助理:在“應用程序”文件夾的“實用工具”中找到“Boot…

683SJBH基于J2EE的廣州旅游管理系統

第1章  緒論 課題背景 自互聯網internet成為一種革命性的大眾媒體以來,其發展速度之快令人驚嘆。而作為世界最大朝陽產業的旅游,當它與電子商務這一新興模式相結合時,其潛藏的商業價值表露無遺。根據CNN(美國有線電視新聞網&…

前端面試每日三題 - Day 27

這是我為準備前端/全棧開發工程師面試整理的第27天每日三題練習,涵蓋了: CSS選擇器的優先級與權重計算機制Angular中的依賴注入(Dependency Injection)機制設計一個支持實時協作編輯(如Google Docs)的前端…

PostgreSQL數據庫操作SQL

數據庫操作SQL 創建 創建數據庫 create database db_test;創建并指定相關參數 with owner : 所有者encoding : 編碼connection limit :連接限制 create database db_test1 with owner postgresencoding utf-8connection limit 100;修改 修改數據庫名稱 renam…

JSP HTTP 狀態碼詳解

JSP HTTP 狀態碼詳解 引言 HTTP 狀態碼是 HTTP 協議的一部分,用于表示客戶端與服務器之間請求與響應的狀態。在 JavaServer Pages (JSP) 技術中,HTTP 狀態碼同樣扮演著重要的角色。本文將詳細解析 JSP 中的 HTTP 狀態碼,幫助開發者更好地理解和應用這些狀態碼。 HTTP 狀態…

文件一鍵解密軟件工具(支持pdf、word、excel、ppt、rar、zip格式文件)

一鍵解密解鎖神器支持解密pdf、doc、docx、xls、xlsx、ppt、pptx、rar、zip格式文件,Excel表格、Word文檔、PPT演示、RAR、ZIP壓縮包、PDF文檔一鍵輕松解密!簡單/高效/安全。這款軟件由密碼帝官方提供,確保了其合法性和安全性,用戶…

Banana Pi BPI-CM6 是一款八核 RISC-V 模塊,兼容 Raspberry Pi CM 載板

Banana Pi BPI-CM6 是一款 SpacemIT K1 八核 RISC-V 系統級模塊,遵循 Raspberry Pi CM5 的設計,并提供高達 16GB LPDDR4 RAM、高達 128GB eMMC 閃存、千兆以太網控制器和 WiFi 6 藍牙 5.2 模塊。 BPI-CM6 雖然與 Raspberry Pi CM5 基本兼容&#xff0c…

【項目篇之統一硬盤操作】仿照RabbitMQ模擬實現消息隊列

統一硬盤操作 創建出實例封裝交換機的操作封裝隊列的操作封裝綁定的操作封裝消息的操作總的完整代碼: 我們之前已經使用了數據庫去管理交換機,綁定,隊列 還使用了數據文件去管理消息 此時我們就搞一個類去把上述兩個部分都整合在一起&#…

快速上手SpringBoot開發指南

文章目錄 1. 項目整體架構2. SpringBoot核心注解詳解2.1 應用程序入口注解SpringBootApplication 2.2 控制器層注解RestControllerRequestMappingPostMappingRequestBody 2.3 服務層注解ServiceAutowired 2.4 數據訪問層注解Repository 2.5 實體類注解JPA相關注解Lombok注解 3.…

Unity WebGL、js發布交互

官網參考 Unity3D開發之WebGL平臺上 unity和js前端通信交互 WebFun.jslib mergeInto(LibraryManager.library, {JSLog: function (str) { var strsUTF8ToString(str); Log(str); Log(strs);}, Hello: function () {var strs"Hello, world!"; Log(strs); Log(UTF8ToS…

Spark 之 YarnCoarseGrainedExecutorBackend

YarnCoarseGrainedExecutorBackend executor ID , 在日志里也有體現。 25/05/06 12:41:58 INFO YarnCoarseGrainedExecutorBackend: Successfully registered with driver 25/05

[HOT 100] 2646. 最小化旅行的價格總和

文章目錄 1. 題目鏈接2. 題目描述3. 題目示例4. 解題思路5. 題解代碼6. 復雜度分析 1. 題目鏈接 2646. 最小化旅行的價格總和 - 力扣(LeetCode) 2. 題目描述 現有一棵無向、無根的樹,樹中有 n 個節點,按從 0 到 n - 1 編號。給你一…

分析 Docker 磁盤占用

以下是分析 Docker 磁盤占用的詳細步驟和工具指南,幫助開發者快速定位和清理冗余數據: 1. 查看 Docker 磁盤使用概覽 docker system df 輸出說明: TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 15 …

聊一聊接口測試中的參數化測試

目錄 一、核心概念 二、適用場景 三、參數化測試的核心目的 四、實現參數化測試的關鍵步驟 4.1 定義測試數據 4.2 使用測試框架參數化功能 4.3 執行測試與結果分析 五、最佳實踐與注意事項 六、工具推薦 那參數化測試的目的是什么?應該是為了提高測試覆蓋率…

Go語言——string、數組、切片以及map

一、string、數組、切片代碼 package mainimport "fmt"// 定義結構體 type student struct {id intname stringage intscore float32 }func main() {// 使用var聲明切片var slice1 []intslice1 append(slice1, 1)slice1 append(slice1, 2)slice1 append(sl…

Android 開發中JDK 的使用和配置詳解

前些天發現了一個蠻有意思的人工智能學習網站,8個字形容一下"通俗易懂,風趣幽默",感覺非常有意思,忍不住分享一下給大家。 ??點擊跳轉到教程 在安卓開發中, 我們會使用到Java的JDK, JDK全程為(Java Development Kit)意思是:Java開發工具包。那么JDK 與我們的…

MPay碼支付系統第四方聚合收款碼多款支付插件個人免簽支付源碼TP8框架全開源

一、源碼描述 這是一套碼支付源碼(MPay),基于TP8框架,前端layui2.9后端PearAdmin,專注于個人免簽收款,通過個人的普通收款碼,即可實現收款通知自動回調,支持絕大多數商城系統&#…