在爬虫开发中,很多网页的核心内容是通过AJAX技术动态加载的,页面初始返回的HTML中并不包含这些动态内容,直接使用BeautifulSoup解析静态HTML无法获取到目标数据。因此需要采用合适的策略来应对这类场景,以下是几种常见的实践方案。

策略一:分析网络请求直接获取AJAX接口数据
大部分AJAX加载的内容本质是通过异步请求调用后端接口获取数据,然后由前端JS渲染到页面上。我们可以直接找到这个接口,模拟请求获取原始数据,这种方式效率最高。
操作步骤
- 打开浏览器开发者工具,切换到Network面板,勾选XHR选项
- 刷新页面触发AJAX请求,找到返回目标数据的接口
- 查看接口的请求方式、参数、请求头,模拟发送请求
- 对返回的JSON或HTML数据进行解析
代码示例
假设某页面的动态列表数据来自接口https://api.ipipp.com/list,请求需要携带page参数:
import requests
from bs4 import BeautifulSoup
# 模拟请求头,避免被反爬
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
# 请求AJAX接口
api_url = "https://api.ipipp.com/list"
params = {"page": 1}
response = requests.get(api_url, headers=headers, params=params)
# 如果接口返回JSON数据
if response.headers.get("Content-Type") == "application/json":
data = response.json()
print("接口返回的JSON数据:", data)
# 如果接口返回HTML片段
else:
soup = BeautifulSoup(response.text, "html.parser")
items = soup.select(".list-item")
for item in items:
print(item.get_text(strip=True))
策略二:结合Selenium模拟浏览器加载动态内容
如果AJAX接口的请求参数带有加密签名,或者接口校验逻辑复杂难以模拟,可以使用Selenium启动真实浏览器,执行页面JS让动态内容加载完成后再抓取。
适用场景
- AJAX接口有复杂的反爬校验,无法直接模拟请求
- 页面动态内容加载依赖复杂的JS执行逻辑
- 需要模拟用户交互(如点击、滚动)触发内容加载
代码示例
需要先安装selenium和对应浏览器的驱动,以下以Chrome为例:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import time
# 初始化Chrome浏览器
options = webdriver.ChromeOptions()
# 可选:无头模式,不弹出浏览器窗口
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
# 访问目标页面
driver.get("https://www.ipipp.com/dynamic-page")
# 等待动态内容加载完成,最多等待10秒
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, "dynamic-content")))
# 获取加载完成后的页面源码
page_source = driver.page_source
# 用BeautifulSoup解析
soup = BeautifulSoup(page_source, "html.parser")
content_list = soup.select(".dynamic-content")
for content in content_list:
print(content.get_text(strip=True))
# 关闭浏览器
driver.quit()
策略三:使用requests-html渲染页面JS
requests-html是一个集成了requests和pyppeteer的库,可以在不启动完整浏览器的情况下渲染页面JS,适合轻量级的动态内容抓取场景。
代码示例
from requests_html import HTMLSession
from bs4 import BeautifulSoup
# 创建会话
session = HTMLSession()
# 访问页面
response = session.get("https://www.ipipp.com/dynamic-page")
# 渲染页面JS,等待动态内容加载
response.html.render(timeout=10)
# 用BeautifulSoup解析渲染后的页面
soup = BeautifulSoup(response.html.html, "html.parser")
dynamic_items = soup.select(".ajax-loaded-item")
for item in dynamic_items:
print(item.get_text(strip=True))
# 关闭会话
session.close()
不同策略的对比
以下是三种策略的适用场景和优缺点对比:
| 策略 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 直接请求AJAX接口 | 效率高、资源占用少 | 需要分析接口,复杂接口难以模拟 | 接口逻辑简单、无复杂校验的场景 |
| Selenium模拟浏览器 | 能应对几乎所有动态加载场景 | 资源占用高、运行速度慢 | 接口反爬严格、需要模拟交互的场景 |
| requests-html渲染 | 比Selenium轻量,使用简单 | 渲染能力弱于真实浏览器,部分复杂JS不支持 | 轻量级动态内容抓取场景 |
注意事项
- 抓取数据前先查看目标网站的robots.txt,遵守爬虫规则
- 控制请求频率,避免对目标服务器造成过大压力
- 如果目标页面使用了<iframe>嵌套动态内容,需要先获取<iframe>的src地址再进一步处理
- 部分网站的动态内容可能需要滚动页面才会加载,使用Selenium时可以模拟滚动操作
# Selenium模拟页面滚动示例
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.ipipp.com/infinite-scroll-page")
# 滚动到页面底部,触发动态加载
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2) # 等待内容加载
# 后续解析逻辑...
driver.quit()
BeautifulSoupAJAX动态加载requestsselenium数据抓取修改时间:2026-07-01 00:21:43