.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)
关键修改说明
- 添加
X-Requested-With头:明确告诉服务器这是AJAX异步请求,触发UpdatePanel的局部内容返回逻辑。 - 修正参数名格式:还原参数名里的
$符号,让requests自动处理URL编码,确保服务器能正确解析参数。 - 使用
requests.Session():自动维护会话中的cookie,避免两次请求的cookie不一致导致验证失败。 - 增加索引越界判断:异步返回的HTML结构可能和初始页面略有差异,加判断防止因字段缺失报错。
这样修改后,应该就能成功获取到纽约联邦储备银行的搜索结果了。
内容的提问来源于stack exchange,提问作者bobby_pine
相关产品推荐
相关产品推荐

