如何修改HTMLSession爬虫代码解决NoneType错误,获取MD-BL-13站点数据
问题解决:修复爬虫代码中的"NoneType object has no attribute html"错误
错误原因分析
你遇到的错误是因为table = r.html.find('table.Grid', first=True)返回了None,说明POST请求后没有找到目标表格。主要问题有几个:
- 会话范围错误:原代码中
with HTMLSession() as s:的缩进不正确,POST请求不在会话块内,导致会话失效,请求无法正确携带必要的会话信息 - 隐藏参数缺失/参数名错误:ASP.NET页面需要的
__VIEWSTATE参数名被写成了_VIEWSTATE(少一个下划线),而且还缺少__VIEWSTATEGENERATOR、__EVENTVALIDATION这类必要的隐藏参数 - 未验证请求是否成功:没有检查POST请求的响应状态,可能请求本身就失败了
修改后的代码
import requests from requests_html import HTMLSession import pandas as pd # 把所有请求逻辑放到会话块内,保持会话持续 with HTMLSession() as s: # 第一步:获取初始页面,提取所有必要的隐藏参数 r = s.get('https://www.cocorahs.org/ViewData/StationPrecipSummary.aspx') r.raise_for_status() # 检查请求是否成功 # 提取ASP.NET所需的隐藏参数 viewstate = r.html.find('input[name=__VIEWSTATE]', first=True).attrs.get('value') viewstate_generator = r.html.find('input[name=__VIEWSTATEGENERATOR]', first=True).attrs.get('value') event_validation = r.html.find('input[name=__EVENTVALIDATION]', first=True).attrs.get('value') # 构造请求参数,修正参数名并补充缺失的隐藏参数 payload = { '__EVENTTARGET': '', '__VIEWSTATE': viewstate, '__VIEWSTATEGENERATOR': viewstate_generator, '__EVENTVALIDATION': event_validation, 'obsSwitcher:ddlObsUnits': 'usunits', 'tbStation1': 'MD-BL-13', 'ucDateRangeFilter:dcStartDate': '8/1/2019', 'ucDateRangeFilter_dcStartDate_p': '2019-8-1-0-0-0-0', 'ucDateRangeFilter:dcEndDate': '8/10/2019', 'ucDateRangeFilter_dcEndDate_p': '2019-8-10-0-0-0-0', 'btnSubmit': 'Get Summary' } # 第二步:发送POST请求获取数据页面 r = s.post('https://www.cocorahs.org/ViewData/StationPrecipSummary.aspx', data=payload) r.raise_for_status() # 查找目标表格,增加判断避免None错误 table = r.html.find('table.Grid', first=True) if not table: print("未找到目标表格,请检查参数或页面结构是否变化") else: # 读取表格并提取需要的列 df = pd.read_html(table.html, header=0)[0] # 提取Date和Precip In列 result_df = df[['Date', 'Precip In']] print(result_df)
关键修改点说明
- 缩进修正:将所有请求操作放到
with HTMLSession() as s:块内,确保会话上下文持续有效 - 参数修正:把
_VIEWSTATE改为__VIEWSTATE,并补充了__VIEWSTATEGENERATOR和__EVENTVALIDATION参数,这些是ASP.NET表单提交必须的验证参数 - 异常处理:增加
r.raise_for_status()检查请求是否成功,避免在请求失败时继续执行后续代码;增加表格存在性判断,提前处理找不到表格的情况 - 数据提取:最后提取出你需要的
Date和Precip In两列,直接得到目标数据
内容的提问来源于stack exchange,提问作者new_coder
相关产品推荐
相关产品推荐

