Python爬虫实战:User-Agent大全与反爬策略解析

发布时间:2026/7/30 2:05:56
Python爬虫实战:User-Agent大全与反爬策略解析 1. 项目缘起为什么我们需要一份“User-Agent大全”如果你写过Python爬虫哪怕只是写过最简单的requests.get()大概率都见过这个错误403 Forbidden或者返回一堆乱码又或者直接给你一个“请使用现代浏览器访问”的提示页面。很多时候问题的根源不在于你的IP也不在于你的请求频率而在于你发出的那个请求头里那个叫做User-Agent简称UA的小小字符串。User-Agent是HTTP协议中的一个字段它告诉服务器“我是谁我用什么来访问你”。对于服务器来说一个来自python-requests/2.28.1的请求和一个来自Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36的请求待遇是天差地别的。前者明明白白地宣告自己是一个Python脚本是来“爬”数据的后者则伪装成了一个在Windows 10上运行的Chrome 114浏览器是一个“正常用户”。所以准备一份详尽的、不断更新的浏览器User-Agent列表对于爬虫开发者来说就像战士需要一张精确的地图厨师需要一套顺手的刀具。它不是为了炫技而是最基础、最实用的生存技能。这份“大全”能帮你绕过基础的反爬机制很多网站的第一道防线就是检查UA非浏览器UA直接拒绝或返回简化版页面。获取完整的页面内容现代网站大量使用JavaScript渲染服务器可能会根据UA决定下发哪个版本的资源如桌面版、移动版、兼容老IE的降级版。伪装成正确的浏览器是拿到目标数据的前提。模拟更真实的用户行为在需要维持会话、处理复杂交互的爬虫中一个合理的UA是构建可信HTTP客户端会话的起点。网上确实有很多现成的UA列表但要么年久失修要么分类混乱要么就是简单罗列。这篇文章我想从一个爬虫实战者的角度不仅给你一份整理好的、分类清晰的UA列表更重要的是和你深入聊聊UA背后的门道怎么选、怎么用、怎么维护以及那些光有列表解决不了的坑。2. User-Agent的构成解析不只是复制粘贴那么简单在开始罗列清单之前我们必须先拆解一个典型的User-Agent字符串。知其然更要知其所以然这样你才能在未来遇到新浏览器时自己判断这个UA是否可用甚至自己“组装”一个。一个现代桌面版Chrome的UA可能是这样的Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36我们来分段解读Mozilla/5.0这是一个历史遗留的兼容性标记。几乎所有现代浏览器都以此开头源于早期的浏览器战争。可以理解为“这是一个兼容Mozilla标准的浏览器”。(Windows NT 10.0; Win64; x64)系统平台令牌。这是括号内的第一部分包含了操作系统信息。Windows NT 10.0 表示Windows 10操作系统。Win64和x64 表示64位Windows系统。如果是32位可能是WOW64在64位系统上运行32位程序或没有此标记。AppleWebKit/537.36渲染引擎标识。Chrome、Edge、Safari以及大多数现代浏览器都使用WebKit或它的分支BlinkChrome/Edge作为核心渲染引擎。这个版本号会随着浏览器内核更新而改变。(KHTML, like Gecko)另一个历史兼容标记表明它兼容GeckoFirefox的引擎和KHTMLWebKit的前身的渲染模式。Chrome/114.0.0.0浏览器品牌和版本。这是最核心的标识直接告诉服务器这是Chrome 114。Safari/537.36为了兼容那些检测Safari的网站而添加的标记因为WebKit最初是为Safari开发的。理解了结构我们就能明白一个“好”的UA不仅仅是版本号新它的各个部分需要自洽。你不能用一个Windows NT 10.0的系统令牌后面却跟着一个只支持macOS的Safari/15.0的浏览器标识这种低级的矛盾很容易被服务器识破。注意移动设备的UA结构类似但平台令牌不同。例如iOS设备会包含iPhone或iPad以及CPU iPhone OS 13_5_1 like Mac OS X这样的信息Android设备则会包含Linux; Android 10等。3. 实战清单分类整理的主流浏览器User-Agent下面我将按照桌面端和移动端以及浏览器品牌进行分类整理。这些UA是我从实际浏览器请求中收集、验证并参考了最新版本信息整理的。请记住浏览器的版本号是快速变化的这里的列表是一个“模板”和“参考”核心是学会如何根据这个模板去更新版本号。3.1 桌面端浏览器3.1.1 Google Chrome (Windows)Chrome是目前市场份额最大的浏览器伪装成Chrome是最常见的选择。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; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36要点Win64; x64对应64位系统。WOW64对应在64位系统上运行的32位Chrome。第三个是更简化的版本省略了位数信息。将120.0.0.0替换为最新的稳定版版本号如121 122等。3.1.2 Microsoft Edge (Windows)Edge基于Chromium内核其UA与Chrome高度相似但带有Edg标识。Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0要点注意末尾的Edg/120.0.0.0。这是区分Edge和Chrome的关键。同样版本号需要更新。3.1.3 Mozilla Firefox (Windows)Firefox使用Gecko渲染引擎其UA格式独树一帜。Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0 Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/109.0要点rv:109.0表示Gecko的版本号通常与Firefox主版本号一致。Gecko/20100101是一个固定日期标记代表Gecko的渲染引擎。更新时主要修改rv:109.0和Firefox/109.0中的版本号。3.1.4 Apple Safari (macOS)Safari是macOS的默认浏览器其UA带有明显的苹果生态特征。Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15要点Macintosh; Intel Mac OS X 10_15_7表示在Intel芯片的Mac上运行macOS Catalina (10.15.7)。对于Apple Silicon芯片M1 M2此部分通常不变或变为Macintosh; ARM Mac OS X但实践中多数网站不深究芯片架构。AppleWebKit/605.1.15是Safari的WebKit版本。Version/16.0是Safari的浏览器版本号。这是需要更新的主要部分。3.2 移动端浏览器移动端爬虫同样重要很多网站对移动端和桌面端返回的HTML结构、API接口甚至数据都不同。3.2.1 iOS Safari (iPhone/iPad)Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1 Mozilla/5.0 (iPad; CPU OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1要点CPU iPhone OS 16_3 like Mac OS X标识了iOS系统版本。Mobile/15E148是移动设备标识符的一部分。Version/16.3和系统版本对应。更新时需要同步修改系统版本和Safari版本。3.2.2 Android ChromeMozilla/5.0 (Linux; Android 10; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36 Mozilla/5.0 (Linux; Android 13; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36要点Android 10或Android 13是安卓系统版本。SM-G981B(三星Galaxy S20) 或Pixel 6是设备型号。这部分可以替换成其他流行机型如Mi 10、VOG-AL00华为P30等增加真实性。Mobile关键字表明这是移动版浏览器。更新Chrome版本号。3.2.3 微信内置浏览器 (iOS/Android)在国内爬取H5页面或公众号内容时微信内置浏览器XWEB的UA非常关键。Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.40(0x1800282f) NetType/WIFI Language/zh_CN Mozilla/5.0 (Linux; Android 10; VOG-AL00 Build/HUAWEIVOG-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/86.0.4240.99 XWEB/4313 MMWEBSDK/20220805 Mobile Safari/537.36 MMWEBID/6404 MicroMessenger/8.0.27.2220(0x28001B3D) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64要点结构复杂包含了MicroMessenger微信、NetType网络类型、Language语言等大量客户端信息。安卓版还包含XWEB腾讯X5内核和MMWEBSDK微信Web SDK信息。重要微信UA的Chrome内核版本号往往滞后于官方Chrome。直接使用最新的Chrome移动版UA可能不如使用微信UA的特征更真实。4. 在Python爬虫中动态管理与使用User-Agent有了清单下一步就是如何在代码中高效、安全地使用它们。直接硬编码在代码里是最差的做法不利于维护和扩展。4.1 构建一个UA池User-Agent Pool最佳实践是创建一个UA池每次请求随机选取一个这样可以避免因短时间内大量相同UA的请求而触发反爬。import random import requests DESKTOP_USER_AGENTS [ ‘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) Chrome/119.0.0.0 Safari/537.36‘, ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0‘, ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15‘, ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0‘, ] MOBILE_USER_AGENTS [ ‘Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1‘, ‘Mozilla/5.0 (Linux; Android 10; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36‘, ] def get_random_ua(platform‘desktop‘): 随机获取一个User-Agent if platform ‘mobile‘: return random.choice(MOBILE_USER_AGENTS) else: return random.choice(DESKTOP_USER_AGENTS) # 使用示例 headers { ‘User-Agent‘: get_random_ua(), ‘Accept‘: ‘text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8‘, ‘Accept-Language‘: ‘zh-CN,zh;q0.8,zh-TW;q0.7,zh-HK;q0.5,en-US;q0.3,en;q0.2‘, ‘Accept-Encoding‘: ‘gzip, deflate, br‘, } response requests.get(‘https://example.com‘, headersheaders)实操心得不要只用一个UA即使你伪装成了Chrome如果同一个IP在1分钟内用同一个Chrome UA发出100个请求依然很可疑。随机轮换是基本操作。平台匹配如果你爬取的网站有专门的移动端适配m.xxx.com 或响应式设计那么使用移动端UA可能更容易获取到结构简单的页面。反之如果需要获取桌面端的完整数据就使用桌面端UA。最好能根据目标URL的特征动态选择。维护版本号定期比如每月检查一次主流浏览器的稳定版版本更新你的UA池。过旧的UA比如Chrome 80可能会被服务器标记为“不安全的旧版浏览器”而限制功能。4.2 进阶使用fake-useragent库手动维护UA池很麻烦。社区有一个非常流行的库叫fake-useragent它可以动态生成看起来非常真实的UA。pip install fake-useragentfrom fake_useragent import UserAgent import requests # 创建一个UserAgent对象 # 使用use_cache_serverFalse和fallback可以避免因为访问不到外部CDN而报错 ua UserAgent(use_cache_serverFalse, fallback‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...‘) headers { ‘User-Agent‘: ua.random, # 随机生成一个 # ‘User-Agent‘: ua.chrome, # 指定生成Chrome的 # ‘User-Agent‘: ua.firefox, # 指定生成Firefox的 } response requests.get(‘https://example.com‘, headersheaders) print(f“使用的UA: {headers[‘User-Agent‘]}“)踩坑与注意事项网络问题fake-useragent首次运行或定期会从远程服务器下载UA数据列表。如果网络环境受限可能导致初始化失败或超时。这就是为什么上面代码中设置了use_cache_serverFalse并提供了fallback参数。更稳妥的做法是在项目初始化时更新一次数据然后将其缓存到本地文件。生成逻辑它生成的UA是“真实”的但版本号可能不是最新的。对于版本号有严格要求的场景仍需手动校验。过度使用如果一个网站的反爬策略非常严格它可能会检测到fake-useragent库生成的一些不常见的、或者版本号和系统信息略微不匹配的UA虽然概率低。在极高安全级别的场景下手动维护一个精心挑选的、高仿真的小规模UA池可能更可靠。5. 超越UA反爬虫策略的对抗与伦理边界仅仅更换UA在如今只是爬虫攻防战中最基础的一步。一个具备基本反爬能力的网站会采用多维度检测请求头完整性检测只改UA是不够的。一个正常的浏览器请求会携带一整套完整的Headers如Accept、Accept-Language、Accept-Encoding、Connection、Upgrade-Insecure-Requests、Sec-Fetch-*系列头等。你的爬虫也应该尽量补全这些头信息特别是Sec-Fetch-Dest、Sec-Fetch-Mode、Sec-Fetch-Site、Sec-Fetch-User这几个用于指示请求来源和目的的头部在现代浏览器中默认发送缺失它们是一个明显的非浏览器信号。headers { ‘User-Agent‘: ‘...‘, ‘Accept‘: ‘text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8‘, ‘Accept-Language‘: ‘zh-CN,zh;q0.9,en;q0.8‘, ‘Accept-Encoding‘: ‘gzip, deflate, br‘, ‘Connection‘: ‘keep-alive‘, ‘Upgrade-Insecure-Requests‘: ‘1‘, ‘Sec-Fetch-Dest‘: ‘document‘, ‘Sec-Fetch-Mode‘: ‘navigate‘, ‘Sec-Fetch-Site‘: ‘none‘, ‘Sec-Fetch-User‘: ‘?1‘, ‘Cache-Control‘: ‘max-age0‘, }TLS指纹与HTTP/2指纹高级反爬会检测客户端的加密套件、TLS版本、ALPN扩展等形成TLS指纹或者检测HTTP/2的连接序言和帧设置形成HTTP/2指纹。使用标准的requests库或aiohttp库其指纹与Python的urllib3相关和真实浏览器如Chrome的boringssl不同。对抗这个需要更底层的工具如使用curl_cffi库模拟浏览器TLS指纹或直接操控浏览器自动化工具如playwright、selenium。浏览器环境与行为模拟对于JavaScript重度依赖的网站简单的HTTP请求无法执行JS拿不到渲染后的数据。此时需要Selenium、Playwright或Pyppeteer这类真正的浏览器自动化工具。它们启动的是一个完整的浏览器实例拥有真实的UA、完整的HTTP头、Canvas指纹、WebGL指纹等能通过绝大多数前端检测。但代价是资源消耗大、速度慢。from playwright.sync_api import sync_playwright with sync_playwright() as p: # 启动一个Chromium浏览器更接近Chrome browser p.chromium.launch(headlessFalse) # 调试时可设为False看界面 page browser.new_page() page.goto(‘https://example.com‘) # 此时page.content()获取到的就是完全渲染后的HTML html page.content() browser.close()IP频率与行为模式这是最核心的防线。即使你伪装得天衣无缝如果一个IP在短时间内发出成千上万的请求也必然会被封禁。因此必须配合代理IP池、请求速率限制如time.sleep(random.uniform(1, 3))、模拟人类操作间隔点击、滚动等策略。关于伦理与法律的最后提醒遵守robots.txt在爬取前访问网站的/robots.txt查看对方是否明确禁止爬取某些路径。这是网络礼仪也是一些法律诉讼中的参考依据。尊重版权与数据所有权爬取的数据用于个人学习、研究是合理的但未经授权用于商业牟利、公开传播可能侵犯对方的权益。避免对目标网站造成负担控制请求频率避免DDoS式的访问影响网站正常服务。这是基本的道德要求。关注法律法规数据安全法、个人信息保护法等法规对爬取个人信息有严格规定。切勿爬取、存储、泄露他人隐私信息。一份好的UA列表是爬虫工程师工具箱里的螺丝刀必不可少但绝不是万能钥匙。真正的挑战在于理解反爬策略的完整链条并在此基础上构建一个稳健、高效且负责任的爬虫系统。从UA出发不断深入这才是爬虫技术学习的正确路径。