使用requests模块的脚本返回428状态码,如何修复?
问题描述
我编写了一个Python脚本,向维兹航空官网发送符合字段要求的POST HTTP请求,预期返回200状态码表示请求成功,但运行脚本时第二个POST请求始终返回428状态码。相关脚本代码如下:
import requests url = 'https://wizzair.com/en-gb' link = 'https://be.wizzair.com/24.9.0/Api/search/search' payload = {"isFlightChange":False,"flightList":[{"departureStation":"TIA","arrivalStation":"VIE","departureDate":"2024-09-17"},{"departureStation":"VIE","arrivalStation":"TIA","departureDate":"2024-10-20"}],"adultCount":1,"childCount":0,"infantCount":0,"wdc":True} headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'wizzair.com', 'Referer': 'https://wizzair.com/en-gb', } with requests.Session() as session: session.headers.update(headers) r = session.get(url) print(r.status_code) session.headers['Accept'] = 'application/json, text/plain, */*' session.headers['Referer'] = 'https://wizzair.com/en-gb/booking/select-flight/TIA/VIE/2024-09-17/2024-10-20/1/0/0/null' session.headers['Host'] = 'be.wizzair.com' session.headers['Origin'] = 'https://wizzair.com' resp = session.post(link,json=payload) print(resp.status_code)
解决思路与方案
428状态码代表「Precondition Required」,说明服务器要求请求满足特定前置条件才能处理。针对维兹航空的API,核心需要补充以下验证逻辑:
- 提取并携带CSRF Token:维兹航空的接口会验证CSRF Token,该Token会在首次访问官网时通过Cookie返回。需要从首次GET请求的Cookie中提取
XSRF-TOKEN,并在POST请求的请求头中添加X-XSRF-TOKEN字段。 - 调整请求头细节:简化
Accept-Encoding避免使用服务器不兼容的编码格式,确保请求头与浏览器真实请求对齐。 - 保留Session状态一致性:利用Session自动管理Cookie,确保首次GET请求获取的所有验证Cookie都能在POST请求中正常发送。
修改后的脚本示例:
import requests url = 'https://wizzair.com/en-gb' link = 'https://be.wizzair.com/24.9.0/Api/search/search' payload = { "isFlightChange": False, "flightList": [ {"departureStation": "TIA", "arrivalStation": "VIE", "departureDate": "2024-09-17"}, {"departureStation": "VIE", "arrivalStation": "TIA", "departureDate": "2024-10-20"} ], "adultCount": 1, "childCount": 0, "infantCount": 0, "wdc": True } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'wizzair.com', 'Referer': 'https://wizzair.com/en-gb', } with requests.Session() as session: session.headers.update(headers) # 首次GET请求获取验证所需的Cookie r = session.get(url) print(f"GET请求状态码: {r.status_code}") # 提取并添加CSRF Token到请求头 xsrf_token = session.cookies.get('XSRF-TOKEN') if xsrf_token: session.headers['X-XSRF-TOKEN'] = xsrf_token # 更新POST请求专属头信息 session.headers.update({ 'Accept': 'application/json, text/plain, */*', 'Referer': 'https://wizzair.com/en-gb/booking/select-flight/TIA/VIE/2024-09-17/2024-10-20/1/0/0/null', 'Host': 'be.wizzair.com', 'Origin': 'https://wizzair.com' }) # 发送POST请求 resp = session.post(link, json=payload) print(f"POST请求状态码: {resp.status_code}") # 可选:打印响应内容,用于排查后续问题 # print(resp.text)
额外提示
- 若上述方法失效,建议通过浏览器开发者工具(F12)监控真实请求的完整请求头、Cookie参数,确保脚本请求与浏览器请求完全一致。
- 避免高频次发送请求,防止触发反爬机制导致IP被封禁。
内容的提问来源于stack exchange,提问作者robots.txt
相关产品推荐
相关产品推荐

