python

抖音视频评论爬取:逆向分析Web端评论接口

2026-07-06 #python#爬虫#JS逆向

前言

抖音作为国内最大的短视频平台,每天产生海量的用户评论数据。这些评论数据对于舆情分析、用户画像、产品反馈等场景具有重要价值。然而,抖音的反爬机制非常严格,涉及到参数签名、设备指纹、Cookie验证等多重防护。

本文基于真实的抖音视频评论爬虫源码,讲解如何通过分析抖音Web端的评论接口,构造完整的请求参数来获取指定视频的评论数据。重点会拆解 a_bogusmsTokenverifyFp 等关键签名参数的作用。

技术背景

抖音Web端接口分析

抖音Web端(www.douyin.com)的评论数据通过以下接口获取:

1
GET https://www.douyin.com/aweme/v1/web/comment/list/

这个接口返回 JSON 格式的评论列表,包含用户昵称、评论内容、点赞数、回复数等信息。

反爬机制

抖音的反爬策略非常复杂,主要涉及以下几个方面:

  1. Cookie 验证:需要完整的会话 Cookie,包括 ttwid__ac_signature
  2. 参数签名a_bogus 参数是抖音的核心签名,由前端 JS 动态生成
  3. 设备指纹msTokenverifyFps_v_web_id)用于设备识别
  4. 请求头校验uifidsec-ch-ua 等头部需要与 Cookie 对应

涉及的库

  • requests:发送 HTTP GET 请求
  • 内置 JSON 解析

实现思路

整体流程如下:

1
2
分析网络请求 → 提取URL和参数 → 构造请求头 → 填充Cookie → 
发送GET请求 → 解析JSON → 提取评论内容

核心步骤是通过浏览器开发者工具(F12 Network面板)抓取真实的评论请求,然后将请求参数和头部信息完整复刻到代码中。

核心代码解析

1. 定义请求URL

1
2
3
4
import requests

# 抖音Web端评论列表接口
url = "https://www.douyin.com/aweme/v1/web/comment/list/"

2. 构造请求头

请求头是绕过抖音反爬的第一道关卡。源码中的 headers 包含了完整的浏览器指纹信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
headers = {
"authority": "www.douyin.com",
"method": "GET",
"path": "/aweme/v1/web/comment/list/",
"scheme": "https",
"accept": "application/json, text/plain, */*",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "zh-CN,zh;q=0.9",
"cookie": "ttwid=1%7CNg9hNx0-rpMm...; __ac_signature=_02B4Z6wo00f01...; ...",
"priority": "u=1, i",
"referer": "https://www.douyin.com/shipin/7270368633061197885",
"sec-ch-ua": '"Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"uifid": "4be83ecefa579a300714166db9e569bafd8689fc248d1e190e384db8df203b81...",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
}

关键头部说明:

  • referer:必须指向抖音的视频页面,服务器会验证来源
  • uifid:用户身份指纹标识,需与 Cookie 中的值一致
  • cookie:包含 ttwid(游客ID)、__ac_signature(签名)等核心字段

3. 构造请求参数

这是最关键的部分。抖音的请求参数包含大量设备信息和签名参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
params = {
"device_platform": "webapp", # 平台标识
"aid": "6383", # 应用ID
"channel": "channel_pc_web", # 渠道
"aweme_id": "7318724406165916963", # 视频ID(目标视频)
"cursor": "0", # 评论偏移量(翻页用)
"count": "20", # 每页评论数
"item_type": "0",
"update_version_code": "170400",
"pc_client_type": "1",
"version_code": "170400",
"version_name": "17.4.0",
"cookie_enabled": "true",
"screen_width": "2560",
"screen_height": "1440",
"browser_language": "zh-CN",
"browser_platform": "Win32",
"browser_name": "Chrome",
"browser_version": "137.0.0.0",
"engine_name": "Blink",
"engine_version": "137.0.0.0",
"os_name": "Windows",
"os_version": "10",
"device_memory": "8",
"platform": "PC",
"downlink": "1.25",
"effective_type": "3g",
"round_trip_time": "400",
"webid": "7496768310278981130",
# ===== 以下为签名参数 =====
"msToken": "F4T44jrnEeB6JH0ljmnhaLUUHOuaoy99JdvY488bpl3yt...", # 动态Token
"a_bogus": "QX4VhH6Jdd5nad%2FtmCbGt5OlG%2FLlNBuy01TxRaaP9xF...", # 核心签名
"verifyFp": "verify_mcd86ytp_114CZoh0_P145_411x_9k9D_FPijnA76CiMQ", # 验证指纹
"fp": "verify_mcd86ytp_114CZoh0_P145_411x_9k9D_FPijnA76CiMQ",
"x-secsdk-web-expire": "1750933212143",
"x-secsdk-web-signature": "95f0353e72b3161c834f8625ef0bffae"
}

签名参数详解:

  • aweme_id:目标视频的唯一ID,决定了要获取哪个视频的评论
  • cursor:评论分页游标,"0" 表示第一页,后续翻页使用上一页返回的 cursor
  • count:每页返回的评论数量,通常为20
  • msToken:抖音的安全令牌,由前端 JS 生成,有效期较短
  • a_bogus:抖音最核心的签名参数,基于请求参数和设备信息通过混淆算法生成
  • verifyFp:验证指纹,与 Cookie 中的 s_v_web_id 值一致
  • 设备信息参数browser_nameos_namescreen_width 等模拟真实浏览器环境

4. 发送请求与解析评论

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 发送GET请求
response = requests.get(url, headers=headers, params=params)

# 检查响应状态码
if response.status_code == 200:
# 解析JSON数据
data = response.json()

# 提取评论数据
comments = data.get("comments", [])

for comment in comments:
user = comment["user"]["nickname"] # 评论用户昵称
content = comment["text"] # 评论内容
print(f"{user}: {content}")
else:
print(f"请求失败,状态码: {response.status_code}")

这里使用 data.get("comments", []) 而不是 data["comments"],因为当请求被反爬拦截时,返回的JSON中可能不包含 comments 字段,直接取值会抛出 KeyError

5. 评论翻页

如果要获取更多评论,需要更新 cursor 参数。抖音的翻页逻辑是:每次请求返回的 JSON 中包含一个 cursor 字段,作为下一页请求的游标值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cursor = "0"
all_comments = []

while True:
params["cursor"] = cursor
response = requests.get(url, headers=headers, params=params)
data = response.json()
comments = data.get("comments", [])

if not comments:
break # 没有更多评论了

all_comments.extend(comments)
cursor = data.get("cursor", "") # 更新游标

运行效果

运行程序后,控制台输出类似如下内容:

1
2
3
4
5
6
用户A: 这个视频太有意思了哈哈哈
用户B: 博主的剪辑水平越来越好了
用户C: 求BGM名字!!
用户D: 第一次来,关注了
用户E: 这才是真正的好内容
...

共输出20条评论(第一页),如果需要更多评论则需要翻页请求。

总结与优化方向

本文基于抖音Web端评论爬虫的真实源码,详细拆解了评论接口的请求构造过程。核心难点在于 a_bogusmsToken 等签名参数的获取——这些参数由前端 JS 动态生成,无法直接在代码中模拟。

当前方案的局限性:

  1. 签名参数有效期短a_bogusmsToken 有时效性,过期后请求会失败
  2. 手动复制参数:目前需要从浏览器开发者工具中手动复制签名参数,无法自动化
  3. Cookie 过期ttwid 等Cookie也有有效期,需要定期更新

优化方向:

  1. JS逆向:通过逆向 a_bogus 的生成算法,在 Python 中直接计算签名,实现全自动化
  2. Playwright/Selenium 自动化:用浏览器自动化工具获取签名参数,绕过JS逆向
  3. 评论存储:将评论存入数据库,配合定时任务实现长期监控
  4. 情感分析:对爬取的评论文本进行NLP情感分析,挖掘用户态度
  5. 代理IP池:高频请求时使用代理IP,避免IP被封禁

抖音爬虫的难点不在于代码本身,而在于对反爬机制的理解和签名参数的获取。随着抖音反爬不断升级,纯参数硬编码的方式越来越难以维持,JS逆向和浏览器自动化是未来的主流方向。

评论
分享