单纯用random.choice()列表易被封,因UA数量少、版本过时、缺少配套请求头;应使用fake-useragent动态获取真实UA并配合Session、合理间隔与Referer等完整浏览器行为模拟。

直接用固定 User-Agent 请求网站,99% 会被识别为爬虫并返回 403 或空响应;换随机 User-Agent 是最基础、最有效的绕过手段之一,但光“随机”不够,得模拟真实浏览器行为。
为什么单纯用 random.choice() 列表容易被封?
很多教程教人手写一个字符串列表,每次随机挑一个。问题在于:
- 列表太小(比如只有 5–10 条),指纹重复率高,服务端通过 UA 频次统计就能识别异常请求
- UA 字符串过时(如还包含
Chrome/58.0),现代网站会结合 UA 中的版本号做客户端能力校验,不匹配直接拦截 - 缺少配套 Header(如
Accept-Language、Accept-Encoding),单换 UA 而其他字段仍是 requests 默认值,反而更可疑
推荐用 fake-useragent 动态获取真实 UA
它会从多个公开源(如 browserscan、useragentstring.com)自动抓取最新 UA,并缓存本地,避免每次请求都发 HTTP。
安装与基础用法:
立即学习“Python免费学习笔记(深入)”;
pip install fake-useragent
使用时注意三点:
- 首次运行会下载 UA 池,需联网;后续默认读
~/.fake_useragent.json,可手动指定路径避免权限问题 - 务必捕获
FakeUserAgentError异常——源站不可用或网络失败时会抛出,不能让程序卡死 - 不要在循环里反复创建
UserAgent()实例,应复用单例,否则频繁重载缓存反而变慢
示例:
from fake_useragent import UserAgent
from requests import Session
<p>ua = UserAgent(cache_path="/tmp/fua.json") # 指定缓存路径防 PermissionError
session = Session()
try:
session.headers.update({
"User-Agent": ua.random,
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
})
except Exception:
session.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" # fallback
requests + session 复用比单次 get() 更安全
反爬系统常分析 IP 的请求节奏和连接特征。用 Session 能自动管理 Cookie、复用 TCP 连接、保持 Header 一致性,比每次新建请求更像真实用户。
关键配置点:
- 设置
session.headers后,所有session.get()/session.post()都自动携带,不用每调用一次都重设 - 加上
timeout=(3, 7)(连接 3 秒,读取 7 秒),避免卡死拖慢整体频率 - 如果目标站有登录态,
Session自动维护Set-Cookie,省去手动解析
UA 不是万能解药:必须配合请求间隔和 Referer
只换 UA,但 1 秒内连发 20 次请求,照样被限流。真实用户不会这么干。
简单加固建议:
- 用
time.sleep(random.uniform(1.5, 4.0))控制间隔,别用固定 1 秒——规律性本身就会暴露脚本 - 对有 Referer 校验的页面(比如图片链接),手动加
"Referer": "https://example.com/",否则返回 403 - 某些站点(如知乎、微博)会验证
Sec-Fetch-*系列 Header,此时仅靠fake-useragent不够,得补全(但多数中小站不需要)
UA 只是第一道门,真正难的是行为建模——鼠标移动、滚动延迟、点击顺序这些,Python 层面很难模拟,得上 Playwright 或 Puppeteer。


















