移动端数据采集必备:主流App User-Agent原理、大全与Python实战
1. 项目概述:为什么我们需要一份“常用App User-Agent大全”?
做爬虫或者做数据接口对接的朋友,估计都跟我一样,对User-Agent这个字段又爱又恨。爱的是,它有时候是打开数据大门的钥匙;恨的是,它变化多端,稍不留神就被目标服务器识别为“非正常访问”给拒之门外。我整理这份“常用App User-Agent大全”的初衷,源于一次真实的踩坑经历。当时我需要模拟某主流短视频App的客户端去抓取一些公开的榜单数据,自以为聪明地用了浏览器默认的UA,结果请求要么石沉大海返回403,要么返回的都是经过混淆的、针对PC端的网页源码,完全不是我想要的结构化数据。
那一刻我才深刻意识到,在移动互联网时代,服务器端识别客户端身份、区分流量来源的核心依据,往往就是这个藏在HTTP请求头里的User-Agent字符串。它不仅仅是一个标识,更像是一张“数字身份证”,上面写明了你的设备型号、操作系统版本、所用的App及其版本号,甚至编译引擎信息。对于很多App的服务器来说,只认自家客户端的“身份证”,你用浏览器或者其他客户端的身份去访问,它要么不搭理你,要么给你看的是另一套完全不同的内容。因此,无论是为了数据采集的稳定性,还是为了精准模拟客户端行为进行测试、逆向分析,手头有一份准确、常用、持续更新的App UA大全,就相当于有了一本“万能通行证手册”。
这份大全适合谁?如果你是爬虫工程师、测试开发、安全研究员,或者是对移动端网络交互原理感兴趣的后端、客户端开发者,那么这份资料就是你工具箱里的必备品。它不能保证你绕过所有反爬策略(那需要更综合的技术),但能解决你遇到的第一道也是最常见的门槛——身份伪装。接下来,我会从原理、结构、实战应用和避坑指南四个维度,为你彻底拆解User-Agent,并附上我精心收集和验证过的数十款国内外主流App的UA信息。
2. User-Agent核心原理与结构深度拆解
2.1 User-Agent到底是什么?服务器用它来做什么?
简单来说,User-Agent(简称UA)是一个HTTP请求头字段,由客户端(如浏览器、App)在发起网络请求时自动发送给服务器。它的核心作用是告知服务器当前客户端的软件环境信息。不要小看这一串文本,在现代复杂的网络服务架构中,它承担了多个关键职能:
内容协商与差异化响应:这是最主要的功能。服务器根据UA判断客户端类型,从而返回最合适的内容格式。例如:
- 识别为移动端浏览器(如
Mobile Safari),则返回移动端优化的H5页面。 - 识别为自家官方App(如
TikTok),则返回专为App设计的、结构清晰的JSON API数据。 - 识别为桌面端浏览器,则返回完整的PC网页。
- 识别为旧版本App,可能会返回降级的功能或提示升级。
- 识别为移动端浏览器(如
统计与分析:服务提供商通过分析UA,可以了解用户的设备分布、操作系统占比、浏览器/App版本流行度等,用于指导产品开发和运营策略。
基础的反爬虫与安全风控:这是与我们最相关的点。一个缺失、明显伪造(如使用默认的
Python-urllib)、或与请求其他特征(如Cookie、行为频率)不匹配的UA,会立刻被标记为可疑流量。虽然高明的反爬系统不单独依赖UA,但它是一个成本极低且有效的第一道过滤器。
2.2 解剖一个典型的移动端App User-Agent
一个完整的移动端App的UA字符串,通常包含多个由空格分隔的“产品标记”(product tokens)。每个标记的格式通常是产品名/版本号。我们以一个真实的抖音Android客户端UA为例进行拆解:
Mozilla/5.0 (Linux; Android 11; SM-G988B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36 Aweme/21.5.0我们来分段解读:
Mozilla/5.0:这是一个历史遗留的兼容性标记,几乎所有现代浏览器和WebView组件都会带上它,没有实际版本意义,可以视为一个“我是浏览器家族成员”的声明。(Linux; Android 11; SM-G988B):系统平台信息,位于括号内。Linux:底层内核,对于Android设备通常是Linux。Android 11:操作系统及版本。SM-G988B:设备型号。这是最关键的信息之一,不同型号可能对应不同的屏幕分辨率、性能,服务器可能据此提供不同清晰度的图片或视频流。
AppleWebKit/537.36 (KHTML, like Gecko):渲染引擎信息。表示客户端使用了与Apple Safari同源的WebKit渲染引擎,并兼容Gecko(Firefox的引擎)标准。这说明了其网页渲染能力。Chrome/91.0.4472.120:Chromium内核版本。许多Android App的内置浏览器组件(WebView)基于Chromium,这里指明了其内核版本号。Mobile Safari/537.36:兼容性声明,声明自己兼容移动版Safari的某些特性。Aweme/21.5.0:这才是App自身的标识!Aweme是抖音的国际版/内部项目名,21.5.0是App的版本号。服务器主要就是靠这个字段来确认请求来自“官方抖音客户端”以及其具体版本。
注意:并非所有App的UA都如此复杂。一些轻量级App或使用原生网络库的App,其UA可能非常简单,例如只包含
AppName/Version。但主流App,特别是大量使用H5混合开发或内置浏览器功能的,其UA往往会包含完整的浏览器引擎信息,以保障内嵌网页的正常渲染。
2.3 如何获取和验证一个App的User-Agent?
作为一名实践者,我们不能只依赖网上流传的、可能过时的UA列表。掌握自行获取和验证的方法至关重要。主要有以下几种途径:
- 抓包工具直接捕获(最推荐):在电脑上配置代理(如Charles、Fiddler、mitmproxy),将手机的网络流量代理到电脑上。然后在手机上正常操作目标App,抓包工具会记录下所有HTTP/HTTPS请求,请求头中的
User-Agent一目了然。这是获取最真实、最新UA的唯一可靠方法。 - 在App内访问特定网页:有些App提供了“内置浏览器”功能,或者有“用户反馈”、“第三方服务”页面。让App加载一个能显示UA的网页(例如搜索“what is my user agent”),网页上显示的就是当前App WebView的UA。
- 通过Android SDK代码获取:对于开发者,可以在Android模拟器或真机中,通过
WebSettings.getDefaultUserAgent()方法获取默认WebView的UA,但此方法获取的不一定包含App自定义部分。
验证环节:获取到UA字符串后,不要直接使用。最好用脚本模拟请求,检查返回的内容是否与用真实App访问时一致(例如,是否返回了JSON数据而非HTML)。同时,观察请求是否成功(状态码200),以及是否有被限流的迹象。
3. 主流App User-Agent大全与解析
以下是我通过抓包、社区收集以及长期维护整理的一份主流App的User-Agent示例。请务必注意:UA中的设备型号(SM-G988B)、系统版本(Android 11)、内核版本(Chrome/91.x)和App版本(Aweme/21.5.0)会随着时间快速变化。这里提供的是结构和关键标识的参考,实际使用时建议根据当前情况更新版本号,甚至替换为更常见的设备型号(如XiaoMi 12)。
3.1 国内主流应用
3.1.1 短视频与内容平台
抖音 (Android)
Mozilla/5.0 (Linux; Android 11; SM-G988B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36 Aweme/21.5.0- 核心标识:
Aweme。这是抖音客户端的核心标记。 - 实操心得:抖音的API对UA校验非常严格。仅使用
Aweme标识可能不够,需要搭配完整的Android设备信息和Chromium内核信息。模拟时,Android版本和Chrome内核版本建议保持相对较新且合理。
- 核心标识:
抖音 (iOS)
Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Aweme/21.5.0- 核心标识:同样是
Aweme。 - 结构差异:iOS端UA以
iPhone和CPU iPhone OS开头,渲染引擎是AppleWebKit/605.1.15,没有Chrome字段。Mobile/15E148是iOS系统构建版本。
- 核心标识:同样是
快手 (Android)
Mozilla/5.0 (Linux; Android 10; VCE-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36 Kwai/10.9.20.xxxx- 核心标识:
Kwai。 - 注意:快手的UA末尾有时会带有一串类似
xxxx的额外编码,可能是渠道标识,模拟时可以不携带。
- 核心标识:
小红书 (Android)
Mozilla/5.0 (Linux; Android 9; MIX 2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36 xhs/5.60.0- 核心标识:
xhs。 - 特点:小红书App的UA相对标准,核心就是
xhs加上版本号。
- 核心标识:
3.1.2 社交与通讯
微信 (Android - 内置浏览器)
Mozilla/5.0 (Linux; Android 10; ELS-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 MMWEBID/xxxx MicroMessenger/8.0.25.xxxx- 核心标识:
MicroMessenger。这是微信客户端的唯一标识。 - 重要提示:微信对自身API的防护极强,仅模拟UA访问其核心接口(如登录、朋友圈)是远远不够的,会涉及复杂的签名、Cookie和网络协议。此UA主要用于识别微信内置浏览器(X5内核)访问第三方网页的场景。
- 核心标识:
微博 (Android)
Mozilla/5.0 (Linux; Android 11; ONEPLUS A6000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36 Weibo (OnePlus-A6000__weibo__11.8.3__android__android11)- 核心标识:以
Weibo开头,后面括号内包含了设备、App版本、系统的详细信息,格式比较独特。 - 解析:这种将详细信息打包在
Weibo标记后的格式,方便了服务器一次性解析所有环境信息。
- 核心标识:以
3.1.3 电商与生活服务
淘宝 (Android)
Mozilla/5.0 (Linux; U; Android 10; zh-cn; VCE-AL00 Build/HUAWEIVCE-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 AliApp(TB/10.15.0) UCBS/xxxx- 核心标识:
AliApp(TB/10.15.0)。AliApp是阿里系应用的统一前缀,TB代表淘宝,后面是版本号。 - 特点:阿里系App的UA格式非常规范,
AliApp(XX/版本号)是通用模式。
- 核心标识:
京东 (Android)
Mozilla/5.0 (Linux; Android 11; Mi 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36 jingdong/10.2.2- 核心标识:
jingdong。 - 注意:京东App的UA相对简洁,核心标识就是
jingdong加版本号。
- 核心标识:
美团 (Android)
Mozilla/5.0 (Linux; Android 9; MI 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.119 Mobile Safari/537.36 Meituan/11.15.203- 核心标识:
Meituan。
- 核心标识:
3.2 国外主流应用(示例)
TikTok (Android)
Mozilla/5.0 (Linux; Android 10; SM-N975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36 TikTok/21.5.0- 核心标识:
TikTok。与其国内版Aweme不同。
- 核心标识:
Instagram (Android)
Mozilla/5.0 (Linux; Android 9; SM-G960F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36 Instagram 200.0.0.32.120 Android (28/9; 420dpi; 1080x2030; samsung; SM-G960F; starlte; samsungexynos9810; en_GB; 000000)- 核心标识:
Instagram。其UA特点是将非常详细的设备信息(分辨率、DPI、芯片型号、语言等)以键值对形式放在了Instagram标记之后,信息量巨大。
- 核心标识:
Twitter (Android)
TwitterAndroid/10.10.0 (SM-G988B; Android 11)- 核心标识:
TwitterAndroid。Twitter的UA非常简洁,直接是App名+版本号,以及括号内的设备信息。
- 核心标识:
3.4 使用与维护清单表格
为了方便查阅和更新,我将关键信息整理成下表:
| 应用平台 | 核心标识 (Product Token) | 典型设备/系统片段 | 备注与更新要点 |
|---|---|---|---|
| 抖音 (Android) | Aweme/版本号 | Android 11; SM-G988B | 需包含完整WebKit/Chrome信息,版本需更新。 |
| 抖音 (iOS) | Aweme/版本号 | iPhone OS 15_5 like Mac OS X | 无Chrome字段,注意iOS系统版本格式。 |
| 快手 | Kwai/版本号 | Android 10; VCE-AL00 | 末尾可能有附加编码,非必需。 |
| 小红书 | xhs/版本号 | Android 9; MIX 2 | 格式标准,易于模拟。 |
| 微信浏览器 | MicroMessenger/版本号 | Android 10; ELS-AN00 | 仅用于识别微信内嵌浏览器。 |
| 微博 | Weibo (...) | Android 11; ONEPLUS A6000 | 独特打包格式,括号内信息丰富。 |
| 淘宝 | AliApp(TB/版本号) | Android 10; VCE-AL00 | 阿里系标准格式,TB可换为TM(天猫)、LY(飞猪)等。 |
| 京东 | jingdong/版本号 | Android 11; Mi 10 | 格式简洁。 |
| TikTok | TikTok/版本号 | Android 10; SM-N975F | 国际版标识。 |
Instagram 版本号 | Android 9; SM-G960F | UA尾部包含极详细的设备参数。 | |
TwitterAndroid/版本号 | SM-G988B; Android 11 | 格式极简,仅有App标识和设备信息。 |
维护建议:建议每季度或每半年,通过抓包方式对重点关注的App进行一轮UA信息更新,主要更新App版本号、Chromium内核版本号和主流设备型号。系统版本(如Android 11/12/13)可以保持在一个较新但非最新的稳定版本。
4. 实战应用:在Python爬虫中动态管理与使用UA
有了UA大全,关键在于如何用好。直接写死在代码里是最差的做法。下面分享我在Python爬虫项目中管理和使用UA的一套实践。
4.1 构建一个UA池(User-Agent Pool)
单一UA频繁使用极易被识别。我们需要一个池子,每次请求随机选取一个。
# ua_pool.py import random # 一个更健壮的UA池示例,包含多种浏览器和App USER_AGENTS_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 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", # 移动端浏览器 "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1", # 重点:模拟的App UA (根据上一章列表填充) "Mozilla/5.0 (Linux; Android 13; SM-S918B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36 Aweme/25.8.0", "Mozilla/5.0 (Linux; Android 12; Mi 11) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36 Kwai/11.9.10", "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Mobile Safari/537.36 xhs/7.90.0", "Mozilla/5.0 (Linux; Android 12; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36 TikTok/27.5.0", ] def get_random_ua(): """从池中随机返回一个User-Agent""" return random.choice(USER_AGENTS_POOL) def get_specific_app_ua(app_name='aweme'): """根据应用名返回一个对应的UA(简化示例)""" ua_map = { 'aweme': USER_AGENTS_POOL[3], # 对应抖音UA 'kwai': USER_AGENTS_POOL[4], 'xhs': USER_AGENTS_POOL[5], 'tiktok': USER_AGENTS_POOL[6], } return ua_map.get(app_name.lower(), get_random_ua())4.2 在请求库中应用UA
以最常用的requests和aiohttp为例。
# 使用requests import requests from ua_pool import get_random_ua, get_specific_app_ua # 方式1:随机UA,适合通用爬取 headers = { 'User-Agent': get_random_ua(), 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', } response = requests.get('https://example.com/api/data', headers=headers) # 方式2:特定App UA,针对目标API target_headers = { 'User-Agent': get_specific_app_ua('xhs'), # 模拟小红书 'Accept': 'application/json, text/plain, */*', # App通常接受JSON 'Content-Type': 'application/json', } # 可能还需要添加App特有的其他Header,如`X-Requested-With`, `Referer`等 json_response = requests.get('https://www.xiaohongshu.com/api/some/data', headers=target_headers).json()# 使用aiohttp (异步) import aiohttp import asyncio from ua_pool import get_random_ua async def fetch(session, url): headers = {'User-Agent': get_random_ua()} async with session.get(url, headers=headers) as response: return await response.text() async def main(): async with aiohttp.ClientSession() as session: tasks = [fetch(session, f'https://example.com/page/{i}') for i in range(10)] results = await asyncio.gather(*tasks) # 处理results # 运行 # asyncio.run(main())4.3 更高级的UA策略:与Session和代理结合
在实际项目中,UA需要与其他反反爬策略协同工作。
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry from ua_pool import get_random_ua class SmartCrawler: def __init__(self, use_proxy=False): self.session = requests.Session() # 1. 设置UA中间件(每次请求前随机更换) self.session.headers.update({ 'Accept-Language': 'zh-CN,zh;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', }) # 移除默认的Python-urllib UA,我们动态设置 if 'User-Agent' in self.session.headers: del self.session.headers['User-Agent'] # 2. 重试策略 retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], # 包含429(请求过多) allowed_methods=["GET", "POST"] ) adapter = HTTPAdapter(max_retries=retry_strategy) self.session.mount("http://", adapter) self.session.mount("https://", adapter) # 3. 代理设置(如有) if use_proxy: self.session.proxies.update({ 'http': 'http://your-proxy:port', 'https': 'http://your-proxy:port', }) def request(self, method, url, **kwargs): # 动态注入随机UA headers = kwargs.pop('headers', {}) headers['User-Agent'] = get_random_ua() kwargs['headers'] = headers response = self.session.request(method, url, **kwargs) # 这里可以添加响应状态码检查、异常处理等 return response # 使用 crawler = SmartCrawler() resp = crawler.request('GET', 'https://api.target-app.com/data')实操心得:不要只在请求开始时设置一次UA。对于长会话(
requests.Session),应该在每次发起请求前动态更新headers中的UA字段,模拟不同请求可能来自不同客户端的假象。同时,将UA池与IP代理池、请求速率控制结合起来,能极大提升爬虫的稳健性。
5. 常见问题、排查技巧与高级对抗实录
即使有了完美的UA,访问仍然可能失败。这一章记录了我踩过的坑和总结的排查思路。
5.1 问题排查清单
当你模拟App UA请求失败时,可以按照以下清单逐一排查:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 返回403 Forbidden | 1. UA被识别为无效或爬虫。 2. 仅UA正确,但缺少其他必要请求头。 | 1.检查UA格式:用抓包工具对比真实请求的UA,确保每个空格、标点、顺序都一致。 2.补全Headers:复制真实请求的所有Headers,特别是 Accept、Accept-Language、Content-Type、X-Requested-With。 |
| 返回200但内容是PC网页或错误数据 | 服务器根据UA返回了错误的内容版本。 | 1.确认UA是移动端App:确保UA中包含Mobile关键字和正确的App标识(如Aweme)。2.检查请求URL:App的API接口地址可能与网页版不同,确保你请求的是移动端API端点。 |
| 返回状态码429 Too Many Requests | 请求频率过高,触发速率限制。 | 1.降低请求频率:在代码中增加随机延迟(如time.sleep(random.uniform(1, 3)))。2.使用代理IP池:分散请求来源IP。 |
| 请求被重定向到登录页或首页 | 请求需要身份验证(Cookie/Token),或缺少关键参数。 | 1.检查Cookie/Session:模拟登录态,获取并携带有效的Cookie或Authorization Token。 2.分析请求参数:使用抓包工具查看真实请求的Query Parameters或Form Data,并完整模拟。 |
| SSL证书验证错误 | 目标服务器使用了不常见或自签名的证书,或客户端证书不匹配。 | 1.临时方案(不推荐用于生产):在请求中设置verify=False(requests库)。注意安全风险。2.正确方案:若App使用证书绑定,则需要提取并配置客户端证书,这涉及更复杂的逆向工程。 |
5.2 超越UA:其他必须模拟的请求特征
UA只是“身份证”,一个活人还有其他特征。高级反爬系统会进行多维度检测:
完整的HTTP头部(Headers):
Accept/Accept-Language/Accept-Encoding:表明客户端接受的内容类型、语言和压缩格式。Connection: 通常为keep-alive。Upgrade-Insecure-Requests: 对于HTTPS站点通常是1。X-Requested-With:很多App的API会携带这个头,例如XMLHttpRequest。Referer:表示请求来源页面,对于有页面跳转逻辑的API至关重要,不能乱写或为空。Origin:在POST等请求中,表示请求发起的源。
Cookie与会话管理:这是维持登录状态的关键。需要使用
requests.Session()对象自动处理Cookie,或者从抓包数据中手动提取并设置有效的Cookie字符串。请求参数与签名:这是最难的环节。很多App的API,尤其是涉及核心数据的,会对请求参数(甚至包括UA、时间戳)进行加密签名(Sign)。签名算法通常藏在App的代码里,需要逆向分析。如果遇到带有一长串无规律
sign或as、cp参数的请求,说明它需要签名验证。TLS指纹与HTTP/2:一些安全要求极高的应用会检测客户端的TLS指纹(如JA3指纹)。Python的
requests库的TLS指纹可能与真实手机客户端不同。使用curl_cffi等库可以更好地模拟特定浏览器的TLS指纹。此外,确保你的请求库支持HTTP/2,因为很多现代App API已升级到HTTP/2。
5.3 我的独家避坑技巧
- 从简单到复杂:不要一开始就试图抓取最难的核心API。先从App内简单的、公开的H5页面或信息流接口入手,验证你的UA和基础Headers是否有效。
- “像素级”复制:使用抓包工具(如Charles)导出第一次成功请求的
cURL命令,然后利用curlconverter等工具将其转换为Python代码。这是最保险的起点。 - 维护“请求模板”:对每个目标App,建立一个JSON或Python字典格式的请求模板,包含成功所需的完整Headers、Cookies和基础参数。每次请求以此模板为基础进行微调。
- 尊重
robots.txt与法律法规:在技术探索的同时,务必遵守目标网站的robots.txt协议,并严格在法律法规允许的范围内进行数据采集,不侵犯个人隐私和商业秘密。
最后,记住一点:UA模拟是网络数据交互模拟的入门技能,而非万能钥匙。随着你对HTTP协议、客户端行为、甚至逆向工程的深入理解,你会逐渐构建起一套更完整、更强大的模拟方案。这份“常用App User-Agent大全”和配套的思路,希望能为你打开这扇门,并提供一份持续更新的参考资料。在实际操作中遇到的具体问题,往往需要结合具体场景进行更精细的分析和调试。
