> 📌 v3.1 更新:修复评论区滚动加载问题(必须滚动容器而非window),确认Draft.js输入方式(只能用keyboard.type),强调回复要自然口语化。
抖音评论区自动回复。核心逻辑:
| 模式 | 入口 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| :----: | :----: | :---- | :---- | :-------- |
| 模式A 🆕 | 个人主页→点作品→评论区 | 真实用户操作流,不易被风控 | 评论懒加载需滚动容器 | 首选 |
| 模式B | 创作者中心评论管理 | 操作直接 | 入口不同,易被检测 | 备选 |
个人主页(/user/self)
↓ 选择已发布作品(/video/{id} 或 /article/{id})
↓ 滚动到评论区→加载全部评论
↓ 从第一条开始,逐条检查
↓ 有「作者」标记? → 已回复,跳过
↓ 无「作者」标记? → 点「回复」
↓ keyboard.type 输入回复(自然口语)
↓ Enter 发送
↓ 间隔2-3秒 → 下一条
↓ 全部回完 → 下一个作品
https://www.douyin.com/user/self/video/{id}/article/{id}// 找到「全部评论」标签,滚到该位置
const all = document.querySelectorAll('*');
for (const el of all) {
if (el.textContent.includes('全部评论')) {
el.scrollIntoView({ block: 'start' });
break;
}
}
关键:评论区在一个独立滚动容器里,用 window.scrollBy 无效!
// ✅ 正确:滚动容器
const container = document.querySelector('.parent-route-container, [class*="route-scroll"]');
container.scrollTop = container.scrollTop + 80;
// ❌ 错误:window.scrollBy(0, 50) — 不会加载更多评论
完整加载循环:
for (let i = 0; i < 50; i++) {
const container = document.querySelector('.parent-route-container, [class*="route-scroll"]');
if (container) container.scrollTop = container.scrollTop + 80;
await new Promise(r => setTimeout(r, 500));
}
// 等渲染
await new Promise(r => setTimeout(r, 2000));
检查是否还有更多:
const hasLoading = document.body.innerText.includes('加载中');
const hasMore = document.body.innerText.includes('暂时没有更多评论');
// 如果没有"加载中"但有"暂时没有更多",说明全部加载完毕
核心规则:每条用户评论下面找是否有「小小程序猿 作者」文本
已回复的评论结构:
┌─ 用户名
│ 评论内容
│ 回复
│ └─ 小小程序猿 作者 ← ⚠️ 有「作者」标记
│ 回复内容
未回复的评论结构:
┌─ 用户名
│ 评论内容
│ 回复 ← ⚠️ 无「作者」
检测方法:
// 遍历所有"回复"文本元素,检查上下文中是否包含"作者"
const all = document.querySelectorAll('*');
for (const el of all) {
if (el.children.length === 0 && el.textContent.trim() === '回复') {
let p = el.parentElement;
let hasAuthor = false;
for (let j = 0; j < 8; j++) {
if (!p) break;
if ((p.textContent || '').includes('作者')) { hasAuthor = true; break; }
p = p.parentElement;
}
if (!hasAuthor) {
// 这是未回复的评论,可以回复
}
}
}
用 evaluate 直接点击:
// 找到目标用户评论下的「回复」按钮
const clicked = await page.evaluate((userName) => {
const all = document.querySelectorAll('*');
for (const el of all) {
if (el.children.length === 0 && el.textContent.trim() === '回复') {
let p = el.parentElement;
for (let j = 0; j < 8; j++) {
if (!p) break;
if ((p.textContent || '').includes(userName) && !(p.textContent || '').includes('作者')) {
el.scrollIntoView({ block: 'center' });
el.click();
return true;
}
p = p.parentElement;
}
}
}
return false;
}, '目标用户名');
Draft.js 编辑器只能用 keyboard.type 逐字输入:
// 找到Draft.js编辑框
const editor = page.locator('.public-DraftEditor-content').first();
if (await editor.isVisible().catch(() => false)) {
await editor.click();
await new Promise(r => setTimeout(r, 300));
// 用keyboard.type逐字输入(Delay模拟真人打字)
await page.keyboard.type('回复内容', { delay: 15 });
await new Promise(r => setTimeout(r, 500));
// Enter发送
await page.keyboard.press('Enter');
await new Promise(r => setTimeout(r, 3000));
}
> 已验证: document.execCommand('insertText') 对 Draft.js 不生效(编辑器不识别)。只能用 keyboard.type。
发送成功后,页面会出现 小小程序猿 作者 + 刚发的回复内容。
| 禁止 | 原因 |
|---|---|
| :---: | :------ |
| 每条回复句式相同 | 被检测为批量自动化 |
| 连续快速发送 | 每回复1条间隔至少2-3秒 |
| 太官方/太AI感 | "让我们一起…""在这个世界上…""替它们谢谢你🙏" |
| 每条都带🙏🐾表情 | 显得很模板化 |
❌ 太官方:"谢谢你的关注🙏流浪的它们需要更多善良的人"
✅ 自然:"你也喜欢小动物呀,谢谢你的关注"
❌ 太官方:"感谢留言🐾愿每个小生命都能被善待"
✅ 自然:"看到这种场景真的挺揪心的,希望它们都好"
❌ 太官方:"替流浪的毛孩子谢谢你!希望它们都能找到家🙏"
✅ 自然:"你的名字好可爱!替它们谢谢你啦"
关键原则:
| 评论者特点 | 回复示例 |
|---|---|
| :---------- | :--------- |
| 名字有趣的 | "哈哈哈你这名字" / "名字好可爱" |
| 评论有内容的 | 针对内容回(如"立法保护动物"→"说的对,确实该立法了") |
| 评论为空/表情 | 简单回一句"谢谢支持" / "感谢关注" |
| 明显很走心的 | 认真回一两句,不要敷衍 |
⏱ 点「回复」→ 等1-2秒
⏱ keyboard.type 输入 → 0.5秒
⏱ Enter发送 → 等2-3秒
⏱ 下一条 → 等1-2秒
⏱ 每5条休息5-10秒
入口:https://creator.douyin.com/creator-micro/interactive/comment
| 问题 | 表现 | 根因 | 修复 |
|---|---|---|---|
| :---- | :---- | :---- | :---- |
| 评论加载不出来 | 翻到底还是只有5条评论 | window.scrollBy 无效 | 必须用容器 container.scrollTop += 80 |
| 容器选择器 | 找不到正确的滚动元素 | 页面结构有多个可滚动容器 | 用 .parent-route-container 或 [class*="route-scroll"] |
| 刷到底了还在转 | "加载中"一直显示 | 已到懒加载上限 | 检查页面是否有"暂时没有更多评论" |
| 问题 | 表现 | 根因 | 修复 |
|---|---|---|---|
| :---- | :---- | :---- | :---- |
| execCommand无效 | 文字没输入 | Draft.js不识别execCommand | 只能用 keyboard.type |
| 回复太官方 | 读者觉得是机器人 | 模板化回复 | 每条都不一样,像真人聊天 |
| 找不到回复按钮 | 回复按钮在视口外 | 没先滚到评论位置 | 用 el.scrollIntoView({block:'center'}) |
/video/{id} 或 /article/{id})共 4 个版本