使用Python Requests模拟POST请求爬取表格数据返回空JSON
问题排查与修复方案
你的请求返回空JSON,大概率是因为缺少AJAX请求标识头、CSRF令牌校验,再加上payload参数可能不匹配,以下是具体解决步骤:
1. 必须补充的请求头字段
浏览器发起AJAX请求时会自动携带X-Requested-With: XMLHttpRequest,很多后端会以此判断请求是否为合法的前端异步请求,你的代码里缺失这个头,导致后端拒绝返回有效数据。
2. 提取并携带CSRF令牌
该网站启用了CSRF防护机制,需要先访问初始页面获取CSRF令牌,再在POST请求中携带。令牌通常存放在页面的meta标签里,或者会话cookie中。
3. 修正payload参数
浏览器实际发送的language参数是pl(波兰语),你使用的en可能没有对应数据,这也是返回空JSON的潜在原因。
修复后的完整代码
import requests from bs4 import BeautifulSoup base_url = 'https://rss.knf.gov.pl/rss_pub/' session = requests.session() # 先访问首页获取CSRF令牌和会话cookie headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', } home_response = session.get(base_url, headers=headers) soup = BeautifulSoup(home_response.text, 'html.parser') # 提取页面中的CSRF令牌(根据实际meta标签属性调整) csrf_token = soup.find('meta', attrs={'name': '_csrf'})['content'] # 更新请求头,添加AJAX标识和CSRF令牌 headers.update({ 'Referer': base_url, 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': csrf_token, 'Content-Type': 'application/json' }) # 调整payload的language为网站默认的波兰语 payload = { "cmd":"get", "language":"pl", "search":[], "limit":10, "offset":0, "method":"Default", "sort":[{"field":"HOLDER_FULL_NAME","direction":"asc"}], "searchLogic":"AND", "searchValue":"" } # 发送POST请求 response = session.post(f"{base_url}JSON", json=payload, headers=headers) print(response.status_code) print(response.json())
额外提示
- 如果找不到页面meta标签里的CSRF令牌,可以查看浏览器的cookie,有些网站会将令牌存放在
XSRF-TOKEN类的cookie中,直接从session.cookies里提取即可。 - 尽量复制浏览器请求头里的所有字段(自动处理的Cookie除外),比如
Accept、Accept-Language等,进一步降低请求被拦截的概率。
内容的提问来源于stack exchange,提问作者Luke Bradley
相关产品推荐
相关产品推荐

