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

.aspx页面POST请求无结果:爬取纽约联邦储备银行数据失败

解决纽约联邦储备银行H2A搜索页面POST请求无结果的问题

我之前爬过不少ASP.NET驱动的政府网站,这类页面的异步POST请求经常在细节上卡壳,你遇到的问题应该是几个关键参数或请求头没处理到位。咱们来拆解一下问题并修正代码:

问题分析

你的代码已经抓取了__VIEWSTATE这类ASP.NET必备的隐藏字段,但还有几个容易忽略的点:

  • 缺少AJAX请求标识头:ASP.NET的UpdatePanel异步请求需要X-Requested-With: XMLHttpRequest头,服务器才会返回局部更新的内容,否则可能直接忽略你的请求。
  • 表单参数编码错误:你把字段名里的$转成了%24,但requests.post会自动对参数名进行URL编码,手动转义反而会导致服务器识别不到参数(比如ctl00%24bodyMaster%24districtDropDownList会被当成完整的参数名,而不是正确的ctl00$bodyMaster$districtDropDownList)。
  • Session保持不严谨:用requests.get和requests.post分开处理,不如用requests.Session()来自动维护会话cookie,避免cookie丢失或不一致导致的验证失败。

修正后的代码

import requests
from bs4 import BeautifulSoup

# 初始化会话,自动维护cookie一致性
session = requests.Session()
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
    # 添加AJAX请求标识,让服务器识别是异步更新请求
    'X-Requested-With': 'XMLHttpRequest'
}

print('Scraping the Latest H2A Release...')
url = 'https://www.federalreserve.gov/apps/h2a/h2asearch.aspx'

# 第一步:获取初始页面的隐藏验证字段
r1 = session.get(url, headers=headers)
soup1 = BeautifulSoup(r1.text, 'html.parser')

# 提取ASP.NET必备的隐藏字段值
viewstate = soup1.find("input", {"type": "hidden", "name": "__VIEWSTATE"})['value']
eventvalidation = soup1.find("input", {"type": "hidden", "name": "__EVENTVALIDATION"})['value']
stategenerator = soup1.find("input", {"type": "hidden", "name": "__VIEWSTATEGENERATOR"})['value']

# 修正表单参数:用$代替手动转义的%24,让requests自动处理编码
item_request_body = {
    "__ASYNCPOST": "true",
    "__EVENTARGUMENT": "",
    "__EVENTTARGET": "",
    "__EVENTVALIDATION": eventvalidation,
    "__VIEWSTATE": viewstate,
    "__VIEWSTATEGENERATOR": stategenerator,
    "ctl00$bodyMaster$applicantTextBox": "",
    "ctl00$bodyMaster$districtDropDownList": "2",  # 2对应纽约联邦储备银行
    "ctl00$bodyMaster$ScriptManager1": "ctl00$bodyMaster$mainUpdatePanel|ctl00$bodyMaster$searchButton",
    "ctl00$bodyMaster$searchButton": "Search",
    "ctl00$bodyMaster$sectionDropDownBox": "ALL",
    "ctl00$bodyMaster$targetTextBox": ""
}

# 第二步:发送POST请求,复用会话cookie
r2 = session.post(url, data=item_request_body, headers=headers)
soup = BeautifulSoup(r2.text, 'html.parser')

mylist5 = []
# 异步返回的是局部HTML,增加索引判断避免报错
for tr in soup.find_all('tr')[2:]:
    tds = tr.find_all('td')
    if len(tds) >= 5:
        output5 = ("Applicant: %s, Activity: %s, Law: %s, Reserve Bank: %s, End of Comment Period: %s \r\n" 
                   % (tds[0].text.strip(), tds[1].text.strip(), tds[2].text.strip(), tds[3].text.strip(), tds[4].text.strip()))
        mylist5.append(output5)

print(mylist5)

关键修改说明

  1. 添加X-Requested-With头:明确告诉服务器这是AJAX异步请求,触发UpdatePanel的局部内容返回逻辑。
  2. 修正参数名格式:还原参数名里的$符号,让requests自动处理URL编码,确保服务器能正确解析参数。
  3. 使用requests.Session():自动维护会话中的cookie,避免两次请求的cookie不一致导致验证失败。
  4. 增加索引越界判断:异步返回的HTML结构可能和初始页面略有差异,加判断防止因字段缺失报错。

这样修改后,应该就能成功获取到纽约联邦储备银行的搜索结果了。

内容的提问来源于stack exchange,提问作者bobby_pine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:28:49