agentsclimarketplace

Juejin article to markdown

Skill HK-hub/AgentSkills/juejin-article-to-markdown

将掘金(juejin.cn)文章转换为整洁的 Markdown 文件,自动去除导航栏、评论区、推荐文章等无关内容,正确处理代码块、表格、图片等格式。当用户提供掘金文章链接或要求保存掘金文章时使用此技能。From its SKILL.md

Install
npx -y skills add HK-hub/AgentSkills --skill juejin-article-to-markdown

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

12.9 KB, ~4.5k tokens by cl100k_base, as published. Nobody here has run it

掘金文章转 Markdown

概述

掘金文章页面包含大量无关内容(导航栏、侧边栏、评论区、推荐文章、代码块按钮等),直接复制粘贴会产生格式问题。此 Skill 提供一套完整的处理流程,将掘金文章转换为干净、规范的 Markdown 文件。

触发条件

  • 用户提供掘金文章链接(juejin.cn/post/
  • 用户说"保存掘金文章"、"另存掘金为 Markdown"
  • 用户想要整理掘金文章到笔记库

完整处理流程

第一步:获取文章内容

同时获取 HTML 和 Markdown 两种格式(并行请求):

# 请求 1:HTML 格式(用于提取元信息和图片位置)
mcp__ScraplingServer__stealthy_fetch
  - url: 掘金文章链接
  - extraction_type: html
  - main_content_only: true
  - wait: 2000

# 请求 2:Markdown 格式(用于提取正文内容)
mcp__ScraplingServer__stealthy_fetch
  - url: 掘金文章链接
  - extraction_type: markdown
  - main_content_only: true
  - wait: 2000

第二步:提取文章元信息

从 HTML 或 Markdown 开头提取:

字段提取方式说明
标题<h1># 标题文章主标题
作者作者名称字段作者用户名
发布日期日期字段格式:YYYY-MM-DD
阅读量阅读数字段可选
标签标签列表文章标签
专栏专栏名称可选

第三步:清理无关内容

必须移除的内容:

  1. 导航栏和页眉

    • 首页、沸点、课程、数据标注、AI Coding 等导航
    • 搜索框
    • 创作者中心
    • 登录/注册按钮
  2. 侧边栏和推荐

    • 搜索建议
    • 精选内容
    • 为你推荐文章列表
    • 目录(可选择性保留简化版)
  3. 评论区

    • 评论列表
    • 评论输入框
    • 点赞、屏蔽、举报按钮
  4. 页脚和推广

    • 下载APP提示
    • 微信公众号二维码
    • 新浪微博链接
    • AI代码助手推广
  5. 代码块无关内容

    • "体验AI代码助手"按钮文字
    • "代码解读"按钮文字
    • "复制代码"按钮文字
  6. 互动元素

    • 点赞、收藏、分享按钮
    • 关注按钮
    • 专栏订阅按钮

第四步:处理代码块

掘金代码块会包含无关的按钮文字,需要清理:

清理模式:

# 原始(有问题)
```bash

体验AI代码助手

代码解读

复制代码

# 实际代码
git clone https://github.com/xxx

清理后

# 实际代码
git clone https://github.com/xxx

**处理规则:**
1. 识别代码块开始(```language)
2. 删除代码块开头的空白行
3. 删除"体验AI代码助手"、"代码解读"、"复制代码"等无关行
4. 保留实际代码内容
5. 确保代码块正确闭合

### 第五步:处理图片

**掘金图片特点:**

| 域名 | 处理方式 | 说明 |
|------|---------|------|
| `p*-xtjj-sign.byteimg.com` | **保留** | 文章正文图片 |
| `p*-juejin-sign.byteimg.com` | **保留** | 文章正文图片 |
| `p1-juejin.byteimg.com` | **保留** | 封面图等 |
| `lf-web-assets.juejin.cn` | **丢弃** | Logo、图标等装饰 |
| `p*-passport.byteacctimg.com` | **丢弃** | 用户头像 |

**图片链接格式:**

https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/xxx~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:q75.awebp?rk3s=xxx&x-expires=xxx&x-signature=xxx


**处理方式:**
- 保留完整链接(包括签名参数)
- 链接有时效性,但通常较长

### 第六步:处理链接

**掘金外链跳转格式:**

https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fxxx


**处理规则:**
1. 解析 `target` 参数,提取真实 URL
2. URL 解码(%3A → :, %2F → /)
3. 替换为真实链接

**示例:**
```markdown
# 原始
[GitHub 仓库](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2F598572%2Fxzll-im-server)

# 处理后
[GitHub 仓库](https://github.com/598572/xzll-im-server)

第七步:处理表格

掘金使用标准 Markdown 表格格式,需要确保:

  1. 表头分隔行正确(| --- | --- |
  2. 列对齐符号正确(:---, :---:, ---:
  3. 表格前后有空行

表格示例:

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | Long | 全局唯一ID |
| name | String | 用户名 |

第八步:处理 Mermaid 图表

掘金使用 bytemd-mermaid 类渲染 Mermaid 图表,需要特殊处理。

重要发现:原始 Mermaid 代码存储在 window.__NUXT__ 数据中

掘金在服务端将 Mermaid 代码渲染为 SVG 用于页面显示,但原始 Mermaid 代码保存在页面的 window.__NUXT__ JavaScript 变量中。

方案 A:从 __NUXT__ 提取原始 Mermaid 代码(推荐)

优点:保留可编辑的源码,Obsidian/Typora 等工具可直接渲染

提取方法

  1. 在 HTML 中查找 <script>window.__NUXT__= 标签
  2. 提取脚本内容
  3. 解码转义序列(\n → 换行,\uXXXX → Unicode 字符)
  4. 使用正则表达式提取 ```mermaid\n...\n``` 代码块

Python 示例代码

import re

# 找到 __NUXT__ 脚本
script_match = re.search(r'<script[^>]*>window\.__NUXT__\s*=', html_content)
if script_match:
    script_start = script_match.start()
    script_end = html_content.find('</script>', script_start)
    script_content = html_content[script_start:script_end]

    # 解码 Unicode 转义
    decoded = re.sub(r'\\u([0-9a-fA-F]{4})',
                     lambda m: chr(int(m.group(1), 16)), script_content)
    decoded = decoded.replace('\\n', '\n')

    # 提取 Mermaid 代码块
    pattern = r'```mermaid\n(.*?)```'
    mermaid_blocks = re.findall(pattern, decoded, re.DOTALL)

输出格式

\`\`\`mermaid
sequenceDiagram
    participant C as 客户端
    C->>G: 登录请求
\`\`\`

方案 B:提取 SVG 并保存为文件(备选)

适用场景__NUXT__ 中没有 Mermaid 代码时

提取方法

从 HTML 中查找以下结构:

<div class="bytemd-mermaid" style="line-height: initial;">
  <svg aria-roledescription="flowchart-v2" ...>...</svg>
</div>

处理步骤

  1. 在 HTML 中查找 class="bytemd-mermaid" 元素
  2. 检查是否包含 <svg> 内容
  3. 如果有 SVG,提取完整的 <svg>...</svg> 内容
  4. 保存为 .svg 文件,命名为对应章节标题
  5. 在 Markdown 中使用图片引用

注意事项

  • 部分 bytemd-mermaid div 可能是空的(作者未添加内容),需要跳过
  • SVG 文件较大(通常 30-50KB),需要单独存储
  • 使用相对路径引用:![流程图](images/日期-文章名/图表名.svg)
![流程图](https://mermaid.ink/img/Z3JhcGggVEQ7IEEtLT5COw==)

方案 C:截图保存(备选)

如果无法提取原始代码,可以截图渲染后的 SVG:

// Playwright 截图示例
const element = await page.$('.bytemd-mermaid svg');
await element.screenshot({ path: 'mermaid-diagram.png' });

注意:此方法需要额外的图片存储。

处理建议

场景推荐方案
使用 Obsidian/Typora方案 A(保留代码)
需要通用兼容方案 B(mermaid.ink 图片)
离线使用方案 C(截图保存)

第九步:处理列表

有序列表:

1. 第一步
2. 第二步
3. 第三步

无序列表:

- 项目一
- 项目二
- 项目三

嵌套列表:

1. 主项目
   - 子项目一
   - 子项目二
2. 下一个主项目

处理规则:

  1. 确保列表项前后有空行
  2. 嵌套使用 2 或 4 空格缩进
  3. 列表符号统一(无序用 -,有序用 1. 2. 等)

第十步:添加元信息

在文件开头添加 YAML frontmatter:

---
title: 文章标题
author: 作者名称
source: 原始链接
date_saved: 保存日期
tags: [掘金, 其他标签]
---

第十一步:保存文件

文件命名规则:

  • 格式:YYYY-MM-DD-标题摘要.md
  • 标题摘要:取标题前 30 字符,去除特殊字符
  • 示例:2026-03-19-开源分布式IM系统介绍.md

常见问题处理

问题 1:代码块格式混乱

原因:掘金代码块包含按钮文字

解决方案

清理代码块开头的前 3-5 行无关内容
保留实际代码
确保语言标识正确

问题 2:链接无法访问

原因:使用掘金跳转链接

解决方案

解析 link.juejin.cn?target=xxx
提取并解码真实 URL
直接使用真实链接

问题 3:图片无法显示

原因

  1. 图片链接过期
  2. 使用了头像等无关图片

解决方案

保留 p*-xtjj-sign.byteimg.com 和 p*-juejin-sign.byteimg.com 域名图片
丢弃 lf-web-assets.juejin.cn 和 passport 相关图片

问题 4:表格格式错乱

原因:表格前后缺少空行

解决方案

确保表格前后各有一个空行
检查表头分隔符
确保每行列数一致

问题 5:Mermaid 图表丢失或显示异常

原因

  1. 需要从 window.__NUXT__ 数据中提取原始 Mermaid 代码
  2. bytemd-mermaid div 可能为空(作者未添加内容)

解决方案

方案 A:从 __NUXT__ 提取原始 Mermaid 代码(推荐)
  - 查找 <script>window.__NUXT__= 标签
  - 解码 Unicode 转义序列(\uXXXX)
  - 解码换行符(\n → 实际换行)
  - 用正则提取 ```mermaid ... ``` 代码块
  - 直接嵌入 Markdown 文件

方案 B:提取 SVG 保存为文件(备选)
  - 仅当 __NUXT__ 中没有 Mermaid 代码时使用
  - 查找 .bytemd-mermaid 内的 <svg> 标签
  - 保存为 .svg 文件

方案 C:跳过空图表
  - 检查 bytemd-mermaid div 是否包含 SVG
  - 如果为空,保留章节标题但不添加图表
  - 这是作者原文就没有图表,不是转换问题

代码示例(提取 Mermaid 源码):

import re

# 找到 __NUXT__ 脚本
script_match = re.search(r'<script[^>]*>window\.__NUXT__\s*=', html)
if script_match:
    script_end = html.find('</script>', script_match.start())
    script = html[script_match.start():script_end]

    # 解码转义
    decoded = re.sub(r'\\u([0-9a-fA-F]{4})',
                     lambda m: chr(int(m.group(1), 16)), script)
    decoded = decoded.replace('\\n', '\n')

    # 提取 Mermaid 代码
    blocks = re.findall(r'```mermaid\n(.*?)```', decoded, re.DOTALL)
    for code in blocks:
        print(code)  # 输出原始 Mermaid 代码

输出模板

---
title: {{文章标题}}
author: {{作者}}
source: {{原始链接}}
date_saved: {{保存日期}}
tags: [掘金, {{其他标签}}]
---

# {{文章标题}}

> 作者:{{作者名称}}
> 来源:掘金
> 链接:{{原始链接}}
> 发布日期:{{发布日期}}

![封面图片]({{封面图片链接}})

{{正文内容}}

---

*本文由 [juejin-article-to-markdown] 自动转换*
*保存自掘金文章,仅供个人学习使用*

示例工作流

用户输入:

保存这篇掘金文章 https://juejin.cn/post/7549107076905173028

处理步骤:

  1. 并行获取 HTML 和 markdown 两种格式
  2. 提取元信息:标题、作者、日期、标签
  3. 清理导航栏:移除首页、沸点、课程等
  4. 清理代码块:删除"体验AI代码助手"等按钮文字
  5. 处理链接:解析跳转链接,提取真实 URL
  6. 处理图片:保留正文图片,丢弃装饰图片
  7. 格式化表格:确保表格格式正确
  8. 添加 frontmatter:元信息
  9. 保存文件:按命名规则保存

与微信文章处理的区别

特性微信公众号掘金
图片域名mmbiz.qpic.cnbyteimg.com
外链处理通常无外链需解析 link.juejin.cn
代码块无特殊按钮需清理按钮文字
Mermaid图表需提取原始代码或转图片
评论需移除评论区需移除评论区
推荐无推荐文章需移除推荐列表
目录通常无目录可选择性保留

注意事项

  1. 版权提醒:保存的文章仅供个人学习使用,请勿二次传播
  2. 图片时效:掘金图片链接带签名,有时效性
  3. 代码块:特别注意清理按钮文字
  4. 外链:记得解析跳转链接
  5. 表格:确保格式正确,前后有空行
  6. Mermaid 图表:掘金将 Mermaid 渲染为 SVG,需提取 SVG 保存为文件;部分 bytemd-mermaid div 可能为空(作者未添加内容)
  7. 不要添加原文不存在的内容:保持文章原意,避免曲解作者意图

相关技能

  • wechat-article-to-markdown - 处理微信公众号文章
  • pdf - 处理 PDF 文件
  • docx - 处理 Word 文档

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,764. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.