You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:47:37