0

0

Python爬取动态网页数据:绕过JavaScript渲染直接调用API的策略

碧海醫心

碧海醫心

发布时间:2025-11-18 12:47:02

|

593人浏览过

|

来源于php中文网

原创

python爬取动态网页数据:绕过javascript渲染直接调用api的策略

在处理由JavaScript动态加载内容的现代网页时,传统的BeautifulSoup解析HTML可能无法获取到完整数据。本教程将介绍一种更高效、稳定的方法:通过分析浏览器网络请求,识别并直接调用网站后端API,从而获取结构化的JSON数据,并使用Pandas进行便捷处理,有效解决动态内容抓取难题。

动态网页爬取挑战与API调用策略

许多现代网站,特别是金融交易平台或社交媒体,其核心数据并非直接嵌入在初始加载的HTML中。相反,这些数据通常通过JavaScript在浏览器端异步请求(AJAX)获取,然后动态渲染到页面上。当尝试使用requests库获取页面HTML并结合BeautifulSoup进行解析时,往往只会得到一个包含加载动画、样式定义(如

解决这一问题的有效策略是绕过前端渲染过程,直接与网站后端提供数据的API进行交互。通过这种方式,我们可以直接获取到结构化的JSON或XML数据,避免了复杂的HTML解析,且通常更稳定、效率更高。

识别目标API请求

要实现API调用,首先需要识别出网页加载数据时所调用的具体API。这通常通过浏览器的开发者工具完成:

立即学习Java免费学习笔记(深入)”;

Voicepods
Voicepods

Voicepods是一个在线文本转语音平台,允许用户在30秒内将任何书面文本转换为音频文件。

下载
  1. 打开开发者工具: 在Chrome、Firefox等浏览器中,右键点击页面并选择“检查”或按F12。
  2. 切换到“网络”(Network)选项卡: 刷新页面,观察网络请求列表。
  3. 筛选XHR/Fetch请求: 大多数动态数据请求会显示为XHR (XMLHttpRequest) 或 Fetch 类型。
  4. 定位数据请求: 仔细查看请求的URL、请求方法(GET/POST)、请求头(Headers)和请求载荷(Payload)。通常,数据请求的响应类型会是JSON。
    • 以Binance P2P为例,通过观察发现,当页面加载价格数据时,会向https://p2p.binance.com/bapi/c2c/v2/friendly/c2c/adv/search发送一个POST请求。
    • 这个请求包含了content-type、accept-language、User-Agent等请求头,以及一个JSON格式的请求体,其中定义了查询条件,如asset (USDT)、fiat (RUB)、tradeType (BUY) 等。

构建API请求与数据解析

一旦识别出目标API及其请求参数,就可以使用Python的requests库来模拟这个请求。对于JSON响应,pandas库的json_normalize函数是处理嵌套JSON数据的强大工具。

示例代码

以下是使用Python模拟Binance P2P API请求并解析数据的示例:

import requests
import pandas as pd
from fake_useragent import UserAgent # 用于生成随机User-Agent,模拟真实浏览器行为

# 1. 初始化Requests会话和请求头
# 使用requests.Session()可以保持会话,并在所有请求中重用相同的TCP连接和请求头,提高效率
s = requests.Session()

# 模拟浏览器请求头,避免被网站识别为爬虫
# User-Agent是关键,可以从浏览器开发者工具中复制,或使用fake_useragent库生成
ua = UserAgent(verify_ssl=False)
headers = {
    'content-type': 'application/json', # 明确告诉服务器发送的是JSON数据
    'accept-language': 'en-US,en;q=0.9',
    'User-Agent': ua.random # 使用随机User-Agent
}

# 2. 定义API请求的URL和载荷(Payload)
# 载荷是POST请求体中的JSON数据,同样从浏览器开发者工具中复制
payload = {
    "proMerchantAds": False,
    "page": 1,
    "rows": 10,
    "payTypes": [],
    "countries": [],
    "publisherType": None,
    "asset": "USDT",
    "fiat": "RUB",
    "tradeType": "BUY"
}

# 目标API的URL
url = 'https://p2p.binance.com/bapi/c2c/v2/friendly/c2c/adv/search'

# 3. 发送POST请求
# 更新会话的请求头
s.headers.update(headers)
# 发送POST请求,data参数需要是JSON字符串,requests会自动处理json=payload
# 或者使用json=payload,requests会自动将字典序列化为JSON字符串并设置Content-Type
r = s.post(url, json=payload) # 使用json=payload更简洁

# 4. 处理API响应
# 检查请求是否成功
if r.status_code == 200:
    # 解析JSON响应数据
    json_data = r.json()

    # 检查'data'字段是否存在且不为空
    if 'data' in json_data and json_data['data']:
        # 使用pandas.json_normalize将嵌套的JSON数据展平为DataFrame
        # 'data'字段通常包含列表形式的记录
        df = pd.json_normalize(json_data['data'])
        print(df.head()) # 打印DataFrame的前几行

        # 进一步提取所需数据,例如价格和交易方法
        # 假设我们需要提取价格和所有交易方法
        # price_data = df[['adv.price', 'advertiser.nickName', 'adv.tradeMethods']]
        # print("\n提取的价格和交易方法数据:")
        # print(price_data.head())

    else:
        print("API响应中没有找到'data'字段或'data'字段为空。")
        print(json_data) # 打印完整JSON响应以供调试
else:
    print(f"请求失败,状态码:{r.status_code}")
    print(f"响应内容:{r.text}")

代码说明

  • requests.Session(): 创建一个会话对象,用于在多个请求之间保持参数(如headers)和底层TCP连接,提高效率。
  • headers: 包含User-Agent、content-type等HTTP头信息。User-Agent是模拟浏览器行为的关键,content-type: application/json则告知服务器请求体是JSON格式。
  • payload: 这是一个Python字典,它会被requests库自动序列化为JSON字符串,并作为POST请求的请求体发送。其内容与在浏览器开发者工具中看到的请求载荷一致。
  • s.post(url, json=payload): 发送POST请求。json参数会自动将Python字典转换为JSON格式的请求体,并设置正确的Content-Type头。
  • r.json(): 将API响应体解析为Python字典。
  • pd.json_normalize(r.json()['data']): 这是处理嵌套JSON的关键。它能够将复杂的JSON结构(特别是包含列表和字典嵌套的)展平为一个Pandas DataFrame,方便后续的数据分析和处理。例如,原始JSON中adv和advertiser下的字段会被展平为adv.price、advertiser.nickName等列名。

注意事项与最佳实践

  1. 动态载荷: 有些网站的API请求载荷或请求头可能包含动态生成的值(如时间戳、签名、CSRF token)。在这种情况下,需要进一步分析JavaScript代码或使用Selenium等工具模拟浏览器行为来获取这些动态值。
  2. 频率限制与反爬机制: 频繁的API请求可能触发网站的反爬机制,导致IP被封禁。建议:
    • 设置合理的请求间隔(time.sleep())。
    • 使用代理IP池。
    • 轮换User-Agent。
  3. 错误处理: 始终检查HTTP响应状态码(r.status_code)以确保请求成功,并对可能出现的异常(如网络错误、JSON解析失败)进行处理。
  4. 数据字段变化: 网站API接口可能会更新,导致字段名或结构发生变化。定期检查API文档或重新分析网络请求是必要的。
  5. 隐私与合规性: 在爬取数据时,务必遵守网站的服务条款和相关法律法规,避免非法获取或滥用数据。

总结

对于数据由JavaScript动态加载的现代网页,直接通过requests和BeautifulSoup解析初始HTML往往无法奏效。通过利用浏览器开发者工具分析网络请求,识别并直接调用网站后端API,可以高效、稳定地获取到结构化的JSON数据。结合Pandas的json_normalize功能,可以轻松将这些数据转换为易于处理的DataFrame格式,为后续的数据分析奠定基础。这种方法不仅解决了动态网页的爬取难题,也通常比模拟完整浏览器渲染(如使用Selenium)更加高效和轻量。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

746

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

634

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

758

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1260

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

705

2023.08.11

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

97

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.1万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号