一次看似简单的批量操作
这次遇到的事情很具体:把 2026 年 1 月 1 日以前发布的一批视频,统一改成“仅自己可见”。表面看,它像是一项重复劳动,找到视频、点开设置、保存,再处理下一条。目标也很清楚,似乎只要足够快,很快就能结束。
但真正开始以后,我很快发现,批量操作最危险的地方,恰恰是它看起来太简单。内容数量超过 1,000 条,任何一次筛选错误、重复点击或状态误判,都会被放大成一串错误。更麻烦的是,平台并不总会及时返回明确结果。一次点击没有反馈,到底是没有执行,还是已经执行但页面没有告诉我?如果不把这个问题处理清楚,后面每一次重试都可能把不确定性继续扩大。
批量任务的目标不是把所有按钮点完,而是让每一条结果都能被解释、被恢复。
先承认工具的边界
我一开始先找现有的执行入口,而不是马上写一套新的流程。检查之后发现,现有工具没有“某个日期以前”的筛选条件,只能按月份取数据。这是一个看起来不方便、实际上很重要的边界。
如果忽略这个边界,直接把“2026 年以前”当成一个整体交给脚本,脚本要么拿不到正确的目标集合,要么只能依赖页面当时返回的顺序。前者会漏处理,后者会让每次重跑都可能拿到不同内容。尤其在内容状态会变化的场景里,不能把一个自然语言条件想当然地当成工具已经支持的参数。
所以我没有先追求“一次完成”,而是把日期范围拆成稳定的月份边界。这样做的理由很简单:月份是现有工具能理解的筛选单位,也是之后记录进度时最容易核对的单位。目标范围没有变,执行颗粒度变得可控了。
先做只读统计,再生成任务
真正执行前,我先同步了一遍内容列表,只读统计目标集合。系统当时看到总量是 2,635 条,符合条件、仍然公开的目标数量是 1,128 条。这个数字不是为了让过程显得专业,而是为了给后面每一步提供一个参照。
接着,我把目标按月份拆成 44 个任务,每个任务都有自己的月份范围和预期数量。这样在执行过程中,我可以知道当前处理的是哪一批,也能判断某一批返回的数量是否异常。只读阶段的价值,是先确认“要改什么”,再允许流程进入“去修改”。
这一步也改变了我对批量自动化的理解。很多人把 dry-run 当成正式执行前的预览按钮,觉得只是多了一步。其实它是在正式动作之前,把目标集合固定下来并让人有机会质疑它。如果统计结果突然过大、过小,或者和已知情况对不上,最便宜的修正时间就是现在,而不是已经改了几百条之后。
串行执行,把账本放在速度前面
任务生成以后,我选择按月份串行执行,而不是并发地打开许多页面。串行当然慢一些,但每批开始和结束都有清楚边界,失败也不会一下子扩散到所有批次。对于会改变内容状态的操作,我判断可恢复性比瞬时吞吐量更重要,是因为平台反馈、登录状态和页面数据都不是完全稳定的。
每一条处理结果都要写入记录:已经成功的,后续跳过;明确失败的,留待续跑;平台规则不允许修改的,单独标记;还没有轮到的,保持未完成。这个账本让重启不再等于从头再来。它也避免了一个常见错误:为了“确保成功”,把已经成功的内容再次点一遍。
当时前几个月跑完后,已经有 90 条明确成功,68 条属于“点了之后没有观察到平台反馈”。后来整体过程暂停时,数据库里仍公开的数量从 1,128 条降到了 918 条。这个变化说明有些操作确实生效了,但不能仅凭数字变化就推断每一条都已完成。批量结果需要按条目解释,而不是只看一个总数。
没有反馈,不等于可以盲目重试
这里最容易误判。页面没有返回确认,直觉会告诉我“那就是失败了”,于是再点一次;另一种直觉则是“我已经点过了,肯定成功”,于是把它直接标为完成。这两种判断都过于简单。
我更愿意把这种结果记成“未知”,因为它准确描述了证据边界:动作已经发出,但当时没有看到足够明确的反馈。后续可以结合实际状态、重新读取列表或再做一次受控尝试,但不能把未知混进成功,也不能把未知全部当成失败高速重放。
如果不区分这三种状态,后果会很直接。把未知当失败,会重复修改,增加平台限流和误操作风险;把未知当成功,会留下没有完成的内容;只看最后剩余数量,则无法知道哪些条目需要人工处理。可靠的批量流程,必须允许“我现在还不知道”成为一种正式状态。
合集是另一个不能靠速度解决的边界。有些视频位于合集里,平台规则不允许直接改成仅自己可见。这种情况下,正确动作不是未经授权把它从合集移出,再继续点击。它应该被记录为“平台限制”,和真正的操作失败分开。用户当时明确要求先完成可以设置的部分,合集部分留到后面处理,这个授权边界也决定了流程不能擅自扩大。
空列表时,停止本身就是成功的保护
批量续跑时,平台曾经返回了空的视频列表,而正常情况下应该有 2,635 条内容。脚本没有把这个空列表理解成“已经没有目标”,也没有继续点击。它按照安全规则停下,因为空结果更可能意味着登录状态、远端会话或平台接口出现异常。
这件事让我重新意识到,门禁不只是执行前检查一次。登录状态应该做秒级检查,列表非空也应该在每批开始前确认。否则,执行者可能在未登录页面、异常页面或错误筛选结果上继续操作,最后得到一份看似完整、实际无法解释的日志。
最容易走的错误捷径,是把“没有数据”当成“任务已完成”,把“没有反馈”当成“再试几次就好”。我不会这样做,是因为批量动作的风险不在某一次点击,而在错误信号被当成正常信号后,系统还继续运行。安全停止会让任务暂时变慢,却保住了后续恢复的可能。
这次之后,我把这类操作概括成一套可以复用的方法。先用只读查询得到目标集合,确认数量和筛选条件;再用现有工具支持的稳定边界切批,给每批留下预期数量;执行时串行推进,并为每条结果保留成功、失败、未知、平台限制和未处理等状态。
每批开始前,先做一次快速登录状态检查,再确认远端列表不是异常空值。发现列表为空、页面结构异常或规则阻断,就停在当前批次,不把异常扩散到下一批。恢复时只处理账本中没有明确成功的条目,同时对未知结果先结合实际状态判断,避免重复修改。
这套方法不保证平台永远稳定,也不保证所有内容都能被设置成功。它真正保证的是:失败不会被藏起来,暂停不会抹掉进度,重启不会自动扩大范围。一个流程成熟的标志,不是它顺利时能跑多快,而是它中断后还能不能准确知道下一步该从哪里开始。
下次我会怎么做
下次再遇到上千条内容需要统一修改,我会把“能不能批量点”改成“能不能安全恢复”来判断方案。第一步仍然是只读统计,先把自然语言条件变成明确的目标集合;第二步选择现有工具真正支持的切分边界,不为了追求整齐而硬塞一个不存在的日期参数;第三步生成带预期数量的任务账本,执行前先做登录和列表非空门禁。
执行中,我会坚持串行和幂等:明确成功的条目不再处理,未知结果不擅自归类,平台限制不越权绕过,真正失败的条目留给下一轮。每一次暂停都要留下原因,每一次恢复都从账本继续,而不是凭记忆猜进度。
这件事让我重新意识到,效率不只是单位时间完成多少动作,也包括出了问题以后少返工多少。真正值得追求的速度,是让下一次恢复足够简单,而不是让这一次点击看起来足够快。