BeautifulSoup循环爬取societe.com遇Cookie反爬拦截问题
问题根因
societe.com 部署的是 Datadome 反爬体系,你遇到的虚假信息页是反爬系统标记请求为爬虫后返回的蜜罐内容,并非单一Cookie校验导致。少量请求能正常返回,是因为初始访问时临时分配的Cookie尚未被标记异常,批量请求触发以下任意一条规则就会被拦截:
- 单IP/单Cookie请求频率超过真人访问阈值,站点对普通访客的容忍度约为单分钟6-8次请求
- 请求端TLS指纹、请求头排序、HTTP协议特征和真实浏览器不匹配,
requests库的默认指纹早已被反爬规则收录 - Cookie未随访问行为动态更新,仅使用首次访问拿到的固定Cookie批量请求,跟踪字段校验不通过
- 请求路径无规律,直接顺序访问企业详情页,没有模拟真人站内跳转的行为特征
可落地的稳定爬取方案
1. 替换请求底层,绕过指纹检测
直接弃用默认requests库做核心请求,两个方案选其一即可:
- 优先选用
curl_cffi库,API和requests几乎完全兼容,可一键模拟最新版Chrome/Edge的TLS指纹、请求头特征,改造成本极低,初始化示例:
from curl_cffi import requests as crequests # 模拟Chrome 124版本指纹 session = crequests.Session(impersonate="chrome124")
- 若坚持使用
requests,需搭配requests-toolbelt调整请求头默认排序,配合pyopenssl修改TLS握手特征,改造成本高,漏特征就会被拦截,不推荐。
2. 正确处理Cookie生命周期
不要用固定Cookie跑全量任务,按以下规则维护会话:
- 每个新会话启动后,先访问站点首页,等待所有Set-Cookie字段完整落地,包括
__cf_bm、datadome、_pk_id开头的核心校验Cookie,不要跳过首页直接请求详情页 - 每爬3-5个企业详情页,随机访问1个站内列表页、分类页或公共说明页,模拟真人浏览跳转路径,同时自动更新会话Cookie里的跟踪字段
- 单个会话连续使用不超过20分钟,到点直接重置会话,重新走首页访问流程拿新Cookie,避免被长期标记。
3. 行为与频率伪装
- 请求间隔设置为8-25秒随机值,禁止用固定间隔,间隔期可随机发起1-2次站内静态资源(CSS、logo图片)请求,完全模拟浏览器加载页面的行为
- 不要按待爬URL列表顺序请求,每次随机抽取URL爬取,避免连续访问同地区、同行业的企业详情页触发行为模型识别
- 请求头补全真实浏览器的全量字段,包括
Accept、Accept-Language、Sec-Ch-Ua、Sec-Fetch-*系列字段,Referer字段设置为上一个访问的站内页面地址,不要留空或固定为首页。
4. 蜜罐识别与重试机制
每次拿到响应不要直接解析,先判断是否为虚假蜜罐页:
- 蜜罐页通用特征:企业名称字段长度异常、经营状态字段出现无意义乱码、DOM中存在隐藏的captcha/access denied相关节点、响应体长度比正常详情页短30%以上
- 一旦识别到蜜罐响应,立刻终止当前会话,切换住宅代理IP、重置Cookie、等待60-120秒后再重试,不要持续用当前会话发请求,避免IP段被全站封禁
- 代理优先选优质住宅代理,不要用数据中心代理,Datadome对数据中心IP段的识别率接近100%,单IP每小时请求量控制在20-30次即可。
5. 高稳定性备选方案
如果上述HTTP请求方案拦截率仍达不到预期,可换用playwright无头浏览器方案,自带真实浏览器指纹,只需要关闭自动化标识、加入随机滚动、鼠标移动的行为模拟,稳定性远高于纯HTTP请求,缺点是爬取速度较慢,适合对数据准确率要求高、量级在十万级以内的爬取任务,初始化示例:
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=True) context = browser.new_context( user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", viewport={"width":1920, "height":1080} ) # 隐藏webdriver自动化标识 context.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") page = context.new_page()
避坑提示
- 不要尝试破解Datadome的验证码接口,逆向成本极高,靠伪装正常用户行为从源头避免触发验证码是性价比最高的方案
- 爬取过程遵守站点robots规则,控制请求频率,避免给站点服务器造成额外压力
- 数据存入DataFrame前先做字段合法性校验,不符合规则的异常响应直接丢弃,避免蜜罐假数据污染结果集
内容的提问来源于stack exchange,提问作者mat47
相关产品推荐
相关产品推荐

