每天替你刷一轮抖音,挑出值得看的写成日报
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Xia28zhi/dsh-douyin-scroll该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · tool
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 10 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 96 处,展示前 73 条)
- 读取本地文件index.js:91
try { myVer = String(JSON.parse(readFileSync(join(pluginDir, 'package.json'), 'utf8')).version || '') } catch { myVer = '' } - 写入本地文件index.js:166
try { appendFileSync(logFile, `${new Date().toISOString()} ${m}\n`, 'utf8') } catch { } - 读取本地文件index.js:170
if (existsSync(logFile) && statSync(logFile).size > 2_000_000) { - 读取本地文件index.js:170
if (existsSync(logFile) && statSync(logFile).size > 2_000_000) { - 写入本地文件index.js:171
try { renameSync(logFile, logFile + '.1') } catch { } - 读取本地文件index.js:184
if (!existsSync(cfgFile)) { - 读取本地文件index.js:238
if (!existsSync(dir)) return - 读取本地文件index.js:240
for (const f of readdirSync(dir)) { - 删除本地文件index.js:243
if (statSync(p).isFile() && statSync(p).mtimeMs < cut) { unlinkSync(p); n++ } - 写入本地文件index.js:390
try { writeFileSync(file, yml.join('\n'), 'utf8'); return file } catch (e) { log(`写 overlay 失败:${e?.message ?? e}`); return null } - 写入本地文件index.js:482
if (existsSync(f)) appendFileSync(f, block + '\n', 'utf8') - 写入本地文件index.js:483
else writeFileSync(f, `# 刷抖音 · ${dayKey()} —— 这一轮被中止\n${block}\n`, 'utf8') - 写入本地文件index.js:496
writeFileSync(f, [ - 执行外部命令来自配置/变量index.js:750
const child = spawn(spawnCmd, args, { - 发起网络请求client.js:37
const jget = async (p) => asJson(await fetch(API + p, { credentials: 'same-origin' })) - 发起网络请求client.js:45
const jpost = async (p, body) => asJson(await fetch(API + p, { - 读取本地文件lib/hostdeps.mjs:34
for (const n of readdirSync(join(npm, '@deepseek-ai'))) push(join(npm, '@deepseek-ai', n, 'node_modules', '@deepseek-ai')) - 读取本地文件lib/hostdeps.mjs:45
for (const p of readdirSync(join(dshHome, 'profiles'))) push(join(dshHome, 'profiles', p, 'node_modules', '@deepseek-ai')) - 读取本地文件lib/hostdeps.mjs:57
if (!existsSync(pkgFile)) return null - 读取本地文件lib/hostdeps.mjs:58
const pkg = JSON.parse(readFileSync(pkgFile, 'utf8')) - 读取本地文件lib/hostdeps.mjs:63
return existsSync(file) ? pathToFileURL(file).href : null - 读取本地文件lib/browser.mjs:41
const j = JSON.parse(readFileSync(this.runtimeFile, 'utf8')) - 写入本地文件lib/browser.mjs:48
writeFileSync(this.runtimeFile, JSON.stringify({ port: this.port, mode: this.mode, at: new Date().toISOString(), ...extra }, null, 2), 'utf8') - 读取本地文件lib/browser.mjs:208
try { return existsSync(join(this.userDataDir, 'Default', 'Cookies')) } catch { return false } - 写入本地文件lib/douyin.mjs:326
writeFileSync(file, Buffer.from(shot.data, 'base64')) - 写入本地文件lib/state.mjs:45
mkdirSync(dir, { recursive: true }) - 读取本地文件lib/state.mjs:111
try { return JSON.parse(readFileSync(file, 'utf8')) } catch { return fallback } - 写入本地文件lib/state.mjs:122
writeFileSync(tmp, JSON.stringify(value, null, 2), 'utf8') - 写入本地文件lib/state.mjs:123
try { renameSync(tmp, file) } catch { try { copyFileSync(tmp, file) } catch { return false } } - 写入本地文件lib/state.mjs:123
try { renameSync(tmp, file) } catch { try { copyFileSync(tmp, file) } catch { return false } } - 读取本地文件lib/state.mjs:141
const readIf = (f) => { try { return readFileSync(f, 'utf8') } catch { return '' } } - 读取本地文件lib/state.mjs:143
if (!existsSync(shipped)) { log(`缺文件:${shipped}`); return } - 读取本地文件lib/state.mjs:145
const newText = readFileSync(shipped, 'utf8') - 读取本地文件lib/state.mjs:148
if (!existsSync(home)) { - 写入本地文件lib/state.mjs:149
writeFileSync(home, newText, 'utf8'); writeFileSync(ledger, hShip, 'utf8') - 读取本地文件lib/state.mjs:153
const hHome = sha(readFileSync(home, 'utf8')) - 写入本地文件lib/state.mjs:155
if (hLast !== hShip) writeFileSync(ledger, hShip, 'utf8') - 读取本地文件lib/outbox.mjs:29
if (!existsSync(f)) return [] - 读取本地文件lib/outbox.mjs:31
for (const line of readFileSync(f, 'utf8').split(/ ? /)) { - 写入本地文件lib/outbox.mjs:43
writeFileSync(tmp, list.map((o) => JSON.stringify(o)).join('\n') + '\n', 'utf8') - 写入本地文件lib/outbox.mjs:44
renameSync(tmp, f) - 写入本地文件lib/outbox.mjs:68
writeFileSync(f, line, { encoding: 'utf8', flag: 'a' }) - 写入本地文件lib/outbox.mjs:98
writeFileSync(fileOf(home), JSON.stringify(item) + '\n', { encoding: 'utf8', flag: 'a' }) - 发起网络请求lib/vision.mjs:57
const res = await fetch(cand.base + '/chat/completions', { - 读取本地文件lib/vision.mjs:110
const b64 = readFileSync(f).toString('base64') - 发起网络请求lib/vision.mjs:129
const res = await fetch(c.base + '/chat/completions', { - 读取本地文件lib/cdp.mjs:29
if (env && existsSync(env)) return env - 读取本地文件lib/cdp.mjs:46
for (const p of cands) if (p && existsSync(p)) return p - 发起网络请求lib/cdp.mjs:53
const r = await fetch(`http://127.0.0.1:${port}/json/version`, { signal: AbortSignal.timeout(timeout) }) - 执行外部命令来自配置/变量lib/cdp.mjs:212
const proc = spawn(browser, args, { windowsHide: true, stdio: 'ignore', detached: true }) - 发起网络请求lib/cdp.mjs:221
const r = await fetch(`http://127.0.0.1:${port}/json/version`) - 发起网络请求lib/cdp.mjs:249
export async function attachPage({ port = 9333, url = '' } = {}) { const list = await (await fetch(`http://127.0.0.1:${port}/json/list`)).json() - 发起网络请求lib/cdp.mjs:261
const created = await (await fetch(`http://127.0.0.1:${port}/json/new?${encodeURIComponent(url)}`, { method: 'PUT' })).json() - 发起网络请求lib/cdp.mjs:268
try { await fetch(`http://127.0.0.1:${port}/json/close/${id}`) } catch { } - 写入本地文件lib/guard.mjs:88
mkdirSync(join(dir, 'frames'), { recursive: true }) - 写入本地文件lib/guard.mjs:94
writeFileSync(file, Buffer.from(b64, 'base64')) - 写入本地文件lib/guard.mjs:98
writeFileSync(join(dir, `abort-${stamp}.json`), JSON.stringify(rec, null, 2), 'utf8') - 写入本地文件lib/guard.mjs:99
writeFileSync(join(dir, 'abort-latest.json'), JSON.stringify(rec, null, 2), 'utf8') - 写入本地文件lib/mcp-server.mjs:41
const log = (m) => { try { appendFileSync(join(HOME, 'duty.log'), `${new Date().toISOString()} [mcp] ${m}\n`, 'utf8') } catch { } } - 读取本地文件lib/mcp-server.mjs:218
if (mode === 'append' && existsSync(f)) { - 读取本地文件lib/mcp-server.mjs:219
const prev = readFileSync(f, 'utf8') - 写入本地文件lib/mcp-server.mjs:225
writeFileSync(f, replaced, 'utf8') - 写入本地文件lib/mcp-server.mjs:228
writeFileSync(f, prev.replace(/ *$/, '') + '\n\n' + md + '\n', 'utf8') - 读取本地文件lib/mcp-server.mjs:231
if (mode === 'overwrite' && existsSync(f)) { - 读取本地文件lib/mcp-server.mjs:232
try { writeFileSync(f + '.bak', readFileSync(f, 'utf8'), 'utf8') } catch { } - 写入本地文件lib/mcp-server.mjs:232
try { writeFileSync(f + '.bak', readFileSync(f, 'utf8'), 'utf8') } catch { } - 写入本地文件lib/mcp-server.mjs:234
writeFileSync(f, md, 'utf8') - 读取本地文件lib/mcp-server.mjs:257
reportExists: existsSync(join(HOME, 'out', `${dayKey()}.md`)), - 写入本地文件lib/ocr.mjs:66
try { mkdirSync(dir, { recursive: true }) } catch { } - 读取本地文件lib/ocr.mjs:67
if (!existsSync(png)) return { ok: false, text: '', error: '图不存在:' + png } - 写入本地文件lib/ocr.mjs:71
try { copyFileSync(png, ascii) } catch (e) { return { ok: false, text: '', error: '复制临时图失败:' + String(e?.message ?? e) } } - 写入本地文件lib/ocr.mjs:74
try { writeFileSync(ps1, PS1, 'utf8') } catch (e) { return { ok: false, text: '', error: '写 OCR 脚本失败:' + String(e?.message ?? e) } } - 执行外部命令固定命令lib/ocr.mjs:78
execFile('powershell', args, { encoding: 'utf8', timeout: 60_000, windowsHide: true, maxBuffer: 4 * 1024 * 1024 }, (err, stdout) => {
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/dsh-tools给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
DSH 插件:每天替你看抖音,写成日报,评论带真 @(点开下拉选人)、分享视频给好友/群
README
由 DeepSeek 最新模型翻译生成刷抖音 · dsh-douyin-scroll
DSH 插件:每天替你刷一轮抖音 —— 按关键词 / 关注 / 热榜 / 指定博主去刷,截画面看内容,挑出值得的写成日报。 你收到的每一条,都是它先看过一遍的。
先看三行
- 需要机器上有个 Edge 或 Chrome(不下载 Chromium,也不装 playwright),以及 dsh ≥ 0.1.7。
- 装完必须重启一次 dsh(插件在 bundle 层组装);然后进 设置 → 刷抖音 点一次「登录抖音」。
- 会动你账号的(自动收藏、评论 @ 你)默认全关;要花钱的(视觉模型)默认关。
它做什么
去哪刷(设置页可开关,可多选)
| 来源 | 说明 |
| 关键词搜索 | 按你填的词搜最近作品;留空用默认组(AI / 编程 / 效率工具 / 摄影 / 健身) |
| 关注列表 | 你关注的人最近发了什么 |
| 热榜 | 今天什么在火,挑相关的词再搜下去 |
| 指定博主 | 填主页链接,逐个看新作品 |
| 推荐流 | 抖音推给你的(默认关) |
怎么判(三层,逐层加码)
1. 元数据:标题 / 文案 / 话题 / 作者 / 时长 / 点赞评论收藏数 —— 快筛,广告标题党直接跳。
2. 画面文字(OCR):抖音没有字幕接口,画面里的字常常就是这条视频的全部信息。用 Windows 自带 OCR,零依赖。
展开完整文档(README 剩余 1 节)
刷抖音 · dsh-douyin-scroll DSH 插件:每天替你刷一轮抖音 —— 按关键词 / 关注 / 热榜 / 指定博主去刷,截画面看内容,挑出值得的写成日报。 你收到的每一条,都是它先看过一遍的。 先看三行 - 需要机器上有个 Edge 或 Chrome(不下载 Chromium,也不装 playwright),以及 dsh ≥ 0.1.7。 - 装完必须重启一次 dsh(插件在 bundle 层组装);然后进 设置 → 刷抖音 点一次「登录抖音」。 - 会动你账号的(自动收藏、评论 @ 你)默认全关;要花钱的(视觉模型)默认关。 它做什么 去哪刷(设置页可开关,可多选) | 来源 | 说明 | | 关键词搜索 | 按你填的词搜最近作品;留空用默认组(AI / 编程 / 效率工具 / 摄影 / 健身) | | 关注列表 | 你关注的人最近发了什么 | | 热榜 | 今天什么在火,挑相关的词再搜下去 | | 指定博主 | 填主页链接,逐个看新作品 | | 推荐流 | 抖音推给你的(默认关) | 怎么判(三层,逐层加码) 1. 元数据:标题 / 文案 / 话题 / 作者 / 时长 / 点赞评论收藏数 —— 快筛,广告标题党直接跳。 2. 画面文字(OCR):抖音没有字幕接口,画面里的字常常就是这条视频的全部信息。用 Windows 自带 OCR,零依赖。 3. 画面理解(视觉模型,可选):填一个多模态接口让它"看图说话"。⚠️ 默认模型 deepseek-flash 是纯文本的、看不了图,所以这一层由插件在宿主侧把画面翻译成文字再交给值班模型 —— 模型换谁来都跑得动。 产出什么 - out/<日期>.md 日报:每条含「为什么值得」+「它自己的一句话」+「画面里看到的」+ 链接。 长这样(示例,内容是编的,格式是真的): 今天刷了 34 条,挑出 3 条 74xxxxxxxxxxxxxxxx · 用 200 行把 CDP 玩明白了作者 某某 · 06:12 · ❤ 1.2万 💬 340 ⭐ 890 - 为什么值得:把协议层讲清楚了,不是念文档。 - 它自己的一句话:「你不需要 playwright,浏览器本来就是可以被远程操控的。」 - 画面里看到的:白板画了 WebSocket 帧结构,讲了 Target 和 Session 的关系。 - https://www.douyin.com/video/74xxxxxxxxxxxxxxxx - 可选自动收藏、可选评论 @ 你(都要你自己开)。 什么时候跑:谷时自动(工作日 12–14 点、18 点后及整个周末)/每日固定时间/开 dsh 时补跑/设置页「现在跑一轮」。 装 三种,选一种。装完一定重启一次 dsh,设置页里才会出现「刷抖音」。 | 你手上是什么 | 命令 | | 想直接装最新版 | dsh plugin --profile desktop add github:Xia28zhi/dsh-douyin-scroll | | 从 Release 下了 dsh-douyin-scroll-1.4.14.tgz(推荐,最稳) | dsh plugin --profile desktop add "E:\完整路径\dsh-douyin-scroll-1.4.14.tgz" --registry=https://registry.npmmirror.com | | 下了 -clean.zip,或想改代码 | 解压出 dsh-douyin-scroll\ 目录,再 dsh plugin --profile desktop add link:"E:\完整路径\dsh-douyin-scroll" | --profile 换成你真在用的那个(桌面版一般就是 desktop,老版 Web 是 web)。link: 指向目录,别删那个目录。 国内拉依赖要带 --registry=https://registry.npmmirror.com。 更细的说明(含「只有 zip 没有命令行」「一键装 .cmd」「卸载」):见 INSTALL-怎么装.md。 进 设置 → 刷抖音: 1. 登录抖音 —— 点一下会开一个浏览器窗口,在里面扫码。登录态存在插件自己的浏览器 profile 里, 跟你现在用的浏览器完全隔离,重启也在。 2. 测一下 —— 它会真跑一遍:登录 → 搜索 → 热榜 → 关注 → 截帧,直接回答"能不能用"。 3. 勾上想刷的来源、定好每天挑几条,然后点现在跑一轮。 它是怎么干活的(想改代码看这里) host(插件本体) 值班那一轮(headless 会话) ├─ 养一台浏览器(Edge/Chrome + CDP) │ ├─ 定时器:谷时 / 每日 / 开 dsh 补跑 │ spawn dsh --profile headless --patch overlay <prompt> ├─ HTTP /api/douyin-duty/(设置页) │ │ └─ 一轮结束后:按 picks.json 收藏/评论 ────┼───────────┴─ overlay 挂 @deepseek-ai/dsh-mcp-client │ └─ 起 lib/mcp-server.mjs(本插件自带) └─ 模型手里的 12 个工具全从这里来 - 不用签名:在已登录的页面上下文里 fetch 同源接口就能拿到数据(实测 search/item、tab/feed、 aweme/post、aweme/detail、follow/feed、hot/search/list 全部 status_code=0)。 不去逆向 a\_bogus,也不引 playwright —— 数据层和截帧都走 CDP。 - 模型没有「收藏 / 评论」这两只手:MCP 工具白名单里就没注册,它连名字都看不到。 真动手的是宿主,在一轮结束后按 picks.json + 开关执行,条数由上限说了算。 目录 | 文件 | 职责 | | index.js | host 半端:配置、HTTP 接口、定时器、跑一轮、一轮后的收藏/评论 | | client.js | 浏览器半端:设置页那一页 | | lib/cdp.mjs | 极简 CDP 客户端(Node 22 自带 WebSocket,零依赖) | | lib/browser.mjs | 浏览器会话(一台常驻、独立 profile) | | lib/douyin.mjs | 数据层:各来源抓取 + 截帧 | | lib/ocr.mjs | Windows 内置 OCR | | lib/vision.mjs | 视觉模型(OpenAI 兼容接口) | | lib/act.mjs | 收藏 / 评论(默认关,走真实 UI 点击) | | lib/mcp-server.mjs | 给值班那一轮的 MCP 服务端(工具白名单 = 安全边界) | | prompts/duty.md | 值班章程(判定口径 + 红线),你可以改,改了不会被覆盖 | 数据都在哪 $DSH_HOME/douyin-duty/:config.json(配置权威)/ state.json / seen.json / picks.json / out/<日期>.md / frames/ / duty.md / duty.log / browser/(浏览器 profile)。 不写进插件包目录。 不装 dsh 也能验 bash node tools/selftest.mjs # 起浏览器 → 查登录 → 挨个跑接口 → 截一帧 node tools/mcp-probe.mjs # 真跑一遍 MCP 服务端(模拟值班那一轮拿工具) 已知边界 - 抖音随时可能改版 / 加风控。哪天某个来源失效了,duty.log 和「测一下」会先告诉你,不是静默失败。 - 截帧是真播一遍视频,一条 15–20 秒。所以只对过了快筛的用,一轮别超过十条。 - 视觉模型要花钱,按张计费;不开也能跑(靠元数据 + OCR)。 - 收藏 / 评论靠真实 UI 点击,抖音改版后可能点不到 —— 失败了会写进日志,不会自作主张重试。 ⚠️ 第一次建议先不开,等你看过两轮日报的风格再决定。 许可证 MIT。架构与若干抗坑做法参考了 dsh-bili-scroll(同为 MIT), 详见 NOTICE.md。 免责 这是个人自用的自动化小工具,不是官方产品。它通过你本机的浏览器去操作抖音网页版,因此: - 可能违反抖音的用户协议,账号风险(限流、验证码、封禁)由使用者自负; - 会动你账号的功能(自动收藏、评论带 @、分享给好友/群)默认全关,开了就是拿你的号在说话,请自己掂量; - 视觉模型那层要花钱且会把画面发给第三方接口,默认关闭; - 代码按 MIT 提供,不含任何担保。 本仓库不含任何账号数据;$DSH_HOME/douyin-duty/ 里的登录态、日报、发件账本都在你机器上,不会自动上传。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Xia28zhi/dsh-douyin-scroll
每天替你刷一轮抖音,挑出值得看的写成日报
相关插件 · 工具 / 效率
破甲管控台kingcharleslzy-ai/dsh-purge
dsh-purge Community · DeepSeek Harness 社区维护版:宿主兼容、状态诊断、提示词管理、更新与本机备份回滚。基于小杨 / YuJunZhiXue 的 dsh-purge。
★ 4,330已汉化DeepSeek 客户端
74.5
网文长卷lingfengQAQ/webnovel-writer
基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200…
★ 7,636已汉化DSH
72.2
多智能体协作HKUDS/AutoSwarm
AutoSwarm: Unify Your Agents. Unify Your Context (Codex · Claude Code · DeepSeek Harness · Muse · Grok · WorkBuddy· nanobot · and more)
★ 2,349已汉化DSH
71.6
Vox 拼贴视频生成Alisa0808/vox-director
🎬 Vox Director拼贴动效导演
★ 2,129已汉化DSH
71.4
Agent 演化引擎Q00/ouroboros
智能体 OS:智能体自己变聪明,我们只守住底线:面试准入、分阶段评估、带预算的进化循环。MCP 服务器,14 种运行时:Claude Code、Codex CLI、Gemini CLI、OpenCode、Copilot、Kiro 等。
★ 6,311已汉化DSH
71.4
智能体运行框架路由HarnessRouter/harnessrouter
智能体 harness 的统一接口。
★ 3,984已汉化DSH
71.3
这是你的仓库?认领条目