Python爬虫100例中怎么处理Ajax动态加载与JSON数据解析

山间有风
山间有风
发布时间:2026-10-31| 8人浏览过
原创

详细讲解在Python网络爬虫实战中如何抓包分析Ajax异步加载接口、模拟发送HTTP请求以及高效安全地解析提取JSON数据。

处理网页中的Ajax动态加载,核心解决路径并不是直接使用资源消耗较大的自动化浏览器工具,而是通过浏览器开发者工具定位前端异步请求的真实数据接口,用Python直接请求该接口并解析返回的标准JSON数据。这种做法直接绕过了复杂的DOM结构渲染,大幅降低了网络带宽消耗和页面解析复杂度,是爬虫实战中处理动态内容最高效的基础手段。

一、理解动态加载:为什么在网页源码中搜不到内容

在传统的服务端渲染(SSR)页面中,浏览器请求某个URL后,服务器会直接将拼接好数据的完整HTML文档返回给客户端。爬虫只要使用 requests 请求初始URL,就能在 response.text 中通过XPath、CSS选择器或BeautifulSoup直接提取文字内容。

然而现代网站广泛使用单页面应用(SPA)或异步请求技术。浏览器加载初始HTML时,返回的页面主体中往往只有空白容器或基础骨架。真正的页面内容是浏览器在运行JavaScript脚本后,通过Ajax(XMLHttpRequest或Fetch API)向后台独立接口发起的异步请求获取的。后台返回的通常是结构化的JSON字符串,前端拿到数据后再动态挂载生成DOM节点。因此,直接查看网页右键“查看网页源代码”时,找不到屏幕上看到的数据文本。

Python爬虫100例中怎么处理Ajax动态加载与JSON数据解析
图1:服务端渲染与Ajax异步加载数据流及爬虫处理策略对比

二、在浏览器中抓取和逆向Ajax接口

解决动态加载的第一步是抓取到那个负责传输数据的网络接口。利用主流浏览器(如Chrome或Edge)内置的开发者工具即可完成此项任务,无需依赖外部抓包程序。

  1. 打开网络监控面板:在目标网页上按下 F12 或右键选择“检查”,切换至顶部的 Network(网络)选项卡。
  2. 筛选异步数据请求:在过滤器过滤条件中勾选 Fetch/XHR。这样可以过滤掉庞大的图片、CSS样式表及第三方脚本干扰。
  3. 触发数据刷新:清空当前网络记录后,在网页上执行产生新数据的动作,例如点击“下一页”、向下滚动鼠标触发懒加载,或者点击筛选栏。
  4. 核对响应内容:点击新出现的请求条目,在右侧切换到 Preview(预览)或 Response(响应)面板,查找是否包含目标文字或列表。
  5. 记录请求属性:在 Headers 面板中,记下 Request URL、Request Method(GET或POST)、Query String Parameters(或 Payload/表单数据),以及关键的请求头字段(如 User-Agent、Referer、Cookie 等)。
Python爬虫100例中怎么处理Ajax动态加载与JSON数据解析
图2:通过浏览器开发者工具准确定位真实 Ajax 接口的操作链路

三、使用 Python 发送请求模拟获取动态数据

获取到真实的接口地址与参数后,即可使用 Python 的 requests 库直接模拟浏览器发起网络调用。与抓取网页相比,请求接口时有两项关键注意点:

  • 规范的请求头:很多接口校验 User-Agent、Referer(防盗链)以及 X-Requested-With: XMLHttpRequest。缺少这些头信息可能会直接返回 403 权限错误或重定向。
  • 参数结构化传递:GET 请求应将查询参数组装为字典传给 params 参数;POST 请求则根据接口要求选择传入 data(表单形式)或 json(JSON Payload 形式)。

下面是一个标准的接口调用示例:

import requests

api_url = "https://example.com/api/articles"

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",
    "Referer": "https://example.com/articles",
    "X-Requested-With": "XMLHttpRequest",
    "Accept": "application/json, text/javascript, */*; q=0.01"
}

# 模拟分页参数与筛选标签
params = {
    "page": 1,
    "limit": 20,
    "category": "python"
}

try:
    response = requests.get(api_url, headers=headers, params=params, timeout=10)
    response.raise_for_status()
    # 直接获取解析后的 Python 字典
    json_data = response.json()
except requests.exceptions.RequestException as e:
    print(f"网络请求失败: {e}")
    json_data = None
except ValueError:
    print("响应内容不是合法的 JSON 格式")
    json_data = None

注意:直接调用 response.json() 时,底层会自动使用 json.loads() 处理响应字符串。若接口因反爬机制返回了 HTML 报错页(如 Cloudflare 拦截页),该调用会抛出 requests.exceptions.JSONDecodeError 或 ValueError,因此务必做好异常捕获。

四、JSON 数据解析与字段安全提取

服务器返回的 JSON 数据映射到 Python 中为基础的数据类型:JSON Object 对应 Python 的 dict,JSON Array 对应 Python 的 list,其余分别对应 str、int、float、bool 和 None。

在实际爬取过程中,接口返回的结构往往是多层深层嵌套的,例如常见的包裹结构 {"code": 200, "message": "success", "data": {"total": 120, "items": [...]}}。直接使用方括号索引(如 data["data"]["items"])非常脆弱,一旦某一页缺少对应键或返回 None,就会导致整个爬虫崩溃中断。

Python爬虫100例中怎么处理Ajax动态加载与JSON数据解析
图3:多层嵌套 JSON 数据的结构特征与防御性提取流程

解析实战完整代码范例

以下代码演示了从接口调用、分页循环、健壮性解析到结果清洗落地的完整过程:

import time
import requests

def fetch_page_items(page_num):
    url = "https://example.com/api/articles"
    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",
        "Referer": "https://example.com/articles"
    }
    params = {"page": page_num, "size": 20}
    
    try:
        resp = requests.get(url, headers=headers, params=params, timeout=8)
        if resp.status_code != 200:
            print(f"第 {page_num} 页请求状态码异常: {resp.status_code}")
            return []
        
        payload = resp.json()
    except Exception as err:
        print(f"获取或解析第 {page_num} 页失败: {err}")
        return []

    # 规范校验:确保外层返回正确
    if payload.get("code") != 200:
        print(f"业务响应码不匹配: {payload.get('message')}")
        return []

    data_block = payload.get("data")
    if not isinstance(data_block, dict):
        return []

    raw_items = data_block.get("items", [])
    parsed_results = []
    
    for item in raw_items:
        if not isinstance(item, dict):
            continue
        # 安全读取并赋予默认值
        article_info = {
            "id": item.get("id"),
            "title": str(item.get("title", "")).strip(),
            "view_count": int(item.get("view_count") or 0),
            "author": item.get("author", {}).get("name", "未知") if isinstance(item.get("author"), dict) else "未知"
        }
        parsed_results.append(article_info)

    return parsed_results

# 执行多页连续抓取
if __name__ == "__main__":
    all_articles = []
    for page in range(1, 4):
        print(f"正在爬取第 {page} 页...")
        records = fetch_page_items(page)
        if not records:
            print(f"第 {page} 页无数据,停止翻页")
            break
        all_articles.extend(records)
        time.sleep(1.5)  # 礼貌爬取,降低请求频率

    print(f"抓取完成,共提取 {len(all_articles)} 条记录。")

五、常见异常排查与应对建议

在处理 Ajax 和 JSON 数据时,通常会遇到以下几类特定问题,应当根据具体原因排查:

  • 返回 HTML 登录页或验证码页:接口设置了 Session、Cookie 验证或动态 Token。可以在 Headers 中带上浏览器当前有效的 Cookie,或排查请求头中的自定义 Header(如 X-Token、Authorization)。
  • 报错 json.decoder.JSONDecodeError:说明响应正文不是有效的 JSON。常见原因是请求被网站 WAF 拦截并返回了 403 页面,或者接口返回的是 JSONP 格式(类似 callback({...}))。若为 JSONP,需要用正则表达式剥离外层函数包裹,仅保留内部的 JSON 字符串后再进行 json.loads()。
  • 参数中带有动态加密签名(sign/token):若抓包发现 Query 或 Payload 中含有 32 位随机哈希或数字签名,说明前端 JS 在发起请求前对参数进行了混淆加密。此时可通过浏览器的全局搜索或 XHR 启动断点(XHR/fetch Breakpoints)定位加密函数。
  • Unicode 编码展示(如 \u4f60\u597d):在控制台打印时如果看到原始转义序列,是由于编码显示设置。在输出或保存文件时,设置 json.dumps(obj, ensure_ascii=False) 即可恢复正常中文字符。
Python爬虫100例中怎么处理Ajax动态加载与JSON数据解析
图4:Ajax 动态爬虫开发全流程质量与容错规范

总结

在 Python 爬虫实战中,面对 Ajax 动态加载内容,最行之有效的方法是逆向分析其背后的数据接口。只要在网络监控中找到负责返回业务数据的 XHR/Fetch 请求,即可绕过庞大复杂的 DOM 解析逻辑,直接利用 requests 获取结构化、规整的 JSON 数据。配合规范的请求头配置与字典的防御性取值策略,可以大幅提升爬取速度与程序的长期稳定性。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。