Python 3.8环境下requests.get加headers与Session仍报403 Forbidden如何解决
Python requests请求返回403 Forbidden的额外解决方案
已经尝试过配置User-Agent、Session对象、Referer字段仍返回403的场景,可以按以下顺序逐一尝试排查:
- 补全全部请求头字段
仅配置UA和Referer不足以模拟真实浏览器请求,大部分站点会校验Accept、Accept-Encoding、Accept-Language、sec-ch-ua系列等标准请求头,你可以直接复制浏览器访问目标图片时的全部请求头,完整填入headers字典,不要遗漏字段。 - 完成站点登录流程
你访问的资源属于站点内部的媒体资源,需要登录后持有有效身份凭证才能访问,当前代码仅配置了登录页作为Referer,没有实际执行登录操作拿到有效Cookie。需要先请求站点登录接口提交账号密码完成登录,Session会自动保存返回的身份Cookie,之后再请求图片资源即可通过校验。注意部分站点登录页会有CSRF Token之类的隐藏校验字段,需要先GET登录页提取对应字段再提交登录请求。 - 手动配置有效Cookie
如果不想通过代码执行登录,可以直接在浏览器登录站点后,复制该站点下的有效Cookie字符串,填入headers的Cookie字段中即可,注意Cookie存在有效期,过期后需要重新获取。 - 绕过请求指纹拦截
部分站点的反爬策略会识别requests库的TLS指纹特征,直接拦截requests发出的请求。这种情况可以更换为curl_cffi、httpx等支持自定义TLS指纹的请求库,模拟真实浏览器的指纹特征即可绕过拦截。 - 排查重定向校验逻辑
可以在get请求中添加allow_redirects=False参数,关闭自动重定向,查看返回的响应头和状态码,确认是否存在额外的跳转校验逻辑需要手动处理。
参考修改代码
import requests from bs4 import BeautifulSoup # 站点登录地址 login_url = 'https://smartsub.les.inf.puc-rio.br/login/' # 登录所需参数,替换为你自己的账号密码 login_payload = { 'username': '你的账号', 'password': '你的密码' } # 目标图片地址 target_url = 'https://smartsub.les.inf.puc-rio.br//media/imagens/5f667ec98b21262d4fc0a9dc5df4d0e4/8c6bbb5844e009eab139442e4024684d.jpg' session = requests.Session() # 先请求登录页,获取CSRF校验参数和基础Cookie login_page_resp = session.get(login_url) soup = BeautifulSoup(login_page_resp.text, 'lxml') # 提取登录页隐藏的csrfmiddlewaretoken参数,参数名根据站点实际字段调整 csrf_token = soup.find('input', {'name': 'csrfmiddlewaretoken'})['value'] login_payload['csrfmiddlewaretoken'] = csrf_token # 提交登录请求 session.post(login_url, data=login_payload) # 补全完整的浏览器请求头 full_headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.53', 'Referer': 'https://smartsub.les.inf.puc-rio.br/login/?next=/', 'Accept': 'image/avif,image/webp,image/apng,*/*;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Connection': 'keep-alive' } # 请求目标图片 img_resp = session.get(target_url, headers=full_headers) print(f"请求状态码:{img_resp.status_code}") # 保存图片到本地 if img_resp.status_code == 200: with open('target.jpg', 'wb') as f: f.write(img_resp.content)
内容的提问来源于stack exchange,提问作者Vitor Bento
相关产品推荐
相关产品推荐

