星星拖尾动画 - 优化版

什么是浏览器指纹

浏览器指纹就是收集浏览器的各种特征信息,来唯一识别一个用户或者设备的技术。

就像警察办案的时候可以通过现场留下的指纹来锁定凶手一样,服务器可以通过浏览器的指纹判断:

  1. 用户使用的是什么浏览器(Chrome,Safari,Firefox等)

  2. 使用的是什么设备(电脑、手机、平板)

  3. 使用的操作系统(Windows、Mac、iOS、Android等)。

为什么使用指纹

服务器端的需求

  1. 识别出来机器人、爬虫、自动化脚本等非人类的操作

  2. 检测出来某些用户的异常操作

  3. 哪怕用户清除掉了cookie也可以识别出用户

### 客户端的需求

  1. 伪装成正常的用户去骗过服务器,让服务器正常返回,而不是401/403的拒绝

指纹的工作原理

image-20260127144906178

指纹的组成部分

1. HTTP Headers(最重要)

User-Agent(用户代理)

 Chrome 桌面版:
 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 
 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
 ​
 Safari iOS 移动版:
 Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) 
 AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 
 Mobile/15E148 Safari/604.1

Sec-Ch-Ua(客户端提示)

 Chrome:
 "Not_A Brand"; v="8", "Chromium"; v="120", "Google Chrome"; v="120"
 ​
 Safari iOS:
 "Not_A Brand"; v="8", "Chromium"; v="120", "Safari"; v="17"

Sec-Ch-Ua-Platform(平台)

 Chrome 桌面: "Windows"
 Safari iOS:  "ios"

Sec-Ch-Ua-Mobile(是否移动设备)

 桌面: ?0
 移动: ?1

2. 其他重要 Headers

 Accept: application/json, text/plain, */*
 Accept-Encoding: gzip, deflate, br, zstd
 Accept-Language: en-US,en;q=0.9
 Cache-Control: no-cache
 Origin: https://sora.chatgpt.com
 Referer: https://sora.chatgpt.com/
 Sec-Fetch-Dest: empty
 Sec-Fetch-Mode: cors
 Sec-Fetch-Site: same-origin

3. TLS 指纹

  • TLS 握手时的加密套件顺序

  • 支持的 TLS 版本

  • 扩展字段


在项目中的应用

我们使用的库:curl_cffi

 from curl_cffi.requests import AsyncSession
 ​
 # 不伪装(会被识别)
 response = await session.get(url, headers=headers)
 ​
 # 伪装成 Chrome(可能被识别)
 response = await session.get(
     url, 
     headers=headers,
     impersonate="chrome"  # 自动模拟 Chrome 的所有特征
 )
 ​
 # 伪装成 Safari iOS(更难被识别)
 response = await session.get(
     url, 
     headers=headers,
     impersonate="safari_ios"  # 自动模拟 Safari iOS 的所有特征
 )

impersonate 参数做了什么?

当你设置 impersonate="safari_ios" 时,curl_cffi 会自动:

  1. 设置正确的 User-Agent

  2. 设置正确的 Sec-Ch-Ua 系列 Headers

  3. 模拟 Safari 的 TLS 指纹

  4. 模拟 Safari 的 HTTP/2 设置

  5. 模拟 Safari 的加密套件顺序

这样,从服务器的角度看,你的请求和真实的 Safari iOS 浏览器几乎一模一样!


Chrome vs Safari iOS 对比

Chrome 桌面指纹特征

 headers = {
     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
     "Sec-Ch-Ua": '"Google Chrome"; v="120"',
     "Sec-Ch-Ua-Platform": '"Windows"',
     "Sec-Ch-Ua-Mobile": "?0",  # 不是移动设备
 }
 impersonate = "chrome"

特点

  • ✅ 常见,不容易引起怀疑

  • ❌ 但 OpenAI 对桌面浏览器检测更严格

  • ❌ 容易触发 401 错误

Safari iOS 指纹特征

 headers = {
     "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 ...",
     "Sec-Ch-Ua": '"Safari"; v="17"',
     "Sec-Ch-Ua-Platform": '"ios"',
     "Sec-Ch-Ua-Mobile": "?1",  # 是移动设备
 }
 impersonate = "safari_ios"

特点

  • ✅ 移动端指纹更简单

  • ✅ OpenAI 对移动端检测较宽松

  • ✅ 几乎不会触发 401 错误

  • ✅ 更稳定


实战案例

案例 1:测试结果对比

修改前(Chrome 指纹)

 # 查看日志中的 401 错误
 docker logs sora2api-main --tail 200 | grep "401"
 ​
 结果:40 个 401 错误
 ❌ Failed to get subscription info: 401
 ❌ Failed to get subscription info: 401
 ❌ Failed to get subscription info: 401
 ...

修改后(Safari iOS 指纹)

 # 查看日志中的 401 错误
 docker logs sora2api-main --tail 200 | grep "401"
 ​
 结果:0 个 401 错误
 ✅ 响应状态码: 200
 ✅ 订阅信息提取成功
 ✅ Sora2邀请码获取成功

案例 2:代码对比

原版(Chrome)

 async def get_user_info(self, access_token: str):
     async with AsyncSession() as session:
         headers = {
             "Authorization": f"Bearer {access_token}",
             "Accept": "application/json",
         }
         
         kwargs = {
             "headers": headers,
             "timeout": 30,
             "impersonate": "chrome"  # ❌ 容易被识别
         }
         
         response = await session.get(url, **kwargs)

优化后(Safari iOS)

 async def get_user_info(self, access_token: str):
     async with AsyncSession() as session:
         headers = {
             "Authorization": f"Bearer {access_token}",
             "Accept": "application/json, text/plain, */*",
             "Accept-Encoding": "gzip, deflate, br, zstd",
             "Accept-Language": "en-US,en;q=0.9",
             "Cache-Control": "no-cache",
             "Origin": "https://sora.chatgpt.com",
             "Pragma": "no-cache",
             "Priority": "u=1, i",
             "Referer": "https://sora.chatgpt.com/",
             "Sec-Ch-Ua": '"Not_A Brand"; v="8", "Chromium"; v="120", "Safari"; v="17"',
             "Sec-Ch-Ua-Mobile": "?1",
             "Sec-Ch-Ua-Platform": '"ios"',
             "Sec-Fetch-Dest": "empty",
             "Sec-Fetch-Mode": "cors",
             "Sec-Fetch-Site": "same-origin"
         }
         
         kwargs = {
             "headers": headers,
             "timeout": 30,
             "impersonate": "safari_ios"  # ✅ 更难被识别
         }
         
         response = await session.get(url, **kwargs)

如何选择合适的指纹?

决策树

 需要调用 API
     |
     ├─ 目标网站对移动端友好?
     |   ├─ 是 → 使用 Safari iOS(推荐)
     |   └─ 否 → 使用 Chrome 桌面
     |
     ├─ 目标网站检测严格?
     |   ├─ 是 → 使用 Safari iOS(更难检测)
     |   └─ 否 → Chrome/Firefox 都可以
     |
     └─ 需要长期稳定?
         ├─ 是 → 使用 Safari iOS(最稳定)
         └─ 否 → 任意浏览器

推荐方案

场景

推荐指纹

原因

OpenAI API

Safari iOS

移动端检测宽松,稳定性高

一般网站爬虫

Chrome

最常见,不容易引起怀疑

需要桌面特性

Chrome/Firefox

某些功能只有桌面版支持

高频请求

Safari iOS

更不容易被限流


常见问题

Q1: 为什么不直接用真实浏览器?

A:

  • 真实浏览器太重,占用资源多

  • 自动化困难(需要 Selenium/Puppeteer)

  • 速度慢

  • 用 curl_cffi 可以模拟浏览器,但速度快、资源占用少

Q2: impersonate 能模拟所有特征吗?

A:

  • ✅ 能模拟:User-Agent、Headers、TLS 指纹、HTTP/2 设置

  • ❌ 不能模拟:JavaScript 环境、Canvas 指纹、WebGL 指纹

  • 对于 API 调用来说,impersonate 已经足够

Q3: 为什么 Safari iOS 比 Chrome 好?

A:

  1. 移动端特征简单:移动浏览器的指纹特征比桌面少

  2. 检测宽松:服务器对移动端的检测通常较宽松

  3. 常见设备:iPhone 用户多,不容易被标记为异常

  4. 实测效果好:0 个 401 错误 vs 40 个 401 错误

Q4: 如何验证指纹是否有效?

A:

 # 方法 1:查看日志中的错误率
 docker logs sora2api-main | grep "401" | wc -l
 ​
 # 方法 2:实际测试请求
 python simple_comparison_test.py
 ​
 # 方法 3:长期监控
 docker logs -f sora2api-main

总结

核心要点

  1. 浏览器指纹 = 浏览器的身份证

    • 通过 Headers、TLS 等特征识别浏览器类型

  2. 为什么需要伪装?

    • 防止被识别为脚本/机器人

    • 避免 401/403 错误

    • 提高请求成功率

  3. 如何伪装?

    • 使用 curl_cffi 库

    • 设置 impersonate 参数

    • 添加完整的 Headers

  4. 最佳实践

    • 优先使用 Safari iOS 指纹(移动端)

    • 添加完整的 Headers(Accept、Referer 等)

    • 定期监控错误率

    • 根据实际效果调整

  5. 效果验证

    • Chrome 指纹:40 个 401 错误

    • Safari iOS 指纹:0 个 401 错误

    • 提升成功率 100%!