← 返回 Skills 市场
tenequm

download-webpage-as-pdf

作者 Misha Kolesnik · GitHub ↗ · v0.1.3 · MIT-0
cross-platform ✓ 安全检测通过
71
总下载
0
收藏
0
当前安装
4
版本数
在 OpenClaw 中安装
/install download-webpage-as-pdf
功能描述
Save a live webpage as a high-fidelity PDF that preserves the original layout AND every image (including lazy-loaded ones) using the agent-browser CLI. Use t...
使用说明 (SKILL.md)

Download a webpage as a PDF (agent-browser recipe)

The naive approaches fail on modern sites:

  • chrome --headless --print-to-pdf captures only the initial viewport's images. Anything below the fold renders as a blank rectangle.
  • agent-browser pdf immediately after open has the same problem - lazy-loaded images haven't decoded yet.
  • Scrolling via JS and then waiting a fixed time is also unreliable - you don't know when each image actually finished.

The fix is one async script that strips lazy-load attributes, scrolls the page to trigger any IntersectionObserver-based loaders, and awaits every \x3Cimg> to decode. agent-browser's eval waits for the returned promise to resolve before exiting, so the subsequent pdf command sees a fully-loaded DOM.

The recipe

If multiple test/agent runs may share the host's agent-browser, isolate each invocation with agent-browser --session \x3Cunique-name> ... on every command in the pipeline. Single-user one-off captures can omit the flag and use the default session.

Set AGENT_BROWSER_HEADED=false in the environment before running so the skill launches headless even when the host's ~/.agent-browser/config.json defaults to "headed": true. This avoids popping a real Chrome window on the user's desktop while an agent is working in the background. Do NOT use the CLI's --headed false flag - in agent-browser 0.26.0 it parses but corrupts the session context (subsequent commands see an empty document). The env var is the supported route. To watch the run for debugging, unset the variable or pass --headed instead.

export AGENT_BROWSER_HEADED=false

agent-browser open \x3CURL>
agent-browser wait --load networkidle

agent-browser eval "(async () => {
  const sleep = ms => new Promise(r => setTimeout(r, ms));
  ['#onetrust-banner-sdk','#onetrust-consent-sdk','.ot-sdk-container','#ot-sdk-btn-floating','[id*=cookie]','[id*=consent]','[id*=onetrust]'].forEach(s => document.querySelectorAll(s).forEach(e => e.remove()));
  document.querySelectorAll('img').forEach(img => {
    img.removeAttribute('loading');
    img.removeAttribute('decoding');
    if (img.dataset.src) img.src = img.dataset.src;
    if (img.dataset.srcset) img.srcset = img.dataset.srcset;
  });
  for (let y = 0; y \x3C document.documentElement.scrollHeight + 2000; y += 400) {
    window.scrollTo(0, y);
    await sleep(200);
  }
  window.scrollTo(0, document.documentElement.scrollHeight);
  await sleep(2000);
  await Promise.all(Array.from(document.images).map(i =>
    i.complete && i.naturalWidth ? null
    : new Promise(r => { i.addEventListener('load', r, {once:true}); i.addEventListener('error', r, {once:true}); setTimeout(r, 5000); })
  ));
  window.scrollTo(0, 0);
  await sleep(500);
  return Array.from(document.images).filter(i => !i.naturalWidth).length;
})()"

agent-browser pdf /tmp/page.pdf
agent-browser close

# Verify the result
pdfinfo /tmp/page.pdf | grep -E "Pages|File size"

The eval returns the count of images that still failed to load. Expect 0. If non-zero, the recipe didn't fully capture the page - investigate before trusting the PDF. The pdfinfo line is your standard end-of-recipe report (page count + bytes) so the agent has concrete numbers to relay back.

Why each step matters

  • wait --load networkidle before the eval gives the page a chance to attach its IntersectionObservers and other JS hooks. Scrolling before observers attach defeats the trigger.
  • Removing the loading attribute is the structural fix. This is the same trick percollate uses internally - the most reliable way to make Chromium eagerly fetch every image.
  • Scrolling the full height in 400px steps triggers any observer-based loaders that watch for elements crossing the viewport. Some sites use observers even after loading=lazy is removed.
  • await Promise.all on every \x3Cimg> guarantees decoded pixels are in memory before the eval returns. agent-browser's eval is promise-aware - the next command (pdf) will not run until this resolves.
  • Returning the broken-image count is your verification. If it is not 0, the recipe did not fully capture the page - do not trust the PDF.

Cleanup pipeline (optional but recommended)

agent-browser saves at letter size with the page's full footer (nav, newsletter signup, link sitemap). For a clean archive:

# 1. Inspect total page count and visually identify which trailing pages are footer
pdfinfo /tmp/page.pdf | grep Pages

# Use the Read tool on the PDF to see the last few pages and decide where the article ends.

# 2. Trim footer pages. The "1-9" below is illustrative ONLY - replace with the
#    article's actual range from pdfinfo + visual inspection. Do not copy this verbatim.
qpdf /tmp/page.pdf --pages . 1-9 -- /tmp/page-trimmed.pdf

# 3. Compress (typically 60-70% reduction with images intact)
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
   -dNOPAUSE -dQUIET -dBATCH \
   -sOutputFile=/path/to/final.pdf /tmp/page-trimmed.pdf

-dPDFSETTINGS=/ebook keeps images legible at roughly half the raw size. /screen is smaller but blurrier; use only when size matters more than legibility.

When NOT to use this

  • Reader-mode / article-only output (no nav, no footer, no manual trimming, just the article body and its images): use npx percollate pdf \x3CURL> -o out.pdf instead. percollate runs Mozilla Readability + Puppeteer and auto-strips chrome. It also handles lazy-load via DOM preprocessing rather than scroll hacks. Slower (~10s) but zero trimming work and very robust on unknown URLs. Pair with --no-hyphenate --css "@page { size: A4; margin: 18mm; } a[href]::after { content: none !important; }" to suppress the inlined-URL-after-link default.
  • Single-page screenshot (not paginated): use agent-browser screenshot --full-page instead.
  • HTML archive with all assets bundled: use monolith or single-file CLI. PDFs lose interactivity.
  • Server-rendered HTML you control (no JS): WeasyPrint is faster and simpler.

Picking between agent-browser and percollate

When the user does not specify, default to percollate for "save this for archival reference" - it's idiot-proof and handles unknown URLs without manual trimming. Use agent-browser (this skill) when the user explicitly wants the page to look like the browser version, or when the page is not article-shaped (a tool, dashboard, marketing page, portfolio) where Mozilla Readability would strip out content the user actually wants.

安全使用建议
Install/use this if you are comfortable with an agent opening the requested URL in agent-browser, running the disclosed image-loading script, and writing a local PDF. For private or logged-in pages, use a unique agent-browser session and choose an output path deliberately; verify local tool versions before relying on the recipe.
功能分析
Type: OpenClaw Skill Name: download-webpage-as-pdf Version: 0.1.3 The skill provides a legitimate recipe for capturing high-fidelity PDFs of webpages using the agent-browser CLI. It uses a JavaScript snippet within the browser context to handle lazy-loaded images, remove cookie banners, and ensure all assets are decoded before printing. The instructions in SKILL.md are transparent, well-documented, and focused entirely on the stated archival purpose without any signs of malicious intent or data exfiltration.
能力标签
cryptocan-make-purchases
能力评估
Purpose & Capability
The documented behavior matches the stated purpose: open a user-requested webpage, wait for images, save a PDF, and optionally clean it up. No code files or static findings were provided.
Instruction Scope
The recipe tells the agent to run browser commands and a fixed DOM-manipulation script. This is purpose-aligned for high-fidelity PDF capture, but it should remain limited to URLs the user intended to capture.
Install Mechanism
There is no install spec and metadata declares no required binaries, while the instructions rely on external CLIs such as agent-browser, pdfinfo, and optional qpdf/gs.
Credentials
The skill loads live webpages in a headless browser, triggers lazy-loaded resources, removes some consent/banner elements from the rendered DOM, and writes PDFs under /tmp. This is expected for the task but should use user-chosen paths when needed.
Persistence & Privilege
The skill discusses use of the default agent-browser session and recommends unique sessions for shared hosts. Users should isolate sessions when private or authenticated browsing state might matter.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install download-webpage-as-pdf
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /download-webpage-as-pdf 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v0.1.3
Updated download-webpage-as-pdf from 0.1.2 to 0.1.3. Changes: - modified `CHANGELOG.md` - modified `SKILL.md`
v0.1.2
Updated download-webpage-as-pdf from 0.1.1 to 0.1.2. Changes: - modified `CHANGELOG.md` - modified `SKILL.md`
v0.1.1
Updated download-webpage-as-pdf from 0.1.0 to 0.1.1. Changes: - added `CHANGELOG.md` - modified `SKILL.md`
v0.1.0
Initial publish of download-webpage-as-pdf 0.1.0. Changes: - added `LICENSE.txt` - added `SKILL.md`
元数据
Slug download-webpage-as-pdf
版本 0.1.3
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 4
常见问题

download-webpage-as-pdf 是什么?

Save a live webpage as a high-fidelity PDF that preserves the original layout AND every image (including lazy-loaded ones) using the agent-browser CLI. Use t... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 71 次。

如何安装 download-webpage-as-pdf?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install download-webpage-as-pdf」即可一键安装,无需额外配置。

download-webpage-as-pdf 是免费的吗?

是的,download-webpage-as-pdf 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

download-webpage-as-pdf 支持哪些平台?

download-webpage-as-pdf 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 download-webpage-as-pdf?

由 Misha Kolesnik(@tenequm)开发并维护,当前版本 v0.1.3。

💬 留言讨论