使用 Selenium 爬取動態網頁數據 —— 實戰與坑點詳解

本文記錄了筆者在爬取網頁數據過程中遇到的各種技術挑戰,包括頁面動態渲染、JavaScript 注入等問題,并最終給出一個可運行的完整方案。

文章目錄

    • 網頁獲取不到數據
    • 🚀 嘗試用 Selenium 渲染頁面

網頁獲取不到數據

某網頁數據依賴大量 JavaScript 動態渲染。筆者最初嘗試通過直接請求頁面源代碼的方法(如 requests)來獲取頁面中的源代碼內容,看看HTML的網頁結構,結果發現頁面核心數據并未寫死在 HTML 中,而是通過 JS 模塊懶加載,并渲染到 DOM 后才可見。

如下為典型的 script 標簽:

<script nonce="..." type="module" src="//c-cdn.qixin.com/web/_web/UbfmNsyd.js" crossorigin>
</script>

直接請求 HTML 無法獲得數據的,使用 BeautifulSoup 解析 <script> 可能也沒用,因為內容可以是異步加載、并由 JS 渲染進 DOM 。

下述是一個下載網頁源代碼保存到本地 html 的 python代碼:

import requests# 目標網頁 URL
url = '替換成你要爬的網頁地址'# 自定義請求頭,防止被識別為爬蟲
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ''(KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'
}# 發送 GET 請求
response = requests.get(url, headers=headers)# 判斷請求是否成功
if response.status_code == 200:# 保存為本地 HTML 文件with open('page.html', 'w', encoding='utf-8') as f:f.write(response.text)print("網頁源代碼已保存為 page.html")
else:print(f"請求失敗,狀態碼: {response.status_code}")

保存到本地的HTML 文件:
在這里插入圖片描述
所需要的數據都在 <script> 里面。

request庫不能運行js代碼,我們需要使用 selenium 借助瀏覽器運行js代碼,完成dom的渲染。

🚀 嘗試用 Selenium 渲染頁面

為了解決數據渲染問題,我們使用 Selenium 啟動一個真實的 Chrome 瀏覽器,讓 JavaScript 有機會執行,待頁面加載完畢后再提取數據

裝包:

pip install selenium webdriver-manager
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
url = "https://www.qixin.com/company/7b752b1d-8d49-4a67-9472-04cef0b301ec"options = webdriver.ChromeOptions()## Chrome,無頭模式(不彈窗)
# options.add_argument('--headless')  # 去掉這行可以看到瀏覽器
# options.add_argument('--disable-gpu')driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options
)driver.get(url)
input(">掃碼登陸,確認開始?")# urls: 網址列表
for url in urls:lock = Falsewhile 1:try:driver.get(url)# 等待目標數據出現(最多等 30 秒)WebDriverWait(driver, 30).until(# EC.presence_of_element_located((By.CLASS_NAME, "table"))EC.presence_of_element_located((By.CSS_SELECTOR,"#__nuxt > div > ... > div > div.credit-number",)))lock = Falseexcept Exception as e:lock = Trueuser_input = input("在網頁上驗證碼,輸入 skip 跳過,否則繼續運行").strip()if user_input == "skip":lock = Falseif lock == False:breaktext = driver.find_element(By.XPATH, '//*[@id="__nuxt"]/div/.../div[2]').text.strip()print(text)

值得注意的是 javascritps 如果需要加載外部的js文件,存在網絡傳輸的時間,如果在 driver.get(url) 后立即調用 driver.find_element 則找不到對應的值,因為js還沒有執行完畢。上述代碼使用 WebDriverWait 等待 js 運行完成。

💡 小貼士(Tip):
把 WebDriverWait 換成 sleep 一個較長的時間也是可以的,因為本質上都是等待 js 運行完成,但更推薦 使用WebDriverWait 。

WebDriverWait(driver, 30).until(# EC.presence_of_element_located((By.CLASS_NAME, "table"))EC.presence_of_element_located((By.CSS_SELECTOR,"#__nuxt > div > ... > div > div.credit-number",))
)

#__nuxt > div > … > div > div.credit-number 是 網頁上目標數據的 css。
上述代碼 一直等待目標數據在網頁上渲染完成,最多等待30秒。
等到目標數據渲染成功后,使用 driver.find_element 就可以得到正確的目標數據。

為了盡可能多地保留每一條數據,使用while循環重復請求每個url,直到獲取到正確的目標數據才退出,如果遇到報錯,會被 try except 捕獲到異常,當代碼正確執行,lock為False會跳出 while,爬取下一個 url。

每一次報錯,都會被 input 中斷,可能是需要用戶在網頁上輸入驗證碼,用戶在輸入完驗證碼后,輸入任意字符會繼續爬取。若不是需要驗證碼,而是該網頁報錯(比如:404),那么用戶可以輸入 skip 實現跳過當前頁面的爬取。

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

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

相關文章

【信息系統項目管理師】法律法規與標準規范——歷年考題(2024年-2020年)

手機端瀏覽?【信息系統項目管理師】法律法規與標準規范——歷年考題&#xff08;2024年-2020年&#xff09; 2024年上半年綜合知識【占比分值3′】 42、關于招標投標的描述&#xff0c;不正確的是&#xff08;屬于同一集團組織成員的投標人可以按照該組織要求協同投標&#xf…

多模態大語言模型arxiv論文略讀(五十六)

DesignQA: A Multimodal Benchmark for Evaluating Large Language Models’ Understanding of Engineering Documentation ?? 論文標題&#xff1a;DesignQA: A Multimodal Benchmark for Evaluating Large Language Models’ Understanding of Engineering Documentation …

Docker 渡渡鳥鏡像同步站 使用教程

Docker 渡渡鳥鏡像同步站 使用教程 &#x1f680; 介紹 Docker.aityp.com&#xff08;渡渡鳥鏡像同步站&#xff09;是一個專注于為國內開發者提供 Docker 鏡像加速和同步服務的平臺。它通過同步官方鏡像源&#xff08;如 Docker Hub、GCR、GHCR 等&#xff09;&#xff0c;為…

Unity:AddTorque()(增加旋轉力矩)

目錄 什么是 AddTorque()&#xff1f; 第一性原理出發&#xff1a;什么是 Torque&#xff08;力矩&#xff09;&#xff1f; Torque 公式 Unity 中 AddTorque 的工作原理 參數屬性 &#x1f50d; Linear Drag&#xff08;線性阻力&#xff09; 線性阻力模擬的現實情況&…

async/await的另一種食用方法

在JavaScript/TypeScript的異步編程中&#xff0c;async/await讓我們的代碼看起來更像是同步的&#xff0c;極大地提高了可讀性。然而&#xff0c;錯誤處理仍然是一個需要仔細考慮的問題。今天我要分享一種優雅的錯誤處理模式&#xff0c;它能讓你的異步代碼更加簡潔。 傳統tr…

計算機網絡 - stp生成樹實驗

【實驗假設】 我們使用 Cisco Packet Tracer 或類似的模擬軟件&#xff0c;或物理的 Cisco 交換機。 交換機初始為默認配置&#xff08;或已通過 write erase 和 reload 清除配置&#xff09;。 PC 已配置 IP 地址如下&#xff08;示例&#xff09;&#xff1a; PC0: 192.168…

淺析 Spring 中 FactoryBean 的實現與使用

淺析 Spring 中 FactoryBean 的實現與使用 一、FactoryBean核心機制剖析二、高級應用場景與實戰三、框架級應用案例解析四、FactoryBean常見面試題 一、FactoryBean核心機制剖析 1. 本質與雙重角色 FactoryBean是Spring容器中用于定制化對象創建的核心接口&#xff08;org.spri…

vue3 element-plus 輸入框回車跳轉頁面問題處理

問題描述&#xff1a; 當頁面搜索條件只有一個的情況下&#xff0c;輸入框不管有沒有值&#xff0c;回車后會跳轉頁面 解決辦法&#xff0c;給表單添加 submit.prevent <el-form ref"ruleForm" :model"search" label-width"120px" class&qu…

(51單片機)LCD展示動畫(延時函數)(LCD1602教程)

前言&#xff1a; 前面我們說過&#xff0c;之前LCD1602模塊有點難&#xff0c;但是現在&#xff0c;我們通過幾遍博客的學習&#xff0c;今天來講一下LCD1602的原理 演示視頻&#xff1a; LCD1602流動 源代碼&#xff1a; main.c #include <STC89C5xRC.H> #include &q…

深入了解 OpenIddict:實現 OAuth 2.0 和 OpenID Connect 協議的 .NET 庫

在現代 Web 開發中&#xff0c;身份驗證和授權是安全性的重要組成部分。隨著對安全性的要求不斷增加&#xff0c;OAuth 2.0 和 OpenID Connect&#xff08;OIDC&#xff09;協議已經成為許多應用程序的標準身份驗證方式。而 OpenIddict&#xff0c;作為一個用于實現 OAuth 2.0 …

【C++游戲引擎開發】第30篇:物理引擎(Bullet)—軟體動力學系統

一、軟體動力學理論體系 1.1 連續體力學基礎 1.1.1 變形梯度張量 物體運動可描述為映射函數: x = ? ( X , t ) \mathbf{x} = \phi(\mathbf{X},t) x

Android Compose 層疊布局(ZStack、Surface)源碼深度剖析(14)

Android Compose 層疊布局&#xff08;ZStack、Surface&#xff09;源碼深度剖析 一、引言 在 Android 應用開發領域&#xff0c;用戶界面&#xff08;UI&#xff09;的設計與實現一直是至關重要的環節。隨著技術的不斷演進&#xff0c;Android Compose 作為一種全新的聲明式…

性能優化實踐:內存優化技巧

性能優化實踐&#xff1a;內存優化技巧 在Flutter應用開發中&#xff0c;內存優化是提升應用性能的關鍵環節之一。本文將從實戰角度深入探討Flutter內存優化的各種技巧&#xff0c;幫助你構建高性能的Flutter應用。 一、內存分析工具使用 1. DevTools內存分析器 啟動DevTool…

2025-05-07 Unity 網絡基礎8——UDP同步異步通信

文章目錄 1 UDP 概述1.1 通信流程1.2 TCP 與 UDP1.3 UDP 分包1.4 UDP 黏包 2 同步通信2.1 服務端2.2 客戶端2.3 測試 3 異步通信3.1 Bgin / End 方法3.2 Async 方法 1 UDP 概述 1.1 通信流程 ? 客戶端和服務端的流程如下&#xff1a; 創建套接字 Socket。用 Bind() 方法將套…

如何減少鎖競爭并細化鎖粒度以提高 Rust 多線程程序的性能?

在并發編程中&#xff0c;鎖&#xff08;Lock&#xff09;是一種常用的同步機制&#xff0c;用于保護共享數據免受多個線程同時訪問造成的競態條件&#xff08;Race Condition&#xff09;。然而&#xff0c;不合理的鎖使用會導致嚴重的性能瓶頸&#xff0c;特別是在高并發場景…

AGV智能搬運機器人:富唯智能引領工業物流高效變革

在智能制造與工業4.0深度融合的今天&#xff0c;物流環節的高效與精準已成為企業核心競爭力的關鍵。富唯智能憑借其自主研發的AGV智能搬運機器人&#xff0c;以創新技術重塑工業物流標準&#xff0c;助力企業實現降本增效的跨越式發展。 一、技術突破&#xff1a;精準導航與智能…

K8s 資源分類

K8s 資源分類圖譜 內置資源的分類 1、工作負載相關&#xff1a; Pod&#xff1a;最小的部署單元&#xff0c;包含一個或多個容器。 Deployment&#xff1a;管理無狀態應用的副本和滾動更新。 StatefulSet&#xff1a;適用于有狀態應用&#xff08;如數據庫&#xff09;&#…

VLM-AD:通過視覺語言模型監督實現端到端自動駕駛

《VLM-AD: End-to-End Autonomous Driving through Vision-Language Model Supervision》2024年12月發表&#xff0c;來自Cruise和美國東北大學的論文。 人類駕駛員依靠常識推理來駕馭多樣化和動態的現實世界場景。現有的端到端&#xff08;E2E&#xff09;自動駕駛&#xff0…

目標檢測中的損失函數(三) | SIoU WIoUv1 WIoUv2 WIoUv3

&#x1f680;該系列將會持續整理和更新BBR相關的問題&#xff0c;如有錯誤和不足懇請大家指正&#xff0c;歡迎討論&#xff01;&#xff01;&#xff01; SCYLLA-IoU&#xff08;SIoU&#xff09;來自掛在2022年arxiv上的文章&#xff1a;《SIoU Loss: More Powerful Learnin…

http Status 400 - Bbad request 網站網頁經常報 HTTP 400 錯誤,清緩存后就好了的原因

目錄 一、HTTP 400 錯誤的常見成因(一)問題 URL(二)緩存與 Cookie 異常(三)請求頭信息錯誤(四)請求體數據格式不正確(五)文件尺寸超標(六)請求方法不當二、清緩存為何能奏效三、其他可以嘗試的解決辦法(一)重新檢查 URL(二)暫時關閉瀏覽器插件(三)切換網絡環…