全部技能 / 文档与知识 / baoyu-url-to-markdown
文档与知识 · JimLiu/baoyu-skills

baoyu-url-to-markdown

Fetch any URL and convert to markdown using baoyu-fetch CLI (Chrome CDP with site-specific adapters). Built-in adapters for X/Twitter, YouTube transcripts, Hacker News threads, and generic pages via Defuddle. Handles login/CAPTCHA via interaction wait modes. Use when user wants to save a webpage as markdown.

风险提醒:红色 · 谨慎使用AI 侦查报告
作者 JimLiuGitHub JimLiu/baoyu-skills ↗Stars 25926许可 MIT(仓库根 LICENSE:Copyright (c) 2026 Jim Liu;根 package.json 同声明 "license": "MIT")commit 1567581c26
agent 宿主通常会约束 skill 执行权限;风险提醒为 AI 侦查观点,不构成质量或安全保证。第三方 skill 仅作拆解与展示,安装使用风险自负,版权归原作者。

1实现原理 · 为什么它能做到

入口是一个 shell 包装 + vendored 的 TS CLI:baoyu-fetch 直接 exec bun 跑 lib/cli.ts,CLI 再按 URL 选适配器(x / youtube / hn / generic)。

skills/baoyu-url-to-markdown/scripts/baoyu-fetch
exec bun "$script_dir/lib/cli.ts" "$@"
注:SKILL.md 要求 agent 先 bun install 装依赖再调 ${READER};CLI 默认不无头(见 verification 的 discrepancy 项),会启动可见 Chrome。

抓取靠真实 Chrome + 手写 CDP 客户端(chrome-launcher 起浏览器,ws 直连 DevTools),不是 puppeteer。

skills/baoyu-url-to-markdown/scripts/lib/browser/cdp-client.ts
import WebSocket from "ws";
注:在页面里执行 JS 用 Runtime.evaluate(awaitPromise + returnByValue),滚动/点击/读取 DOM 都经它。

X 适配器不是只读 DOM,而是内置会话机制:先用 CDP 读 x.com/twitter.com cookie(要求 auth_token 与 ct0),把 cookie 明文写进 profile 目录下的 sidecar 文件,下次运行再回灌。

skills/baoyu-url-to-markdown/scripts/lib/browser/cookie-sidecar.ts
await writeFile(filePath, JSON.stringify(data, null, 2));
注:文件名 x-session-cookies.json,位置在 Chrome profile 目录内(无加密、无权限收紧);正常路径读不到 cookie 时就用它恢复登录态。

X 的数据来源是页面自己发出的 GraphQL 响应:工具用 CDP 网络日志把 /graphql/ 的 TweetDetail / TweetResultByRestId 等响应体捞出来再解析,还会自动滚动+点『Show replies』加载长贴。

skills/baoyu-url-to-markdown/scripts/lib/adapters/x/payloads.ts
entry.url.includes("TweetDetail") ||
注:因此它不逆向 Twitter 私有 API 的签名逻辑,但确实在读取那些非公开接口的返回内容。

YouTube 适配器是自建 InnerTube 调用:从页面 ytcfg 取 INNERTUBE_API_KEY,在页面上下文 POST /youtubei/v1/player(credentials: 'include',带页面 cookie),并显式冒充 ANDROID 客户端。

skills/baoyu-url-to-markdown/scripts/lib/adapters/youtube/transcript.ts
context: { client: { clientName: 'ANDROID', clientVersion: '20.10.38' } },
注:与同仓 baoyu-youtube-transcript 同族做法:不走官方 Data API、带客户端冒充,属逆向/伪装路线。

可复用已运行的 Chrome 调试会话:先扫 ps aux 找带同一 profile 且带 --remote-debugging-port 的进程,或读取 profile 里的 DevToolsActivePort 文件,找到就连上。

skills/baoyu-url-to-markdown/scripts/lib/browser/profile.ts
const activePort = parseDevToolsActivePort(path.join(options.profileDir, "DevToolsActivePort"));
注:也支持 --cdp-url ws://… 直接连任意调试端点;属于设计内的会话接管能力。

遇到登录墙/CAPTCHA 不是硬闯,而是提供等待模式:检测到 Cloudflare/reCAPTCHA 等在页面出现时,弹出可见 Chrome 让用户手动过,检测到进展或按回车就继续。

skills/baoyu-url-to-markdown/scripts/lib/browser/interaction-gates.ts
text.includes("verify you are human") ||
注:默认给 10 分钟等待、1.5 秒轮询;这正是 SKILL.md 所说 'Handles login/CAPTCHA via interaction wait modes' 的实现。

生成 markdown 的主链是本地 Defuddle/Readability + 质量评分,质量不足时才把目标 URL 交给第三方服务 https://defuddle.md 取更干净的 markdown。

skills/baoyu-url-to-markdown/scripts/lib/extract/html-to-markdown.ts
const DEFUDDLE_API_ORIGIN = "https://defuddle.md";
注:这也是 SKILL.md『Quality Gate』存在的原因:无头抓取可能静默返回低质量内容,需要 agent 复检(--debug-dir 可 dump document.json/markdown.md/page.html/network.json)。

2核心能力

01任意 URL → 干净 markdown(默认 stdout,可 --output 存文件,--format json 出结构化文档)
02站点适配器:X/Twitter(含长贴与文章)、YouTube(字幕)、Hacker News(嵌套评论树)、通用网页
03YouTube 字幕抓取(页面上下文 InnerTube + caption XML 解析)
04登录/CAPTCHA 交互等待模式(interaction 自动检测 / force 手动控制)
05媒体下载与链接重写(--download-media 落 imgs/ 与 videos/,可 --media-dir)
06调试取证:--debug-dir 落 document.json / markdown.md / page.html / network.json(含请求头与响应体)
07X 会话持久化(cookie sidecar 导出/回灌)与 CDP 调试会话复用
08质量门禁流程(无头结果视为暂定,人工/agent 复检后可切交互模式重抓)

3外部依赖

类型依赖
package@mozilla/readability ^0.6.0(正文提取)
packagedefuddle ^0.17.0(本地 markdown 提取)
packagejsdom ^30.0.1(HTML 清洗/解析,未开 runScripts)
packageturndown + turndown-plugin-gfm(HTML→markdown)
packagechrome-launcher ^1.2.1(浏览器启动)
packagews ^8.18.3(CDP WebSocket 客户端)
packageunified + remark-parse + remark-gfm(媒体链接收集与重写)
clibun(CLI 运行时;shell 包装 exec bun)
cliChrome/Chromium 二进制(chrome-launcher,可用 --browser-path 指定)
clips aux(POSIX 进程扫描)与 osascript(macOS 窗口激活)
networkChrome DevTools HTTP/WebSocket 端点
api第三方 markdown 服务 defuddle.md(质量不足时把目标 URL 发过去)
networkYouTube watch 页、InnerTube player、caption 轨与 i.ytimg.com 缩略图
networkHacker News 条目页(jsdom 解析)
networkX/Twitter 页面与页面自身发出的 /graphql/ 请求(工具只观察,不构造请求)
network用户指定 URL 与页面内媒体 URL(下载时带伪造的桌面 Chrome UA)

4风险提醒 风险提醒:红色 · 谨慎使用

风险提醒:红色 · 谨慎使用
  • X 会话 cookie 明文落盘(判红要素之一) — auth_token/ct0 等会以明文 JSON 写在 Chrome profile 目录的 x-session-cookies.json,无加密与权限收紧;共享机器或备份同步目录下需格外注意,用后应清理。
  • 逆向/冒充 YouTube 客户端(判红要素之一) — 页面内 InnerTube 调用 + ANDROID 客户端冒充,属绕过平台检测的路线;随 YouTube 风控变化而失效,也可能触发账号侧限制。
  • 接管已运行的 Chrome 调试会话 — 会连上你正在用的调试实例(DevToolsActivePort / ps aux / --cdp-url);被接管的浏览器可能被用来导航与点击(如自动点 Show replies、滚动)。
  • 调试落盘可能包含敏感数据 — --debug-dir 会把登录后页面 HTML 与带请求头/响应体的网络日志写到磁盘,可能含 token 与私人内容,分享前务必检查。
  • 目标 URL 会发给第三方服务 — markdown 模式且本地质量不足时,目标 URL 被送到 https://defuddle.md;内网/带 token 的链接不宜走该兜底。
  • 文档与实现滑移导致预期错位 — 『默认无头』与『默认 profile 相对路径』两处均与代码不符,cookie 导出更是完全未披露——使用前应以源码为准。
风险提醒:红色,谨慎使用(属能力/策略级判定,非恶意植入:代码结构清晰、无混淆、无硬编码密钥、无 TLS/沙箱降级)。三层理由:①【逆向/冒充】YouTube 适配器不走官方 Data API,而是在页面上下文自建 InnerTube 请求('const response = await fetch(\'/youtubei/v1/player?key=\' + apiKey + \'&prettyPrint=false\', {',带 credentials: \'include\',key 取自 window.ytcfg),并显式冒充官方客户端('context: { client: { clientName: \'ANDROID\', clientVersion: \'20.10.38\' } },');与同仓 baoyu-youtube-transcript 属同一族红线。②【凭证明文落盘与调试会话接管】X 适配器把 auth_token/ct0 在内的 x.com/twitter.com cookie 明文写进 <chrome-profile-dir>/x-session-cookies.json('await writeFile(filePath, JSON.stringify(data, null, 2));',无加密),并按需回灌;同时通过 DevToolsActivePort / ps aux 接管已在运行的 Chrome 调试会话(--cdp-url 可连任意 ws 调试端点);--debug-dir 会把请求头与响应体整包落盘('const networkDump = await network.toJSON({ includeBodies: true });')。③【第三方外发与伪装请求】本地提取质量不足时把目标 URL 交给第三方 https://defuddle.md 取 markdown;媒体下载请求带伪造的桌面 Chrome UA;页面内容可决定后续抓取目标与落盘文件名。程度说明:cookie 用于其声明的用途(抓取需登录的 X 内容)、无 TLS 降级、无未转义插值、jsdom 不执行页面脚本、有登录/CAPTCHA 等待模式而非硬闯。

5第二遍独立确认

  • [ok] YouTube 适配器的逆向/冒充 — transcript.ts 有 window.ytcfg?.data_?.INNERTUBE_API_KEY、页面内 POST /youtubei/v1/player?key=…(credentials: 'include')与 context.client.clientName='ANDROID' 三处,与 Main 终裁的『逆向 youtubei + 冒充官方客户端』一致。
  • [ok] X cookie 明文 sidecar 落盘 — cookie-sidecar.ts 用 Network.getCookies 取 cookie 后 JSON.stringify 明文写入 <profile>/x-session-cookies.json(x/index.ts 指定 filename),无加密无 chmod;convert.ts 在开头尝试回灌、finally 里导出。
  • [ok] 接管已运行调试会话 — profile.ts 解析 DevToolsActivePort 并 spawnSync('ps', ['aux']) 匹配 profileDir + --remote-debugging-port;chrome-launcher.ts 支持 --cdp-url ws:// 直连与复用日志 'Reusing Chrome debugger at …'。
  • [ok] 网络日志含请求头与响应体(--debug-dir 落盘) — network-journal.ts 记录 requestHeaders / requestBody / 响应体(Network.getResponseBody),convert.ts 在写 debug 前调用 toJSON({ includeBodies: true }) 并写入 network.json。
  • [ok] 第三方 defuddle.md 兜底 — DEFUDDLE_API_ORIGIN=https://defuddle.md,构建 URL 后 fetch;通用适配器仅在 outputFormat==='markdown' 时启用该兜底,JSON 模式不会外发目标 URL。
  • [discrepancy] 文档与实现不一致(默认无头) — SKILL.md 第 93 行写 '# Default: headless capture, markdown to stdout'、quality-gate.md 亦写 'Default | Headless Chrome',但 cli.ts 默认 headless: false(convert.ts 在非交互模式传该值),实际会启动可见 Chrome(--no-startup-window)。使用前应知道默认并非无头。
  • [discrepancy] 文档与实现不一致(默认 profile 路径) — SKILL.md 写默认 ./baoyu-skills/chrome-profile,代码实际解析为按 OS 的绝对路径(XDG_DATA_HOME / Application Support / APPDATA 下的 baoyu-skills/chrome-profile),从不使用 cwd 相对路径。
  • [discrepancy] 文档未披露 cookie 导出 — SKILL.md 只写 BAOYU_CHROME_PROFILE_DIR 为『Chrome user data directory』,从未提及会导出 X cookie 到 sidecar 文件;该行为只在代码中可见——这是本次侦查中风险披露落差最大的一处。

6结论

  • 一个 CLI 覆盖四类站点,且有质量门禁流程而不是『抓到就算成功』。
  • 对需要登录的页面有正解:交互等待模式让用户手动过登录/CAPTCHA,检测到进展自动继续。
  • 手写 CDP 客户端依赖少、可控:chrome-launcher + ws,不引入 puppeteer 栈。
  • 调试友好:--debug-dir 一次拿到 document/markdown/page.html/network 四类取证文件。
  • 媒体本地化完整:--download-media 下载并重写链接,imgs/videos 与 markdown 同目录自包含。
  • 适合:适合需要把网页/推文长贴/YouTube 字幕/HN 讨论保存为 markdown 的个人与内容工作者:要本地留档、要媒体一起落盘、要处理登录墙(手动过一次),并能接受使用真实 Chrome 与自建 CDP 流程。
    不适合:不适合企业合规或隐私敏感环境(明文 X cookie sidecar、调试落盘、第三方 defuddle.md 外发);不适合无人值守的大批量抓取(交互等待与真实浏览器成本高);不适合要求稳定官方接口的管道;也不适合把它指向内网/私有 URL 或他人账号会话使用。
    安装 agent 直装可复制
    ① 本站镜像 更新 2026-09-15
    方式 A · 人下载镜像包下载 baoyu-url-to-markdown.tar.gz
    sha256: 15be54497a8d6c30…
    方式 B · JSON 格式安装指南,复制给 agent
    安装指南
    agent 读 JSON 指南后会自动从本站下载安装,无需更多说明。
    ② 上游 GitHub · 原始来源
    能访问 GitHub?直接去上游安装(实时版,可能已更新)GitHub 原始 ↗
    本页镜像锁定 commit 1567581c26;上游为实时仓库。
    来源信息 GitHub 原始
    作者 / 仓库JimLiu / JimLiu/baoyu-skills
    Stars25926
    最近推送2026-09-10
    本 skill commit1567581c26
    许可MIT(仓库根 LICENSE:Copyright (c) 2026 Jim Liu;根 package.json 同声明 "license": "MIT")
    本站信息
    收录日期2026-09-06
    分类文档与知识
    侦查报告AI 侦查 · 2 遍 · 2026-09-06
    本站镜像与 GitHub 原始是不同来源:本站锁定 commit 快照经 /r2 分发;GitHub 为实时上游,内容可能已更新。
    同分类邻近