You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda运行Python爬虫无法绕过Cloudflare反爬咨询

问题核心原因

你遇到的403拦截是IP风险+环境指纹异常双重判定的结果,和爬取逻辑本身没有关系:

  • AWS Lambda的默认公网出口IP属于公开的云厂商数据中心IP段,这类IP在Cloudflare的风控库中默认属于高风险标记段,访问有反爬配置的站点时会触发最高等级的校验
  • Python原生请求库(urllib/requests)的TLS握手指纹、HTTP协议特征和真实浏览器存在明显差异,哪怕修改User-Agent也会被直接识别为机器人请求
  • Lambda运行环境无常规桌面系统的浏览器特征,即使搭配xvfb运行Selenium无头浏览器,也会因为navigator.webdriver标记、环境特征缺失被识别,同时叠加数据中心IP的高风险属性,必然触发reCAPTCHA验证。
可行落地方案

按落地成本从低到高排序:

  • 请求层直接接入住宅代理:这是改动最小的方案,不需要调整现有Lambda架构,直接在请求中配置住宅代理转发流量,避开AWS数据中心IP段。注意不要选用数据中心类代理,这类代理IP同样在Cloudflare高风险库中,没有绕过效果。
  • VPC出口统一转发代理:如果爬虫请求量较大,可以给Lambda配置VPC网络,通过VPC内的NAT实例统一将公网出口流量转发到住宅代理池,不用在每个请求里单独配置代理参数,方便统一管理。
  • 更换运行环境:如果不想采购代理服务,可以将爬虫逻辑从Lambda迁移到住宅网络环境下的设备运行(比如本地闲置主机、树莓派搭配定时任务),天然使用住宅IP出口,只要控制请求频率、匹配真实浏览器请求头,基本不会触发拦截。
  • 更换支持住宅出口的Serverless平台:如果必须使用Serverless架构,可选择支持固定住宅IP出口的Serverless服务,从平台层面解决出口IP的风险问题,不用自行搭建代理链路。
之前尝试的方案无效的原因
  • 仅添加请求头、修改User-Agent只能通过最基础的校验,Cloudflare当前的反爬规则会校验TLS指纹、HTTP/2帧顺序、请求头排列顺序等底层特征,Python原生请求库的这些特征和真实浏览器差异极大,无法绕过检测。
  • Lambda环境下运行cloudscraper、Selenium+pyvirtualdisplay的方案,没有解决最核心的出口IP高风险问题,只要请求来源是标记过的数据中心IP,不管上层怎么模拟浏览器行为,都会直接触发人机验证。
修正后的参考代码

以下是添加了住宅代理配置、补全常规请求头的可运行版本:

import json
import urllib.request

def lambda_handler(event, context):
    url = 'https://disboard.org/servers/tag/python/15'
    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,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.5",
        "Referer": "https://disboard.org/",
        "Upgrade-Insecure-Requests": "1"
    }
    # 替换为你自己的住宅代理地址
    proxy_handler = urllib.request.ProxyHandler({
        "http": "http://你的代理账号:密码@代理地址:端口",
        "https": "http://你的代理账号:密码@代理地址:端口"
    })
    opener = urllib.request.build_opener(proxy_handler)
    req = urllib.request.Request(url, headers=headers)
    resp = opener.open(req, timeout=15)
    respData = resp.read()
    return {
        "statusCode": resp.status,
        "body": respData.decode("utf-8")
    }

注意:爬取站点内容请遵守目标站点的robots协议及相关法律法规,控制请求频率,避免对站点正常运行造成影响。

内容的提问来源于stack exchange,提问作者adaorardour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:15:49