
在爬取动态加载内容的网站时,直接使用beautifulsoup解析初始html页面常会遇到数据缺失的问题,因为实际数据通常通过javascript异步加载。本教程将指导您如何通过浏览器开发者工具识别并直接调用网站的后端api接口,从而高效、稳定地获取json格式的结构化数据,并利用pandas库进行便捷处理,避免解析复杂html结构的困扰。
现代Web应用程序,特别是如加密货币交易平台这类数据实时更新的网站,普遍采用前后端分离的架构。这意味着当您访问一个URL时,服务器首先返回一个包含基本结构和JavaScript代码的HTML页面。实际的数据(例如商品价格、交易列表)并非直接嵌入在初始HTML中,而是由浏览器执行JavaScript代码后,向后端API发送异步请求(通常是XHR或Fetch请求)获取JSON或XML格式的数据,再由JavaScript将这些数据渲染到页面上。
如果尝试使用requests库获取页面内容,然后用BeautifulSoup解析,您可能会发现得到的HTML中缺少核心数据,或者只包含加载动画、样式定义等,这是因为requests只获取了初始的HTML响应,并未执行JavaScript代码来触发后续的数据加载。
要解决动态网站数据抓取问题,关键在于绕过前端渲染过程,直接与后端API交互。这通常通过以下步骤完成:
通过分析Binance P2P页面的网络请求,可以发现它通过一个POST请求向https://p2p.binance.com/bapi/c2c/v2/friendly/c2c/adv/search发送JSON格式的请求体,并返回包含交易数据的JSON响应。
立即学习“Python免费学习笔记(深入)”;
一旦识别出API接口及其请求参数,我们就可以使用Python的requests库来模拟这些请求。
我们需要requests库来发送HTTP请求,以及pandas库来方便地处理JSON响应数据。
import requests import pandas as pd
根据开发者工具中观察到的API请求,我们需要构建相应的请求头和请求体。
s = requests.Session() # 使用Session可以保持会话状态和重用连接
headers = {
'content-type': 'application/json',
'accept-language': 'en-US,en;q=0.9',
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}
# 请求体,根据实际API需求构建JSON字符串
payload = '{"proMerchantAds":false,"page":1,"rows":10,"payTypes":[],"countries":[],"publisherType":null,"asset":"USDT","fiat":"RUB","tradeType":"BUY"}'
url = 'https://p2p.binance.com/bapi/c2c/v2/friendly/c2c/adv/search'使用requests.post()方法发送请求,并将JSON响应解析为Python字典,然后利用pandas.json_normalize()将其转换为DataFrame。
s.headers.update(headers) # 更新Session的默认请求头
r = s.post(url, data=payload) # 发送POST请求,data参数接受字符串或字典
# 检查请求是否成功
if r.status_code == 200:
# 将JSON响应数据展平为Pandas DataFrame
df = pd.json_normalize(r.json()['data'])
print(df.head()) # 打印DataFrame的前几行
else:
print(f"请求失败,状态码: {r.status_code}")
print(r.text)示例代码整合:
import requests
import pandas as pd
# 初始化一个请求会话,可以自动处理cookies和连接池
s = requests.Session()
# 模拟浏览器请求头
headers = {
'content-type': 'application/json',
'accept-language': 'en-US,en;q=0.9',
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}
# API接口URL
url = 'https://p2p.binance.com/bapi/c2c/v2/friendly/c2c/adv/search'
# 请求体(Payload),以JSON字符串形式提供
# 示例:查询USDT/RUB的购买广告,第一页,每页10行
payload = '{"proMerchantAds":false,"page":1,"rows":10,"payTypes":[],"countries":[],"publisherType":null,"asset":"USDT","fiat":"RUB","tradeType":"BUY"}'
# 更新会话的请求头
s.headers.update(headers)
try:
# 发送POST请求
response = s.post(url, data=payload)
response.raise_for_status() # 检查HTTP请求是否成功 (2xx状态码)
# 解析JSON响应
json_data = response.json()
# 检查'data'键是否存在且不为空
if 'data' in json_data and json_data['data']:
# 使用pandas.json_normalize将嵌套的JSON数据展平为DataFrame
df = pd.json_normalize(json_data['data'])
print("成功获取数据并转换为DataFrame:")
print(df.head()) # 打印DataFrame的前5行
print(f"\nDataFrame的形状: {df.shape}")
print(f"DataFrame的列名: {df.columns.tolist()}")
else:
print("API响应中没有找到'data'键或数据为空。")
print(json_data) # 打印完整的JSON响应以供调试
except requests.exceptions.RequestException as e:
print(f"请求过程中发生错误: {e}")
except ValueError as e:
print(f"解析JSON响应时发生错误: {e}")
except KeyError as e:
print(f"JSON响应结构不符合预期,缺少键: {e}")
通过直接调用后端API来获取数据,是爬取动态加载内容的网站的更有效和稳定的方法。它避免了复杂的HTML解析,直接获取结构化的JSON数据,极大地简化了数据处理流程。掌握这一技巧,能让您在面对现代Web应用时,更高效地获取所需信息。
以上就是Python爬虫进阶:高效获取动态网站数据的API抓取策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号