如何用Beautiful Soup分页爬取asc.gov网站数据至DataFrame
解决方案:逐页爬取并合并数据到DataFrame
你的代码目前仅获取了第一页数据,要完成34万+条结果的全量爬取,需要处理分页逻辑,同时注意维持会话状态、模拟浏览器请求以避免被反爬。以下是改进后的完整方案:
核心问题分析
- 原代码未处理分页,仅抓取第一页数据
- 未使用会话维持状态,后续分页请求可能无法正常返回有效内容
- 缺少请求头模拟,容易触发网站反爬机制
改进后的代码
import requests from bs4 import BeautifulSoup import pandas as pd from time import sleep # 初始化会话,维持Cookie状态 session = requests.Session() 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', 'Accept-Language': 'en-US,en;q=0.9' } base_url = 'https://asc.gov/appraiser' # 第一步:获取初始页面,提取Apply按钮的参数 response = session.get(base_url, headers=headers) soup = BeautifulSoup(response.content, 'html.parser') apply_button = soup.find('input', {'name': 'btnApply'}) if not apply_button: raise ValueError("未找到Apply按钮,请检查页面结构是否变化") # 构建Apply请求参数 apply_params = {'uid': apply_button['value']} apply_response = session.get(base_url, params=apply_params, headers=headers) apply_soup = BeautifulSoup(apply_response.content, 'html.parser') # 获取分页信息:总条数、每页条数、总页数 total_count = int(apply_soup.find('span', {'id': 'lblTotalCount'}).text.replace(',', '')) page_size = int(apply_soup.find('span', {'id': 'lblPageSize'}).text) total_pages = (total_count + page_size - 1) // page_size # 向上取整计算总页数 # 初始化空DataFrame final_df = pd.DataFrame() # 循环遍历每一页 for page in range(1, total_pages + 1): print(f"正在爬取第 {page}/{total_pages} 页...") # 构建分页请求参数:在Apply参数基础上添加pageIndex page_params = { 'uid': apply_button['value'], 'pageIndex': page } # 请求当前页 page_response = session.get(base_url, params=page_params, headers=headers) page_soup = BeautifulSoup(page_response.content, 'html.parser') # 提取表格数据 results_table = page_soup.find('table', {'class': 'gridTable'}) if not results_table: print(f"第 {page} 页未找到表格,跳过") continue page_df = pd.read_html(str(results_table))[0] # 合并到最终DataFrame final_df = pd.concat([final_df, page_df], ignore_index=True) # 添加延迟,避免请求过于频繁被封 sleep(1) # 保存结果到本地(可选) final_df.to_csv('appraiser_data.csv', index=False) print(f"爬取完成,共获取 {len(final_df)} 条数据")
关键说明
- 会话维持:使用
requests.Session()保存Cookie,确保点击Apply后的分页请求处于同一会话,避免权限验证问题 - 分页参数:通过页面的
pageIndex参数控制页码,从1开始遍历到总页数结束 - 反爬处理:添加
User-Agent模拟浏览器请求,每页请求后加1秒延迟,降低被拦截风险 - 分页计算:通过页面显示的总条数和每页条数,计算出总页数,确保覆盖所有数据
- 容错处理:加入按钮、表格存在性检查,避免因页面结构变化导致程序崩溃
注意事项
- 如果网站的分页参数不是
pageIndex,可以通过浏览器开发者工具(F12)查看分页链接的参数,替换代码中的对应字段 - 若爬取过程中出现请求失败,可添加重试机制(比如使用
tenacity库) - 全量爬取耗时较长,请确保网络稳定,也可根据需要调整延迟时间
内容的提问来源于stack exchange,提问作者AKS
相关产品推荐
相关产品推荐

