Scrapy本地运行正常但生产环境失效,请求遭403拒绝求助
首先明确:从你提供的生产环境统计数据来看,你的请求确实被目标网站以403 Forbidden拒绝了——数据里downloader/response_status_count/403: 2和httperror/response_ignored_status_count/403: 1的记录,说明所有发送的请求都没有拿到正常的200响应,自然无法抓取到数据。
本地运行正常但生产环境失败,核心原因是目标网站的反爬机制识别出了生产环境请求的"异常性",你提到的USER_AGENT确实是可能的点,但还有其他更常见的因素,下面逐一分析并给出解决步骤:
1. 先修复你的USER_AGENT配置
你当前设置的USER_AGENT末尾是Safari/,缺少版本号,属于不完整的UA格式,很容易被反爬规则识别为异常请求。正常的UA应该是类似:
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.36 Safari/535.7'
先把UA补全,再重新部署测试。
2. 生产环境IP被目标网站拦截
云服务器、VPS的IP段很多是爬虫常用IP池,目标网站可能直接拉黑了这类IP段,而你的本地IP是普通民用IP,不在拦截列表里。
排查方法:在生产服务器上用curl命令直接请求目标页面,比如:
curl -I "https://你的目标页面URL"
如果返回403,基本可以确定IP被拦截。
解决方法:
- 尝试更换生产服务器的IP(如果是云服务商,一般可以申请更换)
- 配置Scrapy使用代理IP池,分散请求来源
- 联系目标网站管理员申请白名单(如果是合法爬取)
3. 请求头缺失关键字段
本地浏览器发起请求时,会自动携带很多额外的请求头(比如Accept、Accept-Language、Referer等),而你可能只设置了USER_AGENT,导致请求头过于"干净",被反爬识别。
解决方法:在Scrapy的settings.py中补充完整的请求头:
DEFAULT_REQUEST_HEADERS = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Referer': 'https://目标网站的首页URL/', 'Connection': 'keep-alive' }
4. 爬取速率触发反爬限制
本地运行时,可能因为测试需求爬取量小、速率慢,而生产环境Scrapyd运行时,默认的并发请求数或下载延迟可能过高,触发了目标网站的频率限制。
解决方法:在settings.py中降低爬取速率:
# 设置下载延迟,单位秒 DOWNLOAD_DELAY = 3 # 降低并发请求数 CONCURRENT_REQUESTS = 2 # 禁用自动限速扩展(如果开启了的话) AUTOTHROTTLE_ENABLED = False
5. Cookies或会话状态差异
本地浏览器可能保存了目标网站的Cookies(比如登录状态、会话标识),而生产环境的爬虫是全新的无状态请求,没有这些Cookies,导致被拦截。
解决方法:
- 确保Scrapy的Cookies中间件已启用(默认是启用的,检查
DOWNLOADER_MIDDLEWARES中scrapy.downloadermiddlewares.cookies.CookiesMiddleware是否存在且优先级正确) - 如果目标网站需要登录,在爬虫中实现登录逻辑,获取有效Cookies后再进行爬取
- 可以手动从本地浏览器导出Cookies,临时添加到爬虫的请求头中测试是否能解决问题
6. 用Scrapy Shell做对比测试
在生产环境和本地分别启动Scrapy Shell,请求同一个目标页面,对比返回的响应状态和内容,定位差异:
# 生产环境执行 scrapy shell "https://你的目标页面URL" # 然后输入 response.status 查看状态码 # 输入 response.headers 查看响应头
通过对比两者的请求头、响应结果,能更快定位到具体的异常点。
内容的提问来源于stack exchange,提问作者Chiefir

