YAOTU INSIGHTS

AI自动化发稿实战:227次操作踩9坑,浏览器自动化发布文章全流程

AI自动化发稿实战:227次操作踩9坑,浏览器自动化发布文章全流程
1. 项目缘起与整体设计思路1.1 为什么想让 AI 自己去发稿事情的起因很简单。我手上有一个持续在维护的技术内容账号日常需要在腾讯云开发者社区保持更新频率。写过技术博客的人都知道从选题、写稿、排版、配图到最终发布一篇文章的完整链路走下来纯手工操作少说也要一两个小时。如果遇到需要反复调整格式、上传图片、填写标签的情况时间成本还会进一步拉高。我当时的想法是既然 AI 已经能帮我写稿了那为什么不让它把“发布”这一步也一起干掉换句话说我希望构建一个端到端的自动化流程让 AI 从拿到一篇成稿开始自己打开浏览器、登录社区、进入编辑器、粘贴正文、上传封面图、填写分类标签最后点击发布。整个过程不需要我盯着屏幕我只需要在最后确认一下结果就行。这个想法听起来不算复杂但真正动手之后才发现里面涉及的坑远比想象中多。最终这次实战跑下来AI 一共执行了227 次操作耗时4.3 小时踩了9 个比较典型的坑。我把整个过程完整复盘一遍希望能给同样在做浏览器自动化、AI Agent 操作网页的朋友一些参考。1.2 核心关键词与涉及的技术点这次实战涉及的核心技术点主要有这么几个browser-skill这是我用来驱动浏览器操作的核心能力模块负责把“点击”“输入”“滚动”“截图”这些动作封装成 AI 可以调用的技能。bsk这是 browser-skill 的简称在日志和调试过程中我大量使用这个缩写来标记操作来源。tencent-cloud-community-publish这是本次任务的场景标识代表“在腾讯云开发者社区发布文章”这一具体流程。execCommand这是富文本编辑器里插入内容时绕不开的一个老 API也是本次踩坑的重灾区。upload文件上传环节涉及封面图、正文配图的处理同样是自动化里最容易出问题的地方。这几个关键词基本覆盖了整条链路的核心难点。下面我会按照“整体设计—核心细节—实操过程—问题排查”的顺序把每个环节拆开讲清楚。1.3 整体方案选型与背后的考量在方案设计阶段我其实面临几个选择。第一个选择是用纯 API 方式发布还是用浏览器自动化方式发布理论上如果社区提供开放的发布接口直接调 API 是最稳的。但实际情况是很多内容平台的发布接口并不对外开放或者需要复杂的鉴权流程。所以我最终选择了浏览器自动化这条路——让 AI 像真人一样操作页面。这样做的好处是通用性强不依赖平台是否开放接口坏处是稳定性受页面结构影响大任何一个 DOM 变化都可能导致流程失败。第二个选择是用现成的自动化框架还是自己封装 browser-skill我最终选择了自己封装。原因是我需要让 AI 能够“理解”当前页面状态而不是机械地执行固定脚本。比如当页面加载慢的时候AI 应该知道等待当某个按钮找不到的时候AI 应该尝试滚动或者换一种定位方式。这种“带判断的操作”是普通脚本很难做到的必须把操作封装成 skill让 AI 在每一步都能做决策。第三个选择是一次性跑完还是分阶段执行我最终选择了分阶段。因为整个流程太长如果一次性跑一旦中间出错前面的操作就白费了。分阶段执行的好处是每个阶段可以单独验证、单独重试大大降低了整体失败率。提示做浏览器自动化时不要一上来就追求“全自动一把过”。先把流程拆成若干可独立验证的阶段每个阶段跑通之后再串联这是最省时间的做法。2. 核心细节解析与实操要点2.1 browser-skill 的能力边界与设计原则browser-skill 本质上是一层封装它把浏览器里常见的操作抽象成 AI 可以调用的函数。我设计的 skill 主要包括这几类导航类打开指定 URL、前进、后退、刷新。定位类根据文本、CSS 选择器、XPath 找到页面元素。交互类点击、输入文本、清空输入框、选择下拉项。文件类上传文件到指定 input 元素。状态类获取页面文本、获取元素属性、截图、等待某个条件成立。设计这些 skill 的时候我遵循了一个原则每个 skill 只做一件事并且返回足够的信息让 AI 判断下一步。比如“点击”这个 skill不仅要执行点击还要返回点击后页面是否发生了变化、有没有弹窗出现、当前 URL 是否改变。这样 AI 才能根据返回结果决定是继续还是重试。这里有个很容易被忽略的点skill 的返回值设计比 skill 本身更重要。如果返回值信息不足AI 就会“盲操作”出错率会飙升。我在早期版本里就是因为点击 skill 只返回了“成功/失败”导致 AI 在页面没加载完的时候误判为成功后面一连串操作全部错位。2.2 富文本编辑器的 execCommand 陷阱腾讯云开发者社区的编辑器是富文本编辑器这类编辑器最大的特点是不是一个简单的 textarea而是一个 contenteditable 的 div。往里面插入内容最直接的方式就是用document.execCommand(insertText, false, text)。但 execCommand 有几个非常坑的地方第一它已经被标记为废弃。虽然目前主流浏览器还支持但行为在不同浏览器、不同版本之间可能有差异。我在测试的时候就发现同样的代码在某个版本里能正常插入换一个版本就插不进去。第二它对换行和特殊字符的处理很不稳定。普通文本还好一旦遇到代码块、表格、有序列表这些结构execCommand 经常会把格式搞乱。我最初尝试直接把整篇 Markdown 转成 HTML 再插入结果编辑器把很多标签都过滤掉了代码块直接变成了一坨纯文本。第三它和编辑器的内部状态可能不同步。有些富文本编辑器会在内部维护一份数据模型execCommand 直接操作 DOM 之后编辑器的数据模型并没有更新导致你看着内容进去了但一提交就发现内容是空的。我最终的解决方案是分段插入 模拟真实输入。具体来说就是把文章按段落拆开逐段调用 execCommand 插入每插入一段就触发一次 input 事件让编辑器同步状态。对于代码块这种特殊结构我改用模拟键盘输入的方式一个字符一个字符地敲进去虽然慢但稳定性高很多。注意execCommand 的废弃状态意味着它不是长久之计。如果平台后续升级编辑器这套方案可能需要重写。做自动化时要对这类“依赖废弃 API”的环节保持警惕留好备选方案。2.3 文件上传环节的 upload 处理文件上传是另一个重灾区。浏览器的文件上传通常依赖input typefile元素但自动化工具没法直接操作系统的文件选择对话框。解决办法是绕过对话框直接把文件路径设置到 input 元素的 files 属性上。具体做法是先找到页面上隐藏的 file input然后用自动化工具提供的“设置文件”能力把本地文件路径传进去。这一步的关键是找到正确的 input 元素。很多网站会把 file input 隐藏起来用一个漂亮的按钮代替你点击按钮的时候实际上是触发了那个隐藏 input 的 click。我在实操中遇到的坑是页面上有多个 file input分别对应封面图、正文配图、附件等不同用途。如果定位错了就会出现“封面图传到了正文里”这种尴尬情况。解决办法是通过 input 的 accept 属性、name 属性或者它所在的父容器来精确定位。另外上传之后一定要等待上传完成的信号。有些网站上传是异步的你设置完文件之后图片还在后台上传这时候如果直接点发布图片就会丢失。我的做法是监听网络请求或者轮询检查图片的 src 是否已经变成了真实的 CDN 地址。3. 实操过程与核心环节实现3.1 阶段一登录态与页面准备整个流程的第一步是确保登录态。我没有让 AI 去模拟输入账号密码因为那样涉及验证码、二次验证等问题太不稳定。我的做法是复用已有的浏览器用户数据目录也就是让自动化浏览器加载一个已经登录过的 profile。这样打开社区页面时直接就是登录状态。这一步的实操要点是启动浏览器时要指定userDataDir参数指向一个已经手动登录过的目录。第一次使用前我会手动打开这个浏览器登录一次之后自动化流程就能直接复用。页面准备阶段AI 需要做的是打开社区创作页面等待编辑器加载完成。这里的判断条件是“编辑器区域出现且可编辑”。我用的检测方法是轮询检查 contenteditable 元素的 presence同时检查页面是否有 loading 遮罩。3.2 阶段二正文内容的插入正文插入是整个流程里最耗时、最容易出错的部分。我最终采用的策略是“分块处理”把文章按 Markdown 结构拆分成块标题块、段落块、代码块、图片块、列表块。对每种块类型采用不同的插入策略。每插入一块就验证一次内容是否正确进入编辑器。普通段落用 execCommand 插入代码块用模拟输入图片块先上传再插入引用。这个过程中我记录了一个关键数据平均每插入一个块需要 3 到 5 次操作包括定位、插入、验证。一篇文章大概有 40 到 50 个块所以光正文插入就消耗了 150 次左右的操作。这里有个实操心得插入顺序要从后往前或者从前往后但不要跳着插。因为富文本编辑器的光标位置很容易乱如果你跳着插光标可能跑到意想不到的地方导致内容错位。我一开始就是随机插入结果文章结构全乱了后来改成严格顺序插入才稳定下来。3.3 阶段三封面图与标签填写正文搞定之后接下来是封面图和标签。封面图的上传相对独立找到对应的 file input设置文件等待上传完成即可。标签填写则是在输入框里输入标签文字然后从下拉建议里选中。标签这一块有个小坑有些标签需要精确匹配才能选中。如果你输入的标签文字和平台已有的标签不完全一致可能创建出一个新标签或者干脆选不上。我的做法是先把目标标签文字输入然后等待下拉列表出现再从列表里选择完全匹配的项。3.4 阶段四发布前的最终校验在点击发布之前我做了一次完整的校验包括标题是否正确填入正文块数量是否和预期一致代码块格式是否保留封面图是否上传成功标签是否选中分类是否选择这个校验环节帮我避免了好几次“带病发布”。有一次就是封面图实际上传失败了但页面上显示了一个占位图如果不仔细检查就会误以为成功。校验通过之后点击发布按钮等待跳转到文章详情页确认文章 ID 和标题正确整个流程才算结束。4. 常见问题与排查技巧实录4.1 九个坑的完整记录这次实战踩的 9 个坑我整理成了一张表方便大家对照排查序号问题现象根本原因解决方案1编辑器内容插入后消失execCommand 未触发 input 事件编辑器状态未同步每次插入后手动触发 input 事件2代码块格式丢失直接插入 HTML 被编辑器过滤改用模拟键盘逐字符输入3封面图传到了正文file input 定位错误通过 accept 属性和父容器精确定位4图片上传后立即发布导致丢失未等待异步上传完成轮询检查图片 src 是否为 CDN 地址5标签选不上输入文字与平台标签不完全匹配从下拉建议中精确选择6页面加载慢导致点击无效未等待元素可交互增加显式等待和可交互检测7光标位置错乱跳序插入内容严格按顺序插入8登录态失效profile 过期定期手动刷新登录态9发布按钮点击无反应存在未填必填项发布前做完整校验4.2 排查思路的通用方法遇到问题的时候我总结了一套通用的排查思路第一步截图。不管什么问题先截图看当前页面状态。很多时候问题一眼就能看出来比如弹了个错误提示、页面还在 loading、某个必填项是空的。第二步看日志。browser-skill 的每次操作我都会记录日志包括操作类型、目标元素、执行结果。通过日志能快速定位到是哪一步开始出错的。第三步缩小范围。如果整个流程失败不要从头重跑而是从失败的那一步单独重试。这样可以快速验证是偶发问题还是必现问题。第四步手动复现。如果自动化怎么都跑不通就手动操作一遍看看真人操作时页面是什么反应。很多时候自动化失败是因为它模拟的操作和真人操作有细微差别。提示做浏览器自动化日志和截图是你的两条命。没有这两样排查问题基本靠猜。4.3 提升稳定性的几个实操技巧除了排查问题我还总结了一些提升稳定性的技巧给每个操作加超时和重试。不要假设一次就能成功失败后自动重试 2 到 3 次成功率会大幅提升。用文本定位代替 CSS 选择器。CSS 选择器容易因为页面改版失效而按钮上的文字相对稳定。关键操作后加短暂等待。不要操作完立刻进行下一步给页面一点反应时间。把长流程拆成短流程。每个短流程独立验证降低整体失败率。这次 227 次操作、4.3 小时的实战虽然踩了不少坑但最终跑通了整条链路。对我来说最大的收获不是“AI 能发稿”这个结果而是摸清了浏览器自动化在真实内容平台上的能力边界和稳定性瓶颈。后续如果要做类似的事情这套经验可以直接复用少走很多弯路。