Python + Chrome 爬虫:如何抓取 AJAX 动态加载数据?

Python + Chrome 爬虫:如何抓取 AJAX 动态加载数据?

在现代 Web 开发中,AJAX(Asynchronous JavaScript and XML) 技术被广泛应用于动态加载数据,使得网页能够在不刷新的情况下更新内容。然而,这也给传统爬虫带来了挑战——使用 requests + BeautifulSoup 只能获取初始 HTML,而无法捕获 AJAX 返回的动态数据。

解决方案:

Selenium + ChromeDriver:模拟浏览器行为,等待 AJAX 数据加载完成后再抓取。直接分析 AJAX 请求:通过 Chrome DevTools 捕获 API 接口,用 requests 直接请求数据(更高效)。本文将详细介绍 Python + Chrome 如何抓取 AJAX 动态数据,并提供两种方法的完整实现代码。

1. 理解 AJAX 动态加载1.1 AJAX 工作原理用户访问网页 → 浏览器加载初始 HTML。JavaScript 发起 AJAX 请求(通常是 fetch 或 XMLHttpRequest)。服务器返回 JSON/XML 数据 → 前端动态渲染到页面。1.2 传统爬虫的问题代码语言:javascript代码运行次数:0运行复制import requests

from bs4 import BeautifulSoup

response = requests.get("https://example.com")

soup = BeautifulSoup(response.text, "html.parser")

# 只能获取初始 HTML,无法得到 AJAX 数据!2. 方法 1:使用 Selenium + Chrome 模拟浏览器2.1 环境准备安装必要的库

2.2 示例:爬取动态加载的新闻列表假设目标网站(如新浪新闻)通过 AJAX 加载更多新闻。

代码语言:javascript代码运行次数:0运行复制from selenium import webdriver

from selenium.webdriver.chrome.service import Service

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.chrome.options import Options

from webdriver_manager.chrome import ChromeDriverManager

import time

# 设置代理信息

proxyHost = "www.16yun.cn"

proxyPort = "5445"

proxyUser = "16QMSOML"

proxyPass = "280651"

# 配置 Chrome 代理

chrome_options = Options()

chrome_options.add_argument(f"--proxy-server=http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}")

# 启动 Chrome

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)

driver.get("https://news.sina.com.cn/")

# 等待 AJAX 内容加载(假设新闻列表通过 AJAX 渲染)

try:

WebDriverWait(driver, 10).until(

EC.presence_of_element_located((By.CSS_SELECTOR, ".news-item"))

)

except:

print("超时,未找到新闻列表")

# 提取新闻标题和链接

news_items = driver.find_elements(By.CSS_SELECTOR, ".news-item")

for item in news_items:

title = item.find_element(By.CSS_SELECTOR, "a").text

link = item.find_element(By.CSS_SELECTOR, "a").get_attribute("href")

print(f"标题: {title}\n链接: {link}\n")

# 关闭浏览器

driver.quit()2.3 关键点说明WebDriverWait:显式等待 AJAX 数据渲染完成。EC.presence_of_element_located:检查目标元素是否已加载。find_elements + CSS/XPath:定位动态生成的内容。3. 方法 2:直接抓取 AJAX API 数据(更高效)3.1 分析 AJAX 请求打开 Chrome → F12(开发者工具) → Network(网络) 标签页。刷新页面,筛选 XHR/fetch 请求。找到返回目标数据的 API 接口(通常是 json 格式)。3.2 示例:爬取豆瓣电影 AJAX 数据豆瓣电影首页通过 AJAX 加载热门电影列表。

步骤 1:分析 API打开 https://movie.douban.com → F12 → Network → 筛选 XHR。发现 API:https://movie.douban.com/j/search_subjects?...步骤 2:用 Python 直接请求 API代码语言:javascript代码运行次数:0运行复制import requests

import json

# 豆瓣电影 AJAX API

url = "https://movie.douban.com/j/search_subjects?type=movie&tag=热门&sort=recommend&page_limit=20&page_start=0"

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)

data = response.json() # 直接解析 JSON

# 提取电影信息

for movie in data["subjects"]:

print(f"电影名: {movie['title']}")

print(f"评分: {movie['rate']}")

print(f"链接: {movie['url']}\n")3.3 优势与限制优势:速度快,无需加载完整页面。限制:需手动分析 API,部分接口可能有加密或鉴权。7. 总结方法

适用场景

优点

缺点

Selenium

复杂动态渲染页面

能模拟完整浏览器行为

速度慢,资源占用高

直接请求 API

结构化数据(如 JSON)

高效,速度快

需手动分析接口,可能受限

最佳实践建议优先分析 AJAX API:如果目标网站有清晰的接口,直接请求更高效。Selenium 备用:适用于无法直接获取 API 或需要交互的页面。遵守 Robots.txt:避免高频请求,防止被封禁。

相关文章

steam设置游戏显示帧数 steam显示FPS 方法教程
365dni是真的吃吗

steam设置游戏显示帧数 steam显示FPS 方法教程

07-02 阅读: 1341
WIN10系统如何关闭139 135 445端口
365dni是真的吃吗

WIN10系统如何关闭139 135 445端口

06-30 阅读: 1907
全球10大顶级运动鞋品牌!中美各3家,德国2家,意大利日本各1家
老人讲:“猫来穷,狗来富”,为啥会出现这个说法?有道理吗?
现在苞米价格多少钱一斤?
28365365bet官网

现在苞米价格多少钱一斤?

07-03 阅读: 1121
世界杯,我只是来凑个热闹
365dni是真的吃吗

世界杯,我只是来凑个热闹

07-03 阅读: 1236