对于用静态 HTML 和 CSS 构建的网站,像 Python 的请求库和 Beautiful Soup 这样的简单工具通常能在网页抓取时完成工作。然而,在处理基于动态 JavaScript 框架(如 React、Angular 和 Vue)的高级网站时,抓取动态内容变得棘手。这些框架通过提供预构建的组件和架构简化了网页开发,但也使动态网站难以被抓取。
在这篇博客文章中,我们将概述动态网站和静态网站的区别,并提供动态网页爬取的逐步指南,特别是那些具有无限滚动功能的网站。
什么是动态网站?它与静态网站有何不同?
动态网站是指 HTML 页面不是固定的,而是基于用户操作、数据库查询或其他因素实时生成的网站。与静态网站向每位访客提供相同的预建 HTML 文件不同,动态网站可以实时加载内容,这意味着不同用户根据行为、偏好或搜索输入可以看到同一页面的不同版本。
这种区别主要取决于每种类型的请求处理方式。静态页面只需快速、直接且对所有人都一样的固定文件。在动态网页中,服务器首先进行中间处理,查询数据库,应用逻辑并个性化内容,然后将最终结果发送到浏览器。这使得动态网站更复杂,但互动性和个性化功能也更丰富。
电子商务产品页面、社交媒体动态和账户仪表盘都是常见例子——底层 URL 可能相同,但内容会根据谁和何时访问而变化。
网页抓取动态内容的挑战
抓取动态内容带来了独特的挑战,而像 Python 的请求库和 Beautiful Soup 这样的简单工具无法应对。其中一些可能包括:
-
JavaScript 渲染 :基本的 HTTP 请求无法实时捕获由 React、Angular 和 Vue 等框架生成的 HTML
-
弹窗和叠加层:中间元素可能阻碍内容访问并中断抓取流程
-
下拉菜单和实时搜索建议 :需要用户输入才能揭示内容的互动元素
-
实时更新 :内容如果不经过页面重载,持续变化,更难准确捕捉
-
可排序表 :根据用户交互动态重排序的数据需要额外处理
-
无限滚动 :只有在用户向下滚动时才加载的内容需要自定义抓取器逻辑才能完全捕获
-
反机器人保护 :动态网站常部署验证码和 IP 封锁,以中断自动抓取
如何抓取动态网页?
使用动态抓取技术,比如使用 Selenium、 使用无头浏览器以及发起 AJAX 请求。此外,可以参考高级的 Python 网页抓取指南,学习更多技巧,比如模拟 AJAX 调用和处理无限滚动。
然而,需要注意的是,每个目标都面临独特的挑战,比如弹窗、下拉菜单、实时搜索建议、实时更新、可排序表格等。
最常见的挑战之一是连续滚动或无限滚动——这是一种允许用户在网页滚动时动态加载内容的技术。要从具有无限滚动的网站上抓取目标网址,就需要自定义你的抓取工具。
如何使用 Selenium 抓取动态网页
本节将介绍使用 Selenium 在 Python 中抓取动态站点的步骤。对于这次演示的抓取目标,我们采用带有一些关键词的谷歌搜索页面。
第一步:环境搭建
首先,确保你的系统安装了最新版本的 Python。你还需要使用以下命令安装 Selenium 库:
pip install selenium
然后,下载 Chrome 驱动 ,确保版本与你的 Google Chrome 版本一致。
第二步:代码的实际应用
首先创建一个新的 Python 文件,导入所需的库:
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from bs4 import BeautifulSoup
然后通过复制路径到驱动可执行文件,粘贴以下代码,使用 Selenium 设置 Chrome Webdriver:
# Set up the Chrome WebDriver
driver = webdriver.Chrome()
随后,进入谷歌搜索页面,输入你的搜索关键词:
# Navigate to Google Search
search_keyword = "adidas"
driver.get("https://www.google.com/search?q=" + search_keyword)
现在你可以在硒上模拟连续滚动。使用下面的脚本,你将多次滚动以获得更多结果,然后抓取结果:
Define the number of times to scroll
scroll_count = 5
# Simulate continuous scrolling using JavaScript
for _ in range(scroll_count):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2) # Wait for the new results to load
最后,使用 BeautifulSoap 解析并提取结果:
page_source = driver.page_source
# Parse the page source with BeautifulSoup
soup = BeautifulSoup(page_source, 'html.parser')
search_results = soup.find_all('div', class_='tF2Cxc')
for result in search_results:
title = result.h3.text
link = result.a['href']
print(f"Title: {title}")
print(f"Link: {link}")
print("\n")
按照以下规定运行最终代码,查看结果:
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from bs4 import BeautifulSoup
# Set up the Chrome WebDriver
driver = webdriver.Chrome()
# Navigate to Google Search
search_keyword = "adidas"
driver.get("https://www.google.com/search?q=" + search_keyword)
# Define the number of times to scroll
scroll_count = 5
# Simulate continuous scrolling using JavaScript
for _ in range(scroll_count):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2) # Wait for the new results to load (adjust as needed)
# Get the page source after scrolling
page_source = driver.page_source
# Parse the page source with BeautifulSoup
soup = BeautifulSoup(page_source, "html.parser")
# Extract and print search results
search_results = soup.find_all("div", class_="tF2Cxc")
for result in search_results:
title = result.h3.text
link = result.a["href"]
print(f"Title: {title}")
print(f"Link: {link}")
print("\n")
# Close the WebDriver
driver.quit()
输出应该大致如下:

这种网络抓取方法的一个问题是,谷歌可能会误以为你是恶意机器人,这通常会触发验证码。这意味着你需要将可靠的代理IP集成到脚本中,并不断轮换它们。
所以,如果你在寻找大规模提取数据的解决方案,也可以考虑商业解决方案,专门处理反机器人系统,如需要代理IP相关产品,可以联系余初云。
原创文章,作者:余初云,如若转载,请注明出处:https://blog.jidcy.com/jsjc/2221.html
