如何用Beautiful Soup抓取需点击加载更多的网页全量数据
动态加载赛马销售数据的全量抓取方案
问题说明
抓取网页https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04时,通过BeautifulSoup解析初始HTML仅能获取到50条数据,但页面实际包含1065条(点击加载栏可加载剩余内容),通过正则提取script标签数据也只能拿到初始的50条,需要获取全量数据。
原因分析
该页面采用动态加载机制:初始仅渲染前50条数据,剩余数据在用户点击加载栏时,通过异步请求后端API获取,全量数据并未直接包含在初始返回的HTML中。
解决方案
1. 定位后端数据接口
打开浏览器开发者工具(按F12),切换到「Network」标签:
- 点击页面的加载更多按钮,观察XHR类型的请求
- 找到返回批量数据的API接口(通常URL包含
results、data等关键词) - 记录接口的请求参数(如
page分页页码、pageSize每页条数)
以该页面为例,抓包后可找到核心API接口:https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04/results
请求参数包含page(当前页)和pageSize(每页条数,默认50)。
2. 编写代码批量请求数据
通过循环请求所有分页,合并得到全量数据:
import requests import json import time # 实际抓包得到的API接口地址 api_url = "https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04/results" total_records = 1065 page_size = 50 total_pages = (total_records + page_size - 1) // page_size # 计算总页数 all_records = [] for page_num in range(1, total_pages + 1): # 构造请求参数 params = { "page": page_num, "pageSize": page_size # 若抓包发现其他必填参数(如sort、order),需在此添加 } # 添加请求头模拟浏览器访问,避免被反爬 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Referer": "https://www.racingpost.com/bloodstock/sales/catalogues/5/2023-12-04" } try: response = requests.get(api_url, params=params, headers=headers) response.raise_for_status() # 抛出HTTP请求错误 data = response.json() # 假设返回数据中,items字段存放单页数据,需根据实际接口结构调整 page_records = data.get("items", []) all_records.extend(page_records) print(f"已获取第{page_num}页,累计{len(all_records)}条数据") time.sleep(1) # 添加延时,避免请求过于频繁 except Exception as e: print(f"获取第{page_num}页失败:{str(e)}") # 保存全量数据到JSON文件 with open("racing_post_sales_full_data.json", "w", encoding="utf-8") as f: json.dump(all_records, f, ensure_ascii=False, indent=4) print(f"全量数据抓取完成,共{len(all_records)}条,已保存至文件")
注意事项
- 需严格按照抓包得到的接口参数和请求头构造请求,部分网站会校验
User-Agent、Referer等字段 - 若遇到反爬限制,可增加延时、使用代理IP,或模拟登录(若页面需要登录)
- 接口返回的数据结构需以实际抓包结果为准,调整代码中提取数据的逻辑
内容的提问来源于stack exchange,提问作者Sam Kirwan
相关产品推荐
相关产品推荐

