使用requests抓取cri.nbb.be站点表格数据遇重定向如何解决
问题原因分析
- 你访问的站点基于JSF(Java Server Faces)框架开发,
execution、javax.faces.ViewState都是会话级动态参数,每次新访问都会生成新值,你硬编码的e1s1已经失效,服务器校验不通过就会返回重定向。 - Payload里带
j_id前缀的表单字段名是页面渲染时动态生成的,不是固定值,硬抄之前的字段名也会导致请求参数不匹配。
调整方案
你需要先请求页面提取所有动态参数,再发起搜索请求,具体调整如下:
依赖安装
需要先安装BeautifulSoup用于解析页面参数:pip install beautifulsoup4 lxml
调整后代码
import requests from bs4 import BeautifulSoup base_url = 'https://cri.nbb.be/bc9/web/catalog' company_num = '0466425389' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36', 'Faces-Request': 'partial/ajax', 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/xml, text/xml, */*; q=0.01', } with requests.Session() as s: # 第一次请求获取动态参数 res = s.get(base_url, headers=headers) # 提取当前页面的execution参数 exec_param = res.url.split('execution=')[-1] search_url = f"{base_url}?execution={exec_param}" # 解析页面提取ViewState和表单字段名 soup = BeautifulSoup(res.text, 'lxml') view_state = soup.find('input', {'name': 'javax.faces.ViewState'})['value'] # 匹配Company number对应的输入框name company_input = soup.find('input', {'aria-label': 'Company number'}) if not company_input: # 适配字段匹配规则 company_label = soup.find('label', string=lambda x: x and 'Company number' in x) input_id = company_label['for'] company_input = soup.find('input', {'id': input_id}) company_input_name = company_input['name'] # 构建动态payload payload = { 'javax.faces.partial.ajax': 'true', 'javax.faces.source': 'page_searchForm:actions:0:button', 'javax.faces.partial.execute': 'page_searchForm', 'javax.faces.partial.render': 'page_searchForm page_listForm pageMessagesId', 'page_searchForm:actions:0:button': 'page_searchForm:actions:0:button', 'page_searchForm': 'page_searchForm', company_input_name: company_num, 'page_searchForm:j_id3:generated_name_4_component': '', 'page_searchForm:j_id3:generated_address_zipCode_6_component': '', 'page_searchForm:j_id3_activeIndex': '0', 'page_searchForm:j_id2_stateholder': 'panel_param_visible;', 'page_searchForm:j_idt133_stateholder': 'panel_param_visible;', 'javax.faces.ViewState': view_state } # 发起搜索请求 res = s.post(search_url, data=payload, headers=headers) print(res.text) # 后续可解析返回的XML内容提取表格数据
额外说明
- 如果仍返回重定向,可在请求头中补充
Referer字段,值设置为当前的search_url即可。 - 搜索返回结果为XML格式,表格内容会封装在XML的对应标签中,可通过正则或XML解析库提取后再解析表格结构。
内容的提问来源于stack exchange,提问作者MITHU
相关产品推荐
相关产品推荐

