动态网站POST爬取异常:返回初始页面且JSESSIONID变更求助
问题解决思路及修正代码
核心问题分析
- Session与手动Cookie冲突:
requests.Session会自动维护会话Cookie,手动在headers里硬写Cookie字段会干扰Session的自动管理,导致服务器返回新的JSESSIONID。 - 手动设置Content-Length错误:该字段应由requests根据实际payload自动计算,固定值可能与实际请求体长度不匹配,导致服务器无法正确解析请求。
- 请求头参数拼写错误:
X-Requested-With字段拼写为XMLHttpReques(少了末尾的t),服务器可能以此判断是否为合法AJAX请求,导致拒绝返回正确结果。 - 固定t:formdata无效:这个字段是服务器生成的表单序列化/加密数据,和当前会话、表单状态绑定,直接复用旧值会导致服务器识别为无效请求。
修正后的代码
import requests from bs4 import BeautifulSoup # 正确的POST接口地址 POST_URL = "https://lekovi.zdravstvo.gov.mk/drugsregister.searchform" BASE_URL = "https://lekovi.zdravstvo.gov.mk/drugsregister/overview" session = requests.Session() # 先访问初始页面,让Session自动获取并维护JSESSIONID session.get(BASE_URL) headers = { "Accept": "text/javascript, text/html, application/xml, text/xml, */*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-MK,en-US;q=0.9,en-GB;q=0.8,en;q=0.7,mk;q=0.6", "Connection": "keep-alive", "Content-type": "application/x-www-form-urlencoded; charset=UTF-8", "Host": "lekovi.zdravstvo.gov.mk", "Origin": "https://lekovi.zdravstvo.gov.mk", "Referer": BASE_URL, "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "Sec-GPC": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36", "X-Prototype-Version": "1.7", "X-Requested-With": "XMLHttpRequest", # 修正拼写错误 } # 从初始页面中提取当前有效的t:formdata值 response = session.get(BASE_URL) soup = BeautifulSoup(response.text, "html.parser") formdata = soup.find("input", {"name": "t:formdata"}).get("value") payload = { "t:ac": "overview", "t:submit": "submit_3", # 调整为单个值,匹配浏览器实际提交的参数 "t:formdata": formdata, "filterByApprovalCarrier": "", "manufacturerName": "", "nameNumberOrCode": "paracetamol", "genericNameOrAtc": "", "filterByModeOfIssuance": "", "t:zoneid": "gridZone" # 去掉末尾多余的逗号 } # 发送POST请求,Session自动处理Cookie d = session.post(POST_URL, headers=headers, data=payload) print(d.cookies.get("JSESSIONID")) # 打印响应前500字符,确认是否返回结果页 print(d.text[:500])
额外说明
- 若
t:formdata是加密字段,单纯解析HTML获取可能不够,需要查看网站的JS代码,找到生成该字段的逻辑并模拟实现。 - 务必保证请求流程和浏览器完全一致:先访问初始页面加载必要的会话状态和表单参数,再提交搜索请求。
内容的提问来源于stack exchange,提问作者Nikola
相关产品推荐
相关产品推荐

