Python使用Selenium抓取動(dòng)態(tài)網(wǎng)頁(yè)的方法步驟
1. 什么是動(dòng)態(tài)網(wǎng)頁(yè)抓???
動(dòng)態(tài)網(wǎng)頁(yè)抓取與傳統(tǒng)靜態(tài)網(wǎng)頁(yè)抓取的主要區(qū)別在于:動(dòng)態(tài)網(wǎng)頁(yè)內(nèi)容是通過(guò) JavaScript 在客戶端生成的。這意味著直接請(qǐng)求網(wǎng)頁(yè)的 HTML 文件并不能得到完整的數(shù)據(jù),需要等待 JavaScript 執(zhí)行來(lái)加載數(shù)據(jù)。為了解決這個(gè)問(wèn)題,動(dòng)態(tài)網(wǎng)頁(yè)抓取通常有以下幾種方法:
- 使用自動(dòng)化瀏覽器(如 Selenium):直接讓瀏覽器執(zhí)行 JavaScript,然后抓取加載后的網(wǎng)頁(yè)內(nèi)容。
- 分析網(wǎng)絡(luò)請(qǐng)求:有些網(wǎng)站會(huì)在后臺(tái)向服務(wù)器發(fā)送額外的請(qǐng)求(通常是 JSON 格式的數(shù)據(jù)),可以直接模擬這些請(qǐng)求以獲取數(shù)據(jù)。
- 借助工具庫(kù)(如 Pyppeteer):一些庫(kù)能模擬瀏覽器行為,直接渲染頁(yè)面以獲得完整的內(nèi)容。
2. 準(zhǔn)備工作
在開(kāi)始動(dòng)態(tài)網(wǎng)頁(yè)抓取之前,我們需要安裝一些必要的庫(kù)。
2.1 安裝 Selenium
Selenium 是一個(gè)自動(dòng)化測(cè)試工具,可以通過(guò)控制瀏覽器來(lái)執(zhí)行 JavaScript,從而加載動(dòng)態(tài)內(nèi)容。安裝 Selenium 后,還需要下載與之匹配的瀏覽器驅(qū)動(dòng)(如 ChromeDriver)。
pip install selenium
下載 ChromeDriver(假設(shè)使用 Chrome 瀏覽器),然后將其路徑添加到環(huán)境變量中。
2.2 安裝 Pyppeteer
Pyppeteer 是另一個(gè)強(qiáng)大的動(dòng)態(tài)抓取庫(kù),可以在無(wú)界面模式下執(zhí)行瀏覽器任務(wù)。Pyppeteer 是 Puppeteer 的 Python 版本,Puppeteer 是一個(gè)用于 Node.js 的工具。
pip install pyppeteer
2.3 安裝 Requests 和 BeautifulSoup
雖然 Requests 和 BeautifulSoup 主要用于靜態(tài)網(wǎng)頁(yè)抓取,但它們?cè)讷@取動(dòng)態(tài)網(wǎng)頁(yè)中某些后臺(tái)接口數(shù)據(jù)時(shí)也很有用。
pip install requests beautifulsoup4
3. 使用 Selenium 抓取動(dòng)態(tài)網(wǎng)頁(yè)
我們將通過(guò) Selenium 抓取動(dòng)態(tài)網(wǎng)頁(yè)。首先,我們來(lái)看如何啟動(dòng)瀏覽器、訪問(wèn)網(wǎng)頁(yè)并等待頁(yè)面加載完成。假設(shè)我們要抓取一個(gè)動(dòng)態(tài)加載的商品列表。
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 設(shè)置 ChromeDriver 的路徑 service = Service(executable_path='path/to/chromedriver') # 初始化 Chrome 瀏覽器 driver = webdriver.Chrome(service=service) # 打開(kāi)目標(biāo)網(wǎng)頁(yè) url = 'https://example.com/dynamic-page' driver.get(url) # 等待頁(yè)面加載完成 try: # 等待特定元素加載,假設(shè)我們等待一個(gè)商品列表元素加載 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "product-list")) ) # 抓取頁(yè)面的 HTML 內(nèi)容 page_content = driver.page_source print(page_content) finally: # 關(guān)閉瀏覽器 driver.quit()
3.1 查找元素并提取數(shù)據(jù)
當(dāng)頁(yè)面加載完成后,我們可以使用 Selenium 提供的查找方法來(lái)定位和提取特定元素的內(nèi)容。
# 查找商品名稱的元素(假設(shè) class 為 product-name) products = driver.find_elements(By.CLASS_NAME, 'product-name') for product in products: print(product.text)
3.2 滾動(dòng)頁(yè)面加載更多內(nèi)容
一些動(dòng)態(tài)網(wǎng)頁(yè)會(huì)在用戶滾動(dòng)時(shí)加載更多內(nèi)容,Selenium 可以通過(guò)模擬滾動(dòng)來(lái)抓取更多的數(shù)據(jù):
# 模擬滾動(dòng),加載更多內(nèi)容 SCROLL_PAUSE_TIME = 2 # 獲取當(dāng)前頁(yè)面的高度 last_height = driver.execute_script("return document.body.scrollHeight") while True: # 滾動(dòng)到底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待加載新內(nèi)容 time.sleep(SCROLL_PAUSE_TIME) # 獲取新頁(yè)面的高度 new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break # 如果高度不變,說(shuō)明已經(jīng)加載完畢 last_height = new_height
4. 使用 Pyppeteer 抓取動(dòng)態(tài)網(wǎng)頁(yè)
Pyppeteer 是 Puppeteer 的 Python 版本,它也可以用于抓取動(dòng)態(tài)網(wǎng)頁(yè),并且支持無(wú)頭瀏覽器(headless mode)。
4.1 簡(jiǎn)單示例
以下是一個(gè)使用 Pyppeteer 抓取動(dòng)態(tài)內(nèi)容的簡(jiǎn)單示例:
import asyncio from pyppeteer import launch async def fetch_dynamic_content(url): # 啟動(dòng)瀏覽器 browser = await launch(headless=True) page = await browser.newPage() # 打開(kāi)網(wǎng)頁(yè) await page.goto(url) # 等待特定元素加載完成 await page.waitForSelector('.product-list') # 獲取頁(yè)面內(nèi)容 content = await page.content() print(content) # 關(guān)閉瀏覽器 await browser.close() # 啟動(dòng)異步任務(wù) url = 'https://example.com/dynamic-page' asyncio.get_event_loop().run_until_complete(fetch_dynamic_content(url))
4.2 截圖與調(diào)試
Pyppeteer 還支持截圖功能,可以幫助我們進(jìn)行調(diào)試。
await page.screenshot({'path': 'screenshot.png'})
5. 使用 Requests 抓取動(dòng)態(tài)網(wǎng)頁(yè)中的 API 數(shù)據(jù)
許多動(dòng)態(tài)網(wǎng)站在加載內(nèi)容時(shí),實(shí)際上會(huì)向后端發(fā)送請(qǐng)求獲取數(shù)據(jù)。我們可以在瀏覽器的“網(wǎng)絡(luò)”面板中找到這些請(qǐng)求的 URL,并用 Requests 庫(kù)模擬這些請(qǐng)求來(lái)抓取數(shù)據(jù)。
import requests # 目標(biāo) URL(在瀏覽器網(wǎng)絡(luò)面板中找到的 API 請(qǐng)求 URL) url = 'https://example.com/api/products' # 發(fā)送請(qǐng)求并獲取數(shù)據(jù) response = requests.get(url) data = response.json() # 打印數(shù)據(jù) print(data)
6. 動(dòng)態(tài)抓取的常見(jiàn)問(wèn)題與技巧
6.1 JavaScript 渲染的內(nèi)容未加載
如果頁(yè)面中的內(nèi)容是通過(guò) JavaScript 渲染的,那么直接用 requests
獲取 HTML 不會(huì)包含這些內(nèi)容。這種情況可以考慮:
- 使用 Selenium 或 Pyppeteer,讓瀏覽器真正執(zhí)行 JavaScript 并加載內(nèi)容。
- 找到 JavaScript 背后的 API 請(qǐng)求,直接獲取數(shù)據(jù)。
6.2 遇到驗(yàn)證碼或反爬蟲(chóng)措施
許多網(wǎng)站都有反爬蟲(chóng)措施。遇到這種情況,可以嘗試:
- 調(diào)整請(qǐng)求頻率:增加請(qǐng)求之間的間隔,避免高頻率訪問(wèn)。
- 使用代理:避免使用固定 IP 地址。
- 設(shè)置瀏覽器頭:在請(qǐng)求中添加瀏覽器頭部信息,模擬正常的瀏覽器訪問(wèn)。
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = requests.get(url, headers=headers)
7. 動(dòng)態(tài)抓取的實(shí)際應(yīng)用場(chǎng)景
- 電商數(shù)據(jù)采集:抓取產(chǎn)品列表和詳細(xì)信息。
- 社交媒體分析:獲取社交平臺(tái)的動(dòng)態(tài)內(nèi)容,如推文或評(píng)論。
- 新聞數(shù)據(jù)收集:抓取新聞網(wǎng)站動(dòng)態(tài)加載的新聞條目。
8. 小結(jié)
動(dòng)態(tài)網(wǎng)頁(yè)抓取比靜態(tài)網(wǎng)頁(yè)抓取復(fù)雜得多,因?yàn)樗枰M瀏覽器行為來(lái)執(zhí)行 JavaScript。然而,使用 Selenium 和 Pyppeteer 等工具,我們可以輕松地抓取動(dòng)態(tài)網(wǎng)頁(yè)內(nèi)容。此外,分析網(wǎng)絡(luò)請(qǐng)求并直接抓取 API 數(shù)據(jù)也可以是更高效的方式。希望通過(guò)本文的介紹,您能夠了解 Python 動(dòng)態(tài)網(wǎng)頁(yè)抓取的基礎(chǔ)知識(shí),并運(yùn)用這些工具來(lái)獲取所需的數(shù)據(jù)。
以上就是Python使用Selenium抓取動(dòng)態(tài)網(wǎng)頁(yè)的方法步驟的詳細(xì)內(nèi)容,更多關(guān)于Python Selenium抓取網(wǎng)頁(yè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于python獲取本地時(shí)間并轉(zhuǎn)換時(shí)間戳和日期格式
這篇文章主要介紹了基于python獲取本地時(shí)間并轉(zhuǎn)換時(shí)間戳和日期格式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Python實(shí)現(xiàn)GPU加速圖像處理的代碼詳解
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)GPU加速圖像處理的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04Django框架創(chuàng)建項(xiàng)目的方法入門(mén)教程
這篇文章主要介紹了Django框架創(chuàng)建項(xiàng)目的方法,結(jié)合實(shí)例形式分析了Django框架管理工具的使用及創(chuàng)建項(xiàng)目的相關(guān)操作技巧,需要的朋友可以參考下2019-11-11python實(shí)現(xiàn)在IDLE中輸入多行的方法
下面小編就為大家分享一篇python實(shí)現(xiàn)在IDLE中輸入多行的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04Python中在for循環(huán)中嵌套使用if和else語(yǔ)句的技巧
Python的語(yǔ)法糖非常強(qiáng)大,比如Python中在for循環(huán)中嵌套使用if和else語(yǔ)句的技巧便十分給力,下面我們就舉幾個(gè)例子來(lái)看詳細(xì)的用法:2016-06-06Python phone模塊獲取手機(jī)號(hào)歸屬地 區(qū)號(hào) 運(yùn)營(yíng)商等信息demo
這篇文章主要介紹了Python phone模塊獲取手機(jī)號(hào)歸屬地 區(qū)號(hào) 運(yùn)營(yíng)商等信息的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05使用Python神器對(duì)付12306變態(tài)驗(yàn)證碼
這篇文章主要介紹了使用Python神器對(duì)付12306變態(tài)驗(yàn)證碼的相關(guān)資料,需要的朋友可以參考下2016-01-01使用Python實(shí)現(xiàn)火車(chē)票查詢系統(tǒng)(帶界面)
周末、假期來(lái)了,七夕也快到了,又到一年中最一票難求的時(shí)候了!本文將用Python制作一個(gè)簡(jiǎn)單的火車(chē)票查詢系統(tǒng),感興趣的可以了解一下2022-07-07Jupyter?ipywidgets組件的使用及說(shuō)明
這篇文章主要介紹了Jupyter?ipywidgets組件的使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06