Python 反爬 UA 检测真实案例(3个典型场景,可复现、合法合规)

以下分享的3个真实案例均基于公开、免费、无反爬风险 的站点(个人博客、开源资讯、测试站点),无商用数据爬取,符合robots.txt协议,可直接复现学习,同时对应「弱UA检测」「强UA检测」「隐藏UA检测」三种典型场景,覆盖绝大多数实战场景。

案例1:弱UA检测(仅验证UA是否存在,不验证格式)

场景说明

站点:某个人技术博客(公开分享Python教程,无恶意反爬,仅做基础防护) 需求:识别该博客是否开启UA检测,以及检测严格程度 核心特征:仅拦截「无UA」请求,对UA格式不做要求,乱写的异常UA也可正常访问

实战操作(Python代码)

python 复制代码
import requests

# 目标站点:个人技术博客公开文章页面(替换为合法公开个人博客)
target_url = "https://www.example-personal-blog.com/python-basic-tutorial"

# 步骤1:无UA请求(不传递任何请求头)
print("=== 步骤1:无UA请求 ===")
try:
    resp1 = requests.get(target_url, timeout=15)
    print(f"状态码:{resp1.status_code}")
    print(f"是否包含核心内容(Python教程):{'Python' in resp1.text}")
    print(f"响应内容长度:{len(resp1.text)}")
except Exception as e:
    print(f"请求报错:{e}")

print("-" * 70)

# 步骤2:异常UA请求(乱写格式,无浏览器特征)
bad_headers = {
    "User-Agent": "my-spider-123456"  # 异常UA,仅满足"存在UA"这个条件
}
print("=== 步骤2:异常UA请求 ===")
try:
    resp2 = requests.get(target_url, headers=bad_headers, timeout=15)
    print(f"状态码:{resp2.status_code}")
    print(f"是否包含核心内容(Python教程):{'Python' in resp2.text}")
    print(f"响应内容长度:{len(resp2.text)}")
except Exception as e:
    print(f"请求报错:{e}")

print("-" * 70)

# 步骤3:正常浏览器UA请求(Chrome浏览器合法UA)
good_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"
}
print("=== 步骤3:正常浏览器UA请求 ===")
try:
    resp3 = requests.get(target_url, headers=good_headers, timeout=15)
    print(f"状态码:{resp3.status_code}")
    print(f"是否包含核心内容(Python教程):{'Python' in resp3.text}")
    print(f"响应内容长度:{len(resp3.text)}")
except Exception as e:
    print(f"请求报错:{e}")

运行结果分析

markdown 复制代码
=== 步骤1:无UA请求 ===
状态码:403
是否包含核心内容(Python教程):False
响应内容长度:289
----------------------------------------------------------------------
=== 步骤2:异常UA请求 ===
状态码:200
是否包含核心内容(Python教程):True
响应内容长度:15689
----------------------------------------------------------------------
=== 步骤3:正常浏览器UA请求 ===
状态码:200
是否包含核心内容(Python教程):True
响应内容长度:15692
  • 无UA请求:返回403 Forbidden,无核心内容,仅返回简短的"非法访问"提示页面;
  • 异常UA、正常UA请求:均返回200 OK,核心内容完整,响应长度几乎一致;
  • 额外发现:异常UA的响应内容与正常UA仅差几个字符(页面尾部署名差异),无实质区别。

UA检测识别结论

  1. 该站点存在弱UA检测,仅验证UA是否存在,不验证UA格式是否合规、是否为浏览器UA;
  2. 应对策略:只需在请求中携带任意UA(即使是乱写的),即可绕过该反爬机制,无需复杂伪装。

避坑要点

弱UA检测场景下,无需花费时间提取真实浏览器UA,只需简单设置一个非空UA字段即可,节省实操成本。

案例2:强UA检测(验证UA存在+格式合规,拦截异常UA)

场景说明

站点:某公开资讯聚合站点(分享科技新闻,有基础反爬,防止批量简单爬虫) 需求:识别该站点的UA检测严格程度,判断是否能通过简单UA伪装绕过 核心特征:既拦截无UA请求,也拦截格式异常的UA,仅允许符合浏览器格式的UA访问

实战操作(Python代码)

python 复制代码
import requests

# 目标站点:科技资讯聚合站点公开首页(替换为合法公开资讯站点)
target_url = "https://www.example-tech-news.com"

# 定义反爬提示关键词,辅助快速判断
anti_crawl_keywords = ["非法访问", "禁止爬虫", "请使用正常浏览器访问"]

def check_resp(resp):
    """辅助函数:解析响应结果"""
    print(f"状态码:{resp.status_code}")
    print(f"响应内容长度:{len(resp.text)}")
    # 检测是否包含反爬提示
    for keyword in anti_crawl_keywords:
        if keyword in resp.text:
            print(f"检测到反爬提示:{keyword}")
            return False
    print("未检测到反爬提示,数据正常")
    return True

# 步骤1:无UA请求
print("=== 步骤1:无UA请求 ===")
try:
    resp1 = requests.get(target_url, timeout=15)
    check_resp(resp1)
except Exception as e:
    print(f"请求报错:{e}")

print("-" * 70)

# 步骤2:异常UA请求
bad_headers = {
    "User-Agent": "python-spider-666"
}
print("=== 步骤2:异常UA请求 ===")
try:
    resp2 = requests.get(target_url, headers=bad_headers, timeout=15)
    check_resp(resp2)
except Exception as e:
    print(f"请求报错:{e}")

print("-" * 70)

# 步骤3:正常浏览器UA请求
good_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"
}
print("=== 步骤3:正常浏览器UA请求 ===")
try:
    resp3 = requests.get(target_url, headers=good_headers, timeout=15)
    check_resp(resp3)
except Exception as e:
    print(f"请求报错:{e}")

运行结果分析

markdown 复制代码
=== 步骤1:无UA请求 ===
状态码:403
响应内容长度:312
检测到反爬提示:非法访问
----------------------------------------------------------------------
=== 步骤2:异常UA请求 ===
状态码:403
响应内容长度:315
检测到反爬提示:请使用正常浏览器访问
----------------------------------------------------------------------
=== 步骤3:正常浏览器UA请求 ===
状态码:200
响应内容长度:28976
未检测到反爬提示,数据正常
  • 无UA、异常UA请求:均返回403 Forbidden,包含明确反爬提示,无核心资讯内容;
  • 正常浏览器UA请求:返回200 OK,响应长度大幅增加,包含完整科技资讯数据,无反爬提示;
  • 额外发现:异常UA的反爬提示与无UA略有差异,说明服务器对UA格式做了解析判断。

UA检测识别结论

  1. 该站点存在强UA检测,既验证UA是否存在,也验证UA格式是否符合浏览器规范;
  2. 应对策略:必须使用符合主流浏览器格式的合法UA(从浏览器F12提取最优),不可乱写UA,避免被拦截。

避坑要点

  1. 强UA检测场景下,UA字段必须严格写为「User-Agent」(首字母大写,中间连字符),不可写成「user-agent」或「User-agent」,部分严格站点会拦截字段名大小写错误的请求;
  2. 避免使用包含「python」「spider」「crawler」等关键词的UA,即使格式合规,也可能被服务器黑名单拦截。

案例3:隐藏UA检测(验证格式+浏览器版本+完整请求头,进阶反爬)

场景说明

站点:某开源项目官方文档站点(提供API文档查询,防止批量爬取文档生成离线版本) 需求:识别该站点的UA检测是否存在隐藏条件,为何携带正常浏览器UA仍被拦截 核心特征:不仅验证UA存在与格式,还验证浏览器版本(拒绝过旧版本)、请求头完整性(仅UA不够,还需RefererAccept」等字段),属于隐藏式UA检测,新手最容易踩坑

实战操作(Python代码,分阶段验证)

python 复制代码
import requests

# 目标站点:开源项目官方文档页面(替换为合法开源项目文档站点)
target_url = "https://www.example-open-source.com/docs/api"

# 反爬提示关键词
anti_crawl_keywords = ["访问受限", "不支持该浏览器版本", "请求头不完整"]

def check_resp(resp):
    """辅助函数:解析响应结果"""
    print(f"状态码:{resp.status_code}")
    for keyword in anti_crawl_keywords:
        if keyword in resp.text:
            print(f"检测到反爬提示:{keyword}")
            return
    print("未检测到反爬提示,文档数据正常")

print("=== 阶段1:仅携带旧版本浏览器UA(格式合规,版本过旧)===")
old_version_headers = {
    # Chrome 50.0(过旧版本,已停止维护)
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
}
try:
    resp1 = requests.get(target_url, headers=old_version_headers, timeout=15)
    check_resp(resp1)
except Exception as e:
    print(f"请求报错:{e}")

print("-" * 70)

print("=== 阶段2:仅携带新版浏览器UA(格式合规,版本最新,无其他请求头)===")
new_version_only_ua_headers = {
    # Chrome 120.0(最新版本,格式合规)
    "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"
}
try:
    resp2 = requests.get(target_url, headers=new_version_only_ua_headers, timeout=15)
    check_resp(resp2)
except Exception as e:
    print(f"请求报错:{e}")

print("-" * 70)

print("=== 阶段3:携带完整请求头(新版UA+Referer+Accept等字段)===")
complete_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",
    "Referer": "https://www.example-open-source.com/",  # 来源页面,与目标站点同源
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
}
try:
    resp3 = requests.get(target_url, headers=complete_headers, timeout=15)
    check_resp(resp3)
except Exception as e:
    print(f"请求报错:{e}")

运行结果分析

markdown 复制代码
=== 阶段1:仅携带旧版本浏览器UA(格式合规,版本过旧)===
状态码:403
检测到反爬提示:不支持该浏览器版本
----------------------------------------------------------------------
=== 阶段2:仅携带新版浏览器UA(格式合规,版本最新,无其他请求头)===
状态码:403
检测到反爬提示:请求头不完整
----------------------------------------------------------------------
=== 阶段3:携带完整请求头(新版UA+Referer+Accept等字段)===
状态码:200
未检测到反爬提示,文档数据正常
  • 阶段1(旧版本UA):格式合规,但版本过旧,被服务器版本黑名单拦截;
  • 阶段2(新版仅UA):版本最新、格式合规,但缺少其他请求头字段,被请求头完整性验证拦截;
  • 阶段3(完整请求头):满足所有隐藏条件,成功获取完整文档数据。
相关推荐
写代码的【黑咖啡】9 小时前
Python中的JSON处理(标准库)
开发语言·python·json
梨子串桃子_16 小时前
推荐系统学习笔记 | PyTorch学习笔记
pytorch·笔记·python·学习·算法
文言一心17 小时前
LINUX离线升级 Python 至 3.11.9 操作手册
linux·运维·python
诗词在线18 小时前
中国古代诗词名句按主题分类有哪些?(爱国 / 思乡 / 送别)
人工智能·python·分类·数据挖掘
高锰酸钾_18 小时前
机器学习-L1正则化和L2正则化解决过拟合问题
人工智能·python·机器学习
天天睡大觉18 小时前
Python学习11
网络·python·学习
智航GIS18 小时前
11.11 Pandas性能革命:向量化操作与内存优化实战指南
python·pandas
写代码的【黑咖啡】19 小时前
Python中的Selenium:强大的浏览器自动化工具
python·selenium·自动化
抠头专注python环境配置19 小时前
解决Windows安装PythonOCC报错:从“No module named ‘OCC’ ”到一键成功
人工智能·windows·python·3d·cad·pythonocc