
掌握网页抓取中的分页:完整指南
在本指南中,我们将深入了解分页、它为何对网页抓取很重要,以及最关键的------如何顺利处理它。读完之后,你将能够自信地从多页网站抓取数据,而不会感到不知所措。让我们让分页不再成为需要担心的问题。
处理分页的自动化解决方案
以下 3 项服务可以在分页抓取的每个步骤中为你提供帮助,无论是仅使用代理,还是使用完全自动化的 API:
-
Bright Data --- 高级抓取的综合最佳选择;具备广泛的代理管理功能和可靠的 API。
-
Octoparse --- 用户友好的无代码工具,可用于从网站自动提取数据。
-
ScrapingBee --- 面向开发者的 API,可高效处理代理、浏览器和 CAPTCHA。
我与它们中的任何一家都没有关联。
什么是分页?
电商平台、招聘网站和社交媒体等网站会使用分页来处理大量数据。如果把所有内容都显示在一个页面上,会拖慢下载速度并占用过多内存。分页会将内容拆分到多个页面中,使其更易于管理。它还提供了简单的导航方式,例如"下一页"按钮、页码或自动滚动。这能让浏览保持快速且组织有序。分页确保用户能够快速找到所需内容,同时不会让系统不堪重负。
分页类型
分页的复杂程度各不相同。它既可以是简单的方法,也可以是无限滚动等更高级的技术。根据我的经验,我总结出网站上常见的三种主要分页类型:
-
编号分页:这种方法允许用户通过带编号的链接在不同页面之间导航。用户点击数字即可查看不同组的内容。
-
点击加载分页:在这种方式中,用户点击"加载更多"等按钮来显示更多内容。这可以更可控地加载数据。
-
无限滚动:使用无限滚动时,内容会随着用户向下滚动页面而自动加载。这能创造无缝的浏览体验,无需逐页点击。
编号分页
编号分页使用独立的页面链接,通常显示在网站底部,让用户可以直接从一个页面跳转到另一个页面。这种方法是最容易抓取的方式之一,因为 URL 通常会递增变化(例如 /page=2、/page=3),因此可以很方便地通过程序遍历页面。
要抓取带编号分页的网站,我们需要:
-
识别基础 URL 和 URL 模式。
-
在循环中递增页面参数,直到到达最后一页。
使用 Python 的 BeautifulSoup 示例:
import requests
from bs4 import BeautifulSoup
base_url = "https://example.com/items?page="
page_num = 1
while True:
response = requests.get(base_url + str(page_num))
if response.status_code != 200:
break
soup = BeautifulSoup(response.text, 'html.parser')
Extract the data you need from soup object here
print(f"Scraping page {page_num}...")
If no next page link or last page is reached, exit loop
if not soup.find('a', {'class': 'next-page'}):
break
page_num += 1
在上述代码中,爬虫工具会持续递增 page_num 变量并抓取每个页面,直到找不到后续的"下一页"按钮为止。
挑战:
-
有些网站可能使用动态页码,或使用 JavaScript 加载内容。
-
并非所有编号分页都会显示在 URL 中;有时会涉及 AJAX 调用,需要更深入地检查。
点击加载分页
点击加载分页通常以"加载更多"按钮的形式实现,会在同一页面上动态加载新内容。这要求爬虫反复模拟点击事件,以加载所有可用内容。
使用 Selenium 处理点击加载分页:
由于点击加载分页通常依赖 JavaScript,因此使用 Selenium 或 Playwright 等工具会很有效。这些工具允许我们与页面元素交互并加载所需内容。
使用 Selenium 示例:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Chrome()
driver.get("https://example.com/items")
while True:
try:
load_more_button = driver.find_element(By.XPATH, "//buttontext()='Load More'")
load_more_button.click()
time.sleep(2) # Give time for content to load
except:
break
After loading all items, scrape the data
items = driver.find_elements(By.CLASS_NAME, "item")
for item in items:
print(item.text)
driver.quit()
在上面的示例中,find_element 方法用于定位"加载更多"按钮,然后调用 click() 来加载更多内容,直到该按钮不再出现。
挑战:
-
需要与 JavaScript 交互。
-
多次点击可能触发速率限制或 CAPTCHA。
无限滚动
无限滚动会在用户向下滚动时自动加载更多内容,从而无需分页按钮。虽然它对用户很方便,但由于依赖 JavaScript 和动态加载内容,它会让网页抓取变得更复杂。
使用 Playwright 处理无限滚动:
Playwright 支持基于 Chromium 的浏览器自动化,可以处理无限滚动。这种技术会模拟用户滚动操作,直到不再加载更多内容。
使用 Playwright 示例:
import asyncio
from playwright.async_api import async_playwright
async def scroll_to_bottom(page):
while True:
previous_height = await page.evaluate("document.body.scrollHeight")
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await asyncio.sleep(2)
new_height = await page.evaluate("document.body.scrollHeight")
if new_height == previous_height:
break
async def scrape_infinite_scroll(url):
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto(url)
await scroll_to_bottom(page)
Extract data after fully loading the page
content = await page.content()
print(content)
await browser.close()
asyncio.run(scrape_infinite_scroll("https://example.com/items"))
这段代码会一直向下滚动,直到没有更多内容被加载,从而确保所有条目都在页面上可见,便于抓取。
挑战:
-
判断何时停止滚动并不总是很直接。
-
有些网站会实施诸如懒加载之类的机制,即图片只有在进入视口时才会加载。
分页中的挑战
处理分页内容时,必须考虑多种风险。其中一个重大挑战是可能被网站封锁。有些网站可能在访问一个页面后就阻止继续访问。例如,如果你尝试从 Amazon 这样的电商网站抓取数据,可能会遇到 CAPTCHA 挑战等障碍。
Amazon CAPTCHA 挑战
让我们向 Amazon 首页发起请求,看看会发生什么。
import requests
url = "https://www.amazon.com/"
response = requests.get(url)
print(f"Status code: {response.status_code}")
在这种情况下,你可能会收到一个 403 状态码。
该状态表示 Amazon 已检测到你的请求来自机器人或抓取工具,因此触发了 CAPTCHA 挑战。如果你继续发送多个请求,你的 IP 地址可能会立即被封锁。
为了绕过这些封锁并有效收集所需数据,你可以将代理与 Python Requests 一起使用。这种技术有助于避免 IP 封禁。此外,你还可以通过轮换 User Agent 来模拟真实浏览器。不过,需要注意的是,这些方法无法保证能成功对抗高级机器人检测系统。
结论
对于从以分段形式呈现内容的网站收集完整数据来说,处理分页至关重要。在这里,我介绍了主要的分页类型:编号分页、点击加载分页和无限滚动。我还说明了如何使用 BeautifulSoup、Selenium 和 Playwright 等工具来管理这些分页。
工具的选择取决于分页类型。对于编号分页,我通常可以使用简单循环;而点击加载和无限滚动则需要自动化框架来模拟用户操作。
为了提高我的网页抓取项目的可靠性,我会遵循一些最佳实践,例如限制请求频率、平滑处理错误以及轮换代理。理解这些技术有助于我为任何分页内容创建有效的网页爬虫。