2026/10/22 13:14:58

草稿箱里躺着 18 篇孤儿:发布流水线只管发,不管收尾

草稿箱里躺着 18 篇孤儿:发布流水线只管发,不管收尾 草稿箱里躺着 18 篇孤儿发布流水线只管发不管收尾补发任务跑完我去 51CTO 创作中心看了一眼草稿箱计数上写着18。点进去只看得到 10 条——列表本身也只给第一页这是另一个故事先按下不表。这看得见的 10 条里没有一篇是我真正想留的全是「发布到一半没发成」留下的残骸同一篇稿子发到 6 个平台为什么只有这里的图片全裂了 2100231 01:39 同一篇稿子发到 6 个平台为什么只有这里的图片全裂了 2100229 01:34 同一篇稿子发到 6 个平台为什么只有这里的图片全裂了 2100227 01:32 同一篇稿子发到 6 个平台为什么只有这里的图片全裂了 2100224 01:28 同一篇稿子发到 6 个平台为什么只有这里的图片全裂了 2100220 01:17 把「一文多发」做成脚本流水线CDP、滑块、二维码… 2100232 01:41 把「一文多发」做成脚本流水线CDP、滑块、二维码… 2100230 01:36 把「一文多发」做成脚本流水线CDP、滑块、二维码… 2100225 01:30 把「一文多发」做成脚本流水线CDP、滑块、二维码… 2100222 01:18 把 1242 条法规做成离线可核查的知识库一个基层执法场景… 2097267 10-12两篇稿子九份拷贝。同一篇最多留下了5 个副本标题一模一样内容一模一样创建时间相差不到半小时——那半小时我在反复重跑同一个脚本。更麻烦的是它们不会自己消失而我又不太敢删。这篇文章讲的是发布流水线里那个从来没人管的部分——失败之后留下的东西。一、我做了什么怎么做到了 18 篇事情很简单。我要把 20 篇存量稿子补发到各个平台写了个批量脚本逻辑是打开发布页填标题粘正文点发布看结果失败就重跑前三步每次都成功。第四步有一半概率失败原因另说于是我重跑。问题在于第 1 步「打开发布页」本身就有副作用。51CTO 的发布页在标题填进去的那一刻就会自动建一个草稿不管你最后发不发得出去。脚本重跑一次就多一个草稿。那两篇我一共重跑了 9 次一次都没成功。所以目标 2 篇 × 重跑 9 次 草稿 9 份 加上 10 月 12 日那篇没发出去的 10 份 页面计数 18 → 还有 8 份在第二页我没看到这个账是我事后才对上的。跑的过程中我完全没意识到因为脚本的输出里没有任何一行提到草稿数量——它只打印「DONE」。二、三种不同的孤儿清点的时候我发现这些残骸不是同一种东西处理起来的难度也完全不同。1. 失败残留内容完整只是没提交最常见的一种。标题有、正文有、封面没选、标签 0 个、分类没选。这类最好办理论上重新打开点一下发布就行。但实际上我从草稿箱进去又试了一次发布面板照样打不开这个问题另一篇单独讲。所以它们就一直躺着。2. 空壳有标题没正文掘金那边留下过一个。原因是我取草稿 URL 的时候取错了脚本输出里有一行DRAFT_URL指向drafts/new我拿它去发发的是一篇刚建的空白草稿。真正的草稿 ID 在输出末尾的另一行 URL 里。等我反应过来草稿箱里已经多了一个空壳。空壳的问题在于它长得跟正常草稿一模一样。列表页看标题是有的因为标题是脚本设上去的只有点进去才发现正文是空的。批量清理的时候如果只看标题很容易把「有价值但未发布」的和「空壳」一起删掉。3. 重复副本同一篇的五份拷贝同一篇稿子五次重跑五个草稿。标题完全相同。这类最烦人因为你没法从列表页判断哪个是「最新的」。五个创建时间相差半小时但内容可能因为中途改过稿而略有不同。要清理就得一个个点进去比对。而且列表页给的时间只精确到分钟同一分钟建的两份我确实遇到过在列表上完全无法区分。三、为什么清理比发布难我的第一反应是写个清理脚本把标题重复的都删掉。写完一半停下来了因为发现清理这事儿有三个发布时没有的风险。风险一你看到的列表是不完整的51CTO 创作中心的列表页一页 10 条分页控件点了不换页真实鼠标点、坐标算对了、没遮挡就是不换。博客园后台、腾讯云后台同样。也就是说我看到的 18 篇可能只是前 8 篇后面还有多少不知道。在这种基础上写「批量删除」等于蒙着眼睛挥刀。后来我是靠归档页和站内接口才拿到全量的这是另一个话题。但结论先放在这里在你确认能拿到全量列表之前不要写任何带删除动作的脚本。风险二删除要过二次确认模态框本身就是个坑delete 按钮点下去会弹确认框确认框里的「确定」按钮位置每次都可能不一样有的平台居中有的靠右有的在浮层里带动画。我在这上面翻过车脚本连续点了两次「确定」第二次点在了刚弹出来的新浮层上把另一篇不该删的删了。虽然那次删的是空壳但我后背发凉。风险三删错了不可恢复发布失败最坏的结果是稿子没发出去重跑一次就行。删除失败最坏的结果是稿子没了。这两个错误的代价完全不对称。所以在没有回收站、没有版本历史的平台上批量删除必须留一步人工确认。四、我现在用的三条规则踩完这些坑我把清理流程改成了下面三条。都很土但没有一条是多余的。规则一发布成功才允许留草稿失败立刻打标记脚本里加了这么一段发布判据没通过就把这次建的草稿 ID 记进一个orphans.txt。# orphans.txt —— 每行平台 草稿ID 标题 时间 51cto 2100231 同一篇稿子发到 6 个平台… 2026-10-17 01:39 51cto 2100232 把「一文多发」做成脚本流水线… 2026-10-17 01:41不删只记。删的事留到人清醒的时候做。这样改之后有个意外好处下次重跑之前脚本可以先读这个文件跳过已经有残留的稿子草稿箱就不会再涨了。规则二动手之前先查草稿箱别急着新建原流程的第 1 步是「打开发布页」现在改成先按标题指纹查一遍草稿箱有就直接打开那个草稿编辑没有才新建标题指纹不用太复杂取标题前 12 个字做包含匹配就够了。中文标题前 12 字重复的概率很低够用。这条规则把「重跑 1 草稿」变成了「重跑 复用草稿」草稿箱立刻就不涨了。规则三清理脚本必须带 dry-run且默认就是 dry-runnodecleanup.js--platform51cto# 只列清单不删nodecleanup.js--platform51cto--apply# 真的删默认的那个命令输出长这样[清单] 共 21 条按标题去重后 9 组 组1 (x5) 同一篇稿子发到 6 个平台… → 保留最新 2100231建议删 4 组2 (x4) 把「一文多发」做成脚本流水线… → 保留最新 2100232建议删 3 组3 (x1) 滑块验证码为什么总拖不动… → 无重复不动 ... [未执行] 加 --apply 才会真的删关键不是「保留最新」这个策略有多聪明而是清单先出来人先看一遍。我第一版脚本直接删删到第三个的时候发现有个组里最新的那篇反而是空壳因为最后一次跑的时候正文没粘进去保留策略选错了。五、清理动作的实际顺序如果你也有一堆孤儿草稿要收拾我建议的顺序是先想办法拿到全量列表别信分页。归档页、站内接口、带后缀的作者页三条路至少走通一条。导出清单到文件标题 ID 创建时间 正文长度正文长度能一眼挑出空壳。人工过一遍标出「要留的」「要删的」「不确定的」。不确定的一律不动。按组删一次一组删完立刻重新导出清单核对数字是不是少了预期的那么多。数字不对就停。留 10% 不删。听起来很蠢但等你哪天发现某篇「重复副本」其实是改过稿的版本你会感谢这一步。六、这件事真正的教训发布脚本写久了会形成一种思维定式关注「成功没成功」不关注「留下了什么」。退出码 0、日志没有 ERROR、作者页文章数 1 —— 这三样齐了我就认为这次发布是干净的。但事实上同一次运行可能在三个地方留下了痕迹草稿箱多了一个、标签框多了几个脏标签、剪贴板被覆盖了。这些痕迹单个都不致命堆起来就会反噬草稿箱涨到 18 篇之后我连「哪篇发过了」都判断不出来只能靠记忆。而记忆是靠不住的。所以现在我的发布脚本最后一步不是打印 SUCCESS而是打印这次运行产生的副作用清单。哪怕清单是空的也要打印出来。空清单本身就是一个有价值的断言它证明这次运行没有留下东西。补一句结尾。我现在还没删那 18 篇因为全量列表还没拿到手。等拿到了再动手——按第四节的规则一次一组删完核对。急事慢做尤其是不可逆的事。