Skill 方案导入1316 字·2026/11/14·被检索 0 次

Skill 方案 S6 · 整站长图截图

在已有site-longshot之上补齐URL来源、三层等待策略、字体加载、超长图分片与交付校验:sitemap优先、无则BFS,--save-pages定位坏页,--no-downscale把静默缩小变成显式报错。3次截图的0.09亿token可压到0.01亿。

挂靠在《二、重复操作与 Skill 方案》之下

版本
使用说明
v1reused-preview2026/11/14 11:16:53

Skill 方案 S6 · 整站长图截图

一句话:给一个域名,自动收集站内页面、逐页整页截图、纵向拼成一张 PNG,并给出可核对的尺寸与失败页;3 次截图任务消耗的 0.09 亿 token 可压到 0.01 亿。

一、为什么需要它

截图看似最简单,实际是单次成本最贵的操作之一:单次会话 4.57M token,因为要临时写 Playwright 脚本、调滚动、处理懒加载、拼图,每一步都在试。

指标数值说明
截图任务3 次门户整站、单页存档、对比图
累计 token0.09 亿单次最高 457 万
平均工具调用30–60 次大部分是失败重试
一次成功0 次三次都改了参数重跑
现有资产site-longshot skill已封装 capture.mjs,但触发不稳定

四个反复出现的具体问题:

  1. 临时手写脚本。每次都要重新写 chromium.launch → goto → screenshot({fullPage:true}),然后发现懒加载没触发、fixed 导航重复出现。
  2. 等待时间靠猜。waitForTimeout(1000) 有时不够,有时白等,页面高度在不同次截图里能差 30%。
  3. 拼接错位。分段截图时若视口高度变化,100vh 元素会在每段重复,拼出来一条一条的。
  4. 超长图被浏览器拒绝。单页高度超过 40000 px 时 fullPage 直接失败,或生成一张 300 MB 的图打不开。

二、触发词与边界

触发词不适用场景
「网站截图」「整页长图」「长截图」只要某个元素/某个视口 → 浏览器截图即可
「全站截图」「把网页存成一张图」要 PDF 而不是 PNG → 用打印/导出
「网页存档」「截全站生成一张长图」要抓文字内容 → 走抓取/解析,不截图
「页面太长截不全」需要登录且拿不到登录态 → 明确说明无法截取

边界:只截公开可访问页面,默认同域、不提交表单、不下载文件;需要登录态时必须显式传 --storage-state,不得用公开缓存冒充登录后内容。

三、输入与前置检查

先跑环境自检,ok: true 才继续:

node "C:/Users/cag/.workbuddy/skills/site-longshot/scripts/capture.mjs" --check

本机返回 {"ok":true,"node":"v22.22.2","browsersInstalled":["chromium-1243"],"systemEdge":true},说明 Playwright 与 Chromium 都在,不需要 sharp、Pillow、ImageMagick——拼图是浏览器 canvas 完成的。

URL 列表来源,按优先级三选一:

来源做法适用
用户给定直接列 URL最准,优先
sitemap.xmlInvoke-WebRequest https://cag.quest/sitemap.xml 取 <loc>站点有 sitemap 时
站内 BFS--max-pages N --depth D 自动爬同域链接无 sitemap、只要主要页面

站点规模与页数对应:门户类 3–5 页,文档站 8–15 页,超过 15 页按栏目拆多次跑。

四、执行步骤

步骤 1 · 定视口与设备像素比。 默认 1440 × 1,与桌面浏览一致;要存档级清晰度用 --scale 2,体积约 4 倍,超长页不建议开。

步骤 2 · 等待策略。 三层等待缺一不可:

层参数建议值
首屏加载--wait800 ms(默认);动态站 2500 ms
懒加载预热--scroll-step / --scroll-delay700 px / 120 ms(默认)
动画与 fixed 冻结默认开启不要关

字体加载是隐藏坑:webfont 未就绪时截出来是回退字体,中文字宽变化会让排版整体偏移。当前 capture.mjs 没有独立字体等待参数,用 --wait 2500 兜底;若要精确,需在 goto 之后加 await page.evaluate(() => document.fonts.ready)(需按实际调整,改脚本后同步 SKILL.md)。

步骤 3 · 单页整页长图。

node "C:/Users/cag/.workbuddy/skills/site-longshot/scripts/capture.mjs" "https://cag.quest" \
  --width 1440 --wait 2000 \
  --out "C:/Users/cag/WorkBuddy/2026-11-11-09-21-47/tmp-longshot/cag-quest-home.png"

步骤 4 · 整站多页拼接。

node "C:/Users/cag/.workbuddy/skills/site-longshot/scripts/capture.mjs" "https://cag.quest" \
  --max-pages 8 --depth 2 --width 1440 --wait 2000 \
  --save-pages \
  --out "C:/Users/cag/WorkBuddy/2026-11-11-09-21-47/tmp-longshot/cag-quest-all.png"

--save-pages 一定要开:拼接出错时能立刻定位是哪一页,而不是重跑整站。

步骤 5 · 超长图分片。 单页超过 40000 px 会被裁剪并告警,最终 PNG 超过 30000 px 会被等比缩小(downscaleRatio < 1)。要原尺寸就分片:

node ".../capture.mjs" "https://cag.quest/notes/" --chunk 1200 --max-height 60000 --no-downscale --out ".../notes-part.png"

--no-downscale 让超限变成显式报错而不是悄悄缩小,配合 --chunk 1200 固定每段视口高度,避免 100vh 抖动造成重复条带。

步骤 6 · 校验并交付。 读 stdout 的 JSON,确认 ok、height > width、pages[].status 全 200、failed 为空;用 present_files 展示 PNG 并给出路径、尺寸、体积、覆盖页数。warnings 里的裁剪/缩小必须原样转述。

五、输出与验收

{"ok":true,"output":"...cag-quest-all.png","width":1440,"height":18420,"bytes":8321440,
 "pages":[{"url":"https://cag.quest/","status":200,"height":3120,"chunks":3}],
 "failed":[],"warnings":[],"downscaleRatio":1}

三条硬断言:

  1. ok === true 且输出文件存在,bytes > 100 KB;一张全白的图也可能"成功",所以必须再看尺寸。
  2. 每页 status 为 200,failed 为空;有失败页就如实列出,不许用缓存图替代。
  3. downscaleRatio === 1 或已在回复中说明缩小比例;悄悄缩小的长图会丢字,属于隐性失败。

六、失败处理与回滚

现象根因动作
图里导航重复出现fixed/sticky 未冻结确认没加 --no-freeze
底部大片空白懒加载未触发加 --wait 2500、--scroll-delay 250
中文变宋体/错位webfont 未加载完加大 --wait,或按上文加 document.fonts.ready
executable doesn't exist浏览器未装--check 看 browsersInstalled,用 --browser edge 兜底
拼接错位分段视口高度不一致固定 --chunk,不要混用 --scale
图太大打不开超 --max-output-height分片输出,或按栏目拆多次

回滚:截图是无副作用的只读操作,失败重跑即可;产物统一落 tmp-longshot/,过期文件移到 _trash,不直接删除。

七、收益测算

项目现状改造后
单次 token300 万25 万
次数3 次3 次
累计0.09 亿0.01 亿
一次成功率080% 以上
单次耗时5–15 分钟1–3 分钟

省的是"写脚本 + 调试等待 + 重跑"三轮。已有 site-longshot 把这三轮压成一条命令,本方案要做的是把触发词补全(当前对"全站""存档""截不全"覆盖不足),并在正文里把分片与字体两个坑前置,避免每次重新发现。节省 0.08 亿,约 89%,是七类里比例最高的一项。