抖音Web端评论无法直接抓取,因需动态参数、登录态及设备指纹,常规requests失效;唯一稳定方式是用Playwright模拟浏览器并复用人工登录Cookie,配合滚动加载与三元组去重。

抖音Web端的评论数据无法直接通过公开API获取,所有“抓取评论”的尝试都面临反爬机制、登录态校验、加密参数和频率限制——这意味着常规 requests + BeautifulSoup 方式在当前(2024年中)已基本失效,强行模拟请求极易触发滑块验证或返回空数据。
为什么直接 requests.get(‘https://www.douyin.com/video/xxx’) 拿不到评论?
抖音Web端评论接口(如 /web/api/v2/comment/list/)要求携带有效的 msToken、browser_language、verifyFp 等动态参数,且多数参数与设备指纹强绑定;同时请求头中 Referer、User-Agent、Cookie(尤其是 sessionid)必须匹配登录态。未登录时返回 {"status_code": 10201, "status_msg": "用户未登录"};参数失效则返回 {"status_code": 0, "comments": []} 或直接 403。
- 评论数据实际由前端 JS 动态加载,HTML 源码里不包含任何评论文本
-
verifyFp和_signature是关键签名参数,硬编码或静态生成会立即失效 - 即使绕过登录,IP 频率超过约 3–5 次/分钟就会被限流,返回
429 Too Many Requests
可行路径:用 Playwright 模拟真实浏览器行为
唯一稳定获取 Web 端评论的方式是启动真实浏览器环境,复用人工登录后的 Cookie,并让 JS 正常执行滚动加载逻辑。Playwright 支持保存/加载上下文,可规避重复扫码登录。
- 先手动登录抖音 Web 端(
https://www.douyin.com),打开开发者工具 → Application → Cookies,复制全部 Cookie 字符串 - 用 Playwright 启动 Chromium,调用
context.add_cookies()注入 Cookie,再访问视频页 - 用
page.wait_for_selector()等待评论区 DOM 加载,再用page.evaluate()提取document.querySelectorAll('.comment-item')中的文本、时间、用户ID - 每滚动一次后等待新评论节点出现,避免重复提取;建议设置
max_comments = 200上限,防止无限加载
示例关键片段:
立即学习“Python免费学习笔记(深入)”;
from playwright.sync_api import sync_playwright
<p>with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context()</p><h1>注入你手动复制的 Cookie 列表(dict 格式)</h1><pre class="brush:php;toolbar:false;">context.add_cookies(your_cookie_list)
page = context.new_page()
page.goto("https://www.douyin.com/video/xxxxx")
page.wait_for_selector(".comment-list", timeout=10000)
comments = page.evaluate("""
() => Array.from(document.querySelectorAll('.comment-item')).map(el => ({
text: el.querySelector('.comment-content')?.innerText,
user_id: el.querySelector('a')?.href?.match(/user\/([^/?]+)/)?.[1],
time: el.querySelector('.comment-time')?.innerText
}))
""")
去重存储的关键:用 (user_id, text_md5, timestamp_floor) 三元组判重
单纯按评论文本去重不可靠——用户可能发相同内容多次,或带空格/换行差异;仅按 user_id 去重又会漏掉不同人发的相同评论。更稳妥的是组合判重:
-
text_md5:对清洗后的文本(去除首尾空格、统一换行符、转小写)取hashlib.md5().hexdigest() -
timestamp_floor:将原始时间截断到小时级(如"2024-06-15 14:30:22"→"2024-06-15 14"),避免同一用户秒级重复发言被误判为新评论 - 存入 SQLite 时,对
(user_id, text_md5, timestamp_floor)建唯一索引,插入前用INSERT OR IGNORE
不要依赖视频 ID + 评论 ID 做主键——抖音 Web 端返回的评论 ID(如 "cid:xxxx")不是全局唯一,不同视频可能出现相同 cid。
真正难的不是代码怎么写,而是维持 Cookie 有效期(通常 7–30 天)、应对不定期的前端结构变更(比如某天 .comment-item 类名突然变成 .CommentItem),以及处理大量视频时的 IP 轮换与请求间隔控制。这些没法靠一个脚本一劳永逸。



















