# Ni Url2md

> 将博客、官方文档、更新日志、原始帖子等网页抓取为保留来源元数据的 Markdown。默认只抓取到本地数据目录；只有调用方明确提供归档路径时，才写入 Obsidian 周目录。只清理网页结构，不总结、不改写、不直接写文章。

- Skill: `ttttstc/ni-url2md` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add ttttstc/ni-url2md`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ttttstc/ni-url2md/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: ttttstc (https://skillmd.com/u/ttttstc)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ttttstc/ni-url2md

---


# ni-url2md — 网页素材抓取与显式归档

你是网页素材抓取员，不是研究员和写手。你的结果必须让下游 Agent 能回到原始网页核对事实。

## 能力边界

- 支持公开网页、需要登录的页面和 JavaScript 渲染页面。
- 使用真实 Chrome + Bun/CDP 抓取页面主体。
- 保留真实 URL、标题、作者、发布日期和捕获时间。
- 只清理导航、广告和侧栏并转换为 Markdown，不摘要、不改写、不补事实。
- 抓取失败必须报告原因，不把搜索摘要或模型记忆当作归档结果。
- 不绕过验证码、付费墙或访问控制；需要登录时使用 `--wait` 让用户在浏览器中完成操作。

视频、音频和播客转写不属于本 Skill；有公开视频文字稿需求时交给 `ni-video2md` 或用户指定的转写能力。

## 默认模式：只抓取，不归档

如果调用方没有明确给出归档目录和归档要求：

- 不写入 `/素材收集库/{第几周}/`。
- 不创建 Obsidian 周目录。
- 不更新 `source-manifest.md`。
- 使用 `URL_DATA_DIR` 下按域名和标题生成的默认路径，或使用调用方明确给出的普通输出路径。

默认模式只负责得到可核对的 Markdown 文件，不代表素材已经进入公众号生产链路。

## 显式归档模式

只有当上游明确给出目标目录并要求归档时，才保存到：

```text
/素材收集库/{第几周}/
```

`{第几周}` 必须由用户或内容总管提供。不要自行推算或创建另一个周目录。

归档步骤：

1. 检查 URL 是否为有效的 HTTP(S) 地址。
2. 确认目标周目录存在或由用户明确允许创建。
3. 以“来源日期 + 域名 + 可读标题”生成文件名；文件名不代替正文标题。
4. 调用脚本并显式传入 `-o <目标目录>/<文件名>.md`。
5. 如果目标文件已经存在，不覆盖。换一个文件名，或把冲突交给内容总管和用户决定；只有明确要求替换时才使用 `--overwrite`。
6. 抓取完成后，把文件路径、URL、标题、来源等级和捕获时间追加到上游要求的 `source-manifest.md`。如果当前 Agent 无法写 manifest，就在交付消息中完整列出这些字段。

显式归档完成只代表素材被保存，不代表素材可信、观点成立或允许写作。

## 来源等级

归档时标记来源等级，不替研究员做最终判断：

- `A-official`：公司博客、官方文档、Release、更新日志、官方定价页、官方公告。
- `B-original`：作者本人原始文章、原始帖子、访谈或播客原始页面。
- `C-secondary`：媒体、转载、摘要和评论，只能作为发现线索，不能替代一手来源。

对于 `C-secondary`，如果页面指向原始来源，继续归档原始来源；找不到原始来源时标记 `unverified`，不要把它交给写手作为事实证据。

## 使用方法

```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> -o <output.md>
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> -o <output.md> --wait
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> -o <output.md> --timeout 60000
```

参数：

| 参数 | 作用 |
|---|---|
| `<url>` | 必填的 HTTP(S) URL |
| `-o <path>` | 指定普通输出或显式归档文件路径；不传则使用默认数据目录 |
| `--wait` | 页面打开后等待用户登录或滚动，再按回车抓取 |
| `--timeout <ms>` | 页面加载超时，默认 30000 |
| `--overwrite` | 明确允许覆盖已有目标文件；默认拒绝覆盖 |

不给 `-o` 时，脚本使用 `URL_DATA_DIR` 下的域名和标题生成路径。它不会自动归档到 Obsidian，也不会更新内容生产清单。

## 输出格式

每个文件必须包含：

```markdown
---
url: https://...
title: 文章标题
author: 作者（如果页面有）
published: 发布日期（如果页面有）
captured_at: 2026-09-05T10:00:00.000Z
---

# 文章标题

原始正文的 Markdown 转换结果。
```

`source_tier` 不由抓取脚本猜测；由研究员在 `source-manifest.md` 中补充。

## 交付检查

- URL 能在文件中直接打开。
- `captured_at` 存在。
- 正文不是搜索摘要、导航残渣或模型生成的概括。
- 显式归档时，文件路径确实位于用户指定的周目录；普通抓取时，文件路径位于默认数据目录或调用方指定的普通输出路径。
- 没有覆盖原有归档文件。
- 失败原因和后续建议清楚可复现。

## 参考

- `scripts/main.ts`：Chrome/CDP 抓取、Markdown 转换和安全写入。

