使用Python爬取Just Eat站点如何避免被反爬机制识别为机器人
Just Eat站点爬取拦截问题修复方案
你遇到的拦截页是Imperva Incapsula反机器人服务的拦截标记,核心触发原因和请求头配置、请求行为、特征识别都有关,具体修复措施如下:
现有配置问题排查
- 多余请求头配置:你在GET请求中携带了
Content-Type: application/json头,该头仅用于POST提交JSON数据的场景,浏览器正常访问页面不会携带该参数,属于异常标记点 - 无会话复用:每次请求为独立连接,未携带站点下发的Cookie,被反爬系统判定为非浏览器访问
- 无请求间隔:高频批量请求直接触发频率限制,是你前5次请求正常后续被拦截的核心原因
- TLS指纹特征不匹配:requests库默认的TLS握手指纹和真实浏览器差异极大,Incapsula可直接通过该特征识别机器人,即便请求头完全和浏览器一致也会被拦截
具体修复步骤
1. 修正请求头
删除请求头中的Content-Type: application/json配置项。
2. 启用会话复用+请求间隔+异常重试
使用requests.Session()创建全局会话,自动管理站点Cookie,和浏览器的Cookie逻辑保持一致,增加随机请求间隔和拦截重试逻辑,示例代码:
import requests import time import random import re import json session = requests.Session() # 首次先请求站点首页,获取初始Cookie base_headers = { # 保留原有的其他头,删掉Content-Type即可 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'sec-ch-ua': "\"Google Chrome\";v=\"93\", \" Not;A Brand\";v=\"99\", \"Chromium\";v=\"93\"", 'sec-ch-ua-mobile': '?0', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-User': '?1', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36', } session.get("https://www.just-eat.co.uk", headers=base_headers) for resto in restos: host = resto['menu_url'].replace('https://', '').split('/')[0] # 每次请求只更新Host头即可 headers = base_headers.copy() headers['Host'] = host response = session.get(url=resto['menu_url'], headers=headers) # 增加判断逻辑,确认返回内容正常再解析,异常则重试 if 'window.__INITIAL_STATE__' not in response.text: for retry in range(3): time.sleep(random.uniform(2,5)) response = session.get(url=resto['menu_url'], headers=headers) if 'window.__INITIAL_STATE__' in response.text: break data = re.search('(?<=window.__INITIAL_STATE__=)(.*)(?=<)', response.text).group(1) data = json.loads(data) # 每次请求后加随机延迟,避免触发频率限制 time.sleep(random.uniform(1,3))
3. 修复TLS指纹特征
如果修改后还是被拦截,替换请求库为curl_cffi,该库可以模拟真实浏览器的TLS握手指纹,完全匹配Chrome 93的特征,示例代码:
from curl_cffi import requests # 发请求时指定impersonate参数为对应Chrome版本 response = requests.get(url=resto['menu_url'], headers=headers, impersonate="chrome93")
4. VPN出口排查
如果以上配置都调整后仍然出现周期性拦截,可切换VPN的出口节点,部分被大量用户使用的VPN出口IP会被Incapsula标记为高风险IP,会优先触发拦截逻辑。
内容的提问来源于stack exchange,提问作者Tenserflu
相关产品推荐
相关产品推荐

