1. 分頁的介紹
誰說你需要的數據一定會在同一個頁面上?很多時候你得從一堆頁面中把它們撈出來,或者它們壓根分散在整個網站上。所以,你會面臨的第一個挑戰就是數據分頁 (pages)。而那份有趣的數據收集工作被稱為 pagination(分頁)。
是的,分頁不僅僅是當你期待 Google 搜尋結果跳到下一頁時會遇到的事,還是在你作為 web-scraper 想辦法自動化這一過程時的挑戰:如何不手動點擊而實現自動化?
分頁就是一種網站組織數據的方式,避免出現過長的網頁內容。相反的,網站會把數據分成多頁,並添加一些像「下一頁」或「更多」之類的連結,方便跳轉到下一頁。這是一個重要的概念,因為作為 web-scraper 的你,不可能向你的老闆說,有些內容因為藏在「第五頁」所以沒抓取到吧。
2. 從多個頁面抓取數據的挑戰
第一個挑戰是遇到不直觀、不規律的 URL。有些網站的 URL 在切換頁面時並不會有明顯的變化,這讓自動化變得非常困難。例如,取而代之的是 page=1
, page=2
,你可能會遇到 x=abc
, x=def
,這種完全看不出規律的情況。
第二個挑戰是防止機器人爬取的系統保護。一些網站會密切監控來自單個 IP 位址的請求次數。如果它們發現你請求次數過多,可能會暫時甚至永久封鎖你。
不過別擔心,我們現在學習如何像真正的 scraper 一樣應對這些困難。
3. 分頁的應對方法
技巧和策略
-
分析 URL 結構: 通常頁面會使用參數來標示頁碼,例如
?page=2
。如果你發現這樣的模式,恭喜你,找到了分頁的「黃金模板」! - 尋找「下一步」的連結: 有時候 URL 無法預測。在這種情況下,你需要在頁面中搜索像「下一頁」或「更多」的連結,然後點擊跟隨它們。
- 使用 AJAX 請求: 某些網站通過 AJAX 載入數據而無需刷新頁面。在這種情況下,你需要攔截這些請求並模仿它們。
讓我們進入實踐階段!
分頁與數據抓取腳本範例
下面是腳本範例:
import requests
from bs4 import BeautifulSoup
# 從單頁中獲取數據的函數
def get_data_from_page(url):
response = requests.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser')
# 這裡從 soup 中提取數據 - 範例
data = soup.find_all('div', class_='data-class')
for item in data:
print(item.text) # 打印或保存數據
else:
print(f"無法獲取頁面: {url}")
# 遍歷所有頁面的主要邏輯
def scrape_all_pages(start_url):
current_url = start_url
while current_url:
get_data_from_page(current_url)
soup = BeautifulSoup(requests.get(current_url).text, 'html.parser')
# 嘗試找到「下一步」的連結
next_button = soup.find('a', text='下一步')
if next_button:
current_url = next_button['href']
else:
current_url = None
# 從第一頁開始抓取
start_url = 'http://example.com/page=1'
scrape_all_pages(start_url)
這是一個基本範例,演示了如何處理分頁的原理。你需要根據你的網站結構進行適應性修改。
管理 Session 與使用 user-agent
當你向網站發送多個請求時,使用 session 和更改 user-agent 會非常有效,能降低被封鎖的風險。
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
session = requests.Session()
session.headers.update(headers)
response = session.get('http://example.com')
這種結構比直接發送不帶 header 的請求更加真實地模仿了瀏覽器行為。
4. 實踐應用
現在我們已經掌握了基礎,讓我們稍微複雜化一點場景。考慮一種情況,頁面連結包含不可預測的參數,並且我們需要使用 AJAX 來獲取數據。
基於 AJAX 的實現
有時候數據不會載入在主頁上,而是通過 AJAX 動態載入。如果你發現網站是這樣工作的,可以用瀏覽器的網絡調試工具來分析後台發出的請求。接著,用 Python 模仿這些請求。
# AJAX 請求示例
ajax_url = 'http://example.com/ajax_endpoint'
params = {
'some_param': 'value', # 如果需要,請求參數
'page': 1
}
while True:
response = session.get(ajax_url, params=params)
data = response.json()
if not data['has_more']:
break
# 處理數據
for item in data['items']:
print(item)
params['page'] += 1 # 跳轉到下一頁
這種方法適用於你經過細致分析請求與回應後,了解數據加載流程的情況。
今天的課程將我們帶入了迷人且經常挑戰耐性的分頁世界。掌握這項技能將使你能夠自信且高效地從網站收集數據,不會錯過任何頁面。畢竟,無論是 web-scraping 還是人生,方法和堅持才是成功的關鍵,因為誰知道在第二十頁上隱藏了什麼寶藏呢!
GO TO FULL VERSION