UA 检测作为最基础、最常见的反爬手段,识别的核心是**“找差异、验合规、判结果”**,以下分享一系列实战性极强的技巧,均来自爬虫落地过程中的真实经验总结,避开理论空谈,直接对接实操场景。
一、 前期准备:先搞定“有效UA”,避免从源头踩坑
-
浏览器F12精准提取合法UA(首选,最可靠) 这是获取有效UA的核心方法,避免手动编造或使用过时UA被拦截:
- 打开Chrome/Edge浏览器,访问目标站点(确保正常访问);
- 按
F12打开开发者工具,切换到「Network」面板,勾选「Preserve log」(保留日志); - 刷新页面,找到第一个
GET请求(通常是目标站点的文档请求,Type为「document」); - 下拉找到「Request Headers」,复制
User-Agent对应的完整字符串(从头到尾完整复制,避免遗漏字符); - 直接粘贴到Python请求头字典中,不做任何修改,这是通过UA检测的“黄金标准”。
-
避开requests库默认UA(新手必避坑) requests库在不手动设置UA时,会默认传递
python-requests/xx.xx.xx(xx为版本号),这类UA会被绝大多数开启UA检测的网站直接拦截,因此任何爬虫请求,都必须手动覆盖默认UA,不抱有任何侥幸心理。 -
UA格式快速验证技巧 合法浏览器UA都有固定结构(操作系统+渲染引擎+浏览器版本+兼容内核),若拿到的UA不包含这些要素,大概率无效:
- 必备要素:
Windows NT/ macOS(操作系统)、AppleWebKit(渲染引擎)、Chrome/Edge/Safari(浏览器); - 排除要素:包含
python、spider、crawler、bot等关键词的UA,几乎100%会被拦截。
- 必备要素:
二、 核心识别:三步对比法,精准判定是否存在UA检测
这是识别UA检测的“万能方法”,通过发送三种不同UA的请求,对比响应结果,即可快速得出结论,无任何技术门槛。
步骤1:发送“无UA”请求(仅传递空请求头或不传递请求头)
- 操作:Python中不设置
headers参数,直接发送requests.get(url); - 观察结果:记录响应状态码(
403/400/200)、响应内容长度、是否包含“非法访问”提示; - 核心意义:验证网站是否强制要求携带UA,无UA直接拦截是UA检测的最典型特征。
步骤2:发送“异常UA”请求(传递格式无效、乱写的UA)
- 操作:设置明显不符合浏览器格式的UA,如
headers={"User-Agent": "123456"}、headers={"User-Agent": "my-spider"}; - 观察结果:对比与“无UA”请求的结果是否一致(是否均返回
403、是否均无有效内容); - 核心意义:验证网站是否不仅要求“存在UA”,还要求“UA格式合规”,这是区分“弱UA检测”和“强UA检测”的关键。
步骤3:发送“正常浏览器UA”请求(传递步骤1提取的合法UA)
- 操作:设置完整的浏览器UA,如
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}; - 观察结果:记录是否返回
200、是否包含完整的目标页面数据; - 核心意义:通过与前两步结果对比,完成最终判定。
判定逻辑(直接套用)
- 若步骤1、步骤2均返回
403/400,步骤3返回200且数据完整 → 判定存在强UA检测(既验证UA存在,又验证格式合规); - 若步骤1返回
403,步骤2、步骤3均返回200且数据完整 → 判定存在弱UA检测(仅验证UA是否存在,不验证格式); - 若三步均返回
200且数据完整 → 判定未开启UA检测; - 补充:若三步均返回
200,但步骤1、2的响应内容是“访问受限”提示,步骤3是正常数据 → 仍判定存在UA检测(部分网站不返回错误状态码,仅返回错误内容)。
三、 细节优化:提升UA检测识别准确率的辅助技巧
-
响应内容优先于状态码(关键避坑) 很多网站为了隐藏反爬机制,不会返回
403/400等错误状态码,而是返回200,但响应内容是空白页面、“非法访问”提示页或跳转页面。因此,识别时不能只看状态码,必须解析响应内容的核心关键词(如“登录”、“禁止”、“非法”、“不支持”),这是提升准确率的核心。 -
关键词检索法,快速辅助判定 编写简单的关键词匹配逻辑,自动筛选响应内容中的反爬提示,避免人工逐一查看:
# 关键词检索辅助判定UA检测 import requests url = "https://www.example.com" good_headers = {"User-Agent": "合法浏览器UA"} bad_headers = {"User-Agent": "123456"} # 定义反爬提示关键词列表 anti_crawl_keywords = ["非法访问", "禁止", "不支持", "请使用浏览器", "Login", "Forbidden"] def check_ua_detection(headers): resp = requests.get(url, headers=headers, timeout=10) # 遍历关键词,判断是否包含反爬提示 for keyword in anti_crawl_keywords: if keyword in resp.text: return True, f"检测到反爬提示:{keyword}" return False, "未检测到反爬提示,数据正常" # 验证异常UA is_anti, msg = check_ua_detection(bad_headers) print(f"异常UA请求结果:{msg}") -
排除其他反爬干扰,避免误判 识别UA检测时,需先排除IP封禁、Cookie验证等其他反爬的干扰,避免将其他反爬误判为UA检测:
- 若更换IP(如本地WiFi→手机热点)后,前两步请求从
403变为200→ 大概率是IP封禁,而非UA检测; - 若携带有效Cookie后,前两步请求从
403变为200→ 大概率是Cookie验证,而非UA检测。
- 若更换IP(如本地WiFi→手机热点)后,前两步请求从
-
验证UA字段的大小写敏感性 部分严格的网站会验证请求头中
User-Agent字段的大小写,若写成user-agent、User-agent,可能会被拦截。因此,请求头中UA字段的键必须严格写为「User-Agent」(首字母大写,其余小写,中间连字符连接),避免因字段名错误导致误判。
四、 进阶技巧:识别隐藏的UA检测(针对高难度站点)
-
UA版本有效性验证 部分网站不仅验证UA格式,还会验证浏览器版本、操作系统版本,即使格式合规,若使用过旧的UA(如Chrome 50.0),也会被拦截。此时可通过更换不同版本的浏览器UA(如Chrome 119、Chrome 120)进行对比,若部分版本通过、部分版本被拦截,说明存在隐藏的UA版本检测。
-
完整请求头伪装,避免UA“孤立” 部分网站会验证请求头的完整性,仅伪装UA,而缺少
Referer、Accept、Accept-Encoding等字段,也会被拦截,导致误判为UA检测失效。此时需将浏览器中的完整请求头(除Cookie外)全部复制到Python请求中,再进行验证,避免因请求头不完整导致的识别误差。 -
批量UA池验证,快速筛选有效UA 对于不确定UA有效性的场景,可搭建简易UA池,通过循环批量发送请求,筛选出能通过UA检测的有效UA,同时验证网站的UA检测严格程度:
# 简易UA池批量验证 import requests url = "https://www.example.com" # 构建UA池(包含不同浏览器、不同版本的合法UA) ua_pool = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/120.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ] for ua in ua_pool: headers = {"User-Agent": ua} try: resp = requests.get(url, headers=headers, timeout=10) if "核心内容关键词" in resp.text: print(f"UA有效:{ua[:50]}...") else: print(f"UA无效:{ua[:50]}...") except Exception as e: print(f"UA验证失败:{ua[:50]}... 报错:{e}")