使用Python请求带authenticity_token的URL返回406错误如何解决
406错误与令牌问题说明
- 406 Not Acceptable错误的直接原因是请求头不完整:你当前仅配置了User-Agent字段,Goodreads站点会校验请求的
Accept、Accept-Language、Referer等多个请求头字段,缺少对应字段会直接被服务器拒绝响应。 - authenticity_token不是专门的反爬机制,是Ruby on Rails框架自带的CSRF(跨站请求伪造)防护参数,该参数和当前用户的会话Cookie强绑定,你从浏览器中复制的token仅对当时浏览器的会话有效,直接在Python脚本中使用没有对应Cookie,就算请求头完整也会请求失败。
修复方案
你需要调整请求流程,不要硬编码复制的URL和token,按以下步骤操作即可:
- 完善请求头配置,从浏览器开发者工具的对应请求中把
Accept、Accept-Language、Referer等全部请求头字段复制到你的脚本中,不要仅保留User-Agent - 先请求原书籍页面,保存请求返回的Cookie,同时从页面的meta标签中提取当前会话对应的CSRF token
- 用提取到的token构造评论分页请求参数,携带之前保存的Cookie发起请求
推荐使用requests库替换urllib,该库对会话、Cookie的处理更简便,示例代码如下:
import requests from bs4 import BeautifulSoup # 初始化会话对象,自动维护Cookie req_session = requests.Session() # 替换为你自己浏览器中对应请求的请求头内容 full_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Referer": "https://www.goodreads.com/book/show/385228.On_Liberty" } req_session.headers.update(full_headers) # 请求原页面获取CSRF token和会话Cookie origin_resp = req_session.get("https://www.goodreads.com/book/show/385228.On_Liberty") page_soup = BeautifulSoup(origin_resp.text, "html.parser") csrf_token = page_soup.find("meta", {"name": "csrf-token"})["content"] # 构造评论页请求参数 review_params = { "authenticity_token": csrf_token, "hide_last_page": "true", "language_code": "en", "page": 4 } # 发起评论页请求 review_resp = req_session.get( "https://www.goodreads.com/book/reviews/385228.On_Liberty", params=review_params ) print(review_resp.status_code) # 后续可从review_resp.text中提取所需评论信息
注意事项
- 控制请求频率,两次请求间隔至少1秒,避免触发站点频率限制被封IP
- 若后续出现403错误,可定期更换User-Agent字段的值
内容的提问来源于stack exchange,提问作者Shaharg
相关产品推荐
相关产品推荐

