# X Article Downloader

> 使用 browser-agent 下载 X/Twitter 长文章（Article）到本地 Markdown。自动抓取文章内容、下载图片和视频，生成带元信息和标签的专业 Markdown 文档。当用户提供 x.com 链接、说"下载 X 文章"、"保存推文"、"X 转 markdown"时使用此 skill。

- Skill: `azure12355/x-article-downloader` (Agent Skill)
- Install (CLI): `npx skillmds@latest add azure12355/x-article-downloader`
- Raw SKILL.md: https://api.skillmd.com/api/skills/azure12355/x-article-downloader/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: azure12355 (https://skillmd.com/u/azure12355)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/azure12355/x-article-downloader

---


# X Article Downloader

将 X/Twitter 长文章下载为本地 Markdown，包含完整内容和媒体资源。

## 输出目录结构

```
/Users/lytton/mac_wps_clound/Obsidian笔记知识库/宝藏资源库/x-to-markdown/
└── {作者名字}/
    └── {凝练标题}/              # 使用凝练后的标题命名
        ├── {凝练标题}.md        # Markdown 文档（同目录名）
        ├── imgs/                # 图片文件夹
        │   ├── img-01.jpg
        │   ├── img-02.png
        │   └── ...
        └── videos/              # 视频文件夹（如有）
            └── video-01.mp4
```

## 完整工作流程

### Step 1: 打开页面获取内容

```bash
# 打开 X 文章页面
agent-browser open "https://x.com/{user}/status/{id}"

# 获取无障碍树内容（紧凑模式）
agent-browser snapshot -c
```

### Step 2: 创建临时输出目录

```bash
# 先用 ID 创建临时目录
OUTPUT_DIR="/Users/lytton/mac_wps_clound/Obsidian笔记知识库/宝藏资源库/x-to-markdown/{作者}/{文章ID}"
mkdir -p "${OUTPUT_DIR}/imgs"
mkdir -p "${OUTPUT_DIR}/videos"
```

### Step 3: 提取并下载图片

```bash
# 提取图片 URL
agent-browser eval "Array.from(document.querySelectorAll('img[src*=\"media\"]')).map(img => img.src).filter(src => src.includes('twimg')).join('\n')"

# 下载图片（使用 large 格式获取高清版本）
# 注意：URL 中的 format 参数不一定准确，后续需要校验实际格式
i=1
for url in "${IMAGE_URLS[@]}"; do
  printf -v num "%02d" $i
  # 转换为 large 格式
  large_url="${url}&name=large" 2>/dev/null || large_url="${url}?name=large"
  # 临时使用 jpg 扩展名，后续会校验
  curl -s -o "${OUTPUT_DIR}/imgs/img-${num}.jpg" "$large_url"
  ((i++))
done
```

### Step 4: 图片格式校验 ⭐ 重要

**问题**：X/Twitter 返回的图片实际格式可能与 URL 参数不一致，导致文件扩展名错误，Markdown 引用失效。

**解决方案**：下载完成后，必须校验图片实际格式并修正扩展名。

```bash
IMG_DIR="${OUTPUT_DIR}/imgs"

# 校验并修正图片格式
for f in "$IMG_DIR"/*; do
  if [ -f "$f" ]; then
    # 获取实际格式
    actual=$(file -b "$f" | awk '{print $1}')
    filename=$(basename "$f")
    ext="${filename##*.}"
    name="${filename%.*}"

    # 确定正确的扩展名
    case "$actual" in
      JPEG|JPG)
        correct_ext="jpg"
        ;;
      PNG)
        correct_ext="png"
        ;;
      GIF)
        correct_ext="gif"
        ;;
      WebP)
        correct_ext="webp"
        ;;
      *)
        correct_ext="$ext"
        ;;
    esac

    # 如果格式不匹配，重命名文件
    if [ "$ext" != "$correct_ext" ]; then
      mv "$f" "${IMG_DIR}/${name}.${correct_ext}"
      echo "修正: ${filename} -> ${name}.${correct_ext}"
    fi
  fi
done
```

**支持的图片格式**：

| 实际格式 | 正确扩展名 |
|----------|------------|
| JPEG/JPG | .jpg |
| PNG | .png |
| GIF | .gif |
| WebP | .webp |

### Step 5: 下载视频（如有）

```bash
# 检查是否有视频
agent-browser eval "Array.from(document.querySelectorAll('video')).map(v => v.src).join('\n')"

# 如有视频，使用 yt-dlp 下载
yt-dlp "https://x.com/{user}/status/{id}" -o "${OUTPUT_DIR}/videos/video-01.%(ext)s"
```

### Step 6: 关闭浏览器

```bash
agent-browser close
```

### Step 7: 生成 Markdown 文档

创建包含完整元信息的 Markdown 文件（先用 ID 命名）：

**重要**：生成 Markdown 时，图片引用必须使用校验后的正确扩展名。

```markdown
---
url: "https://x.com/{user}/status/{id}"
author: "{作者名字} (@{username})"
title: "{文章标题}"
date: "{发布日期}"
stats:
  replies: {回复数}
  reposts: {转发数}
  likes: {点赞数}
  bookmarks: {收藏数}
  views: {浏览数}
tags:
  - {标签1}
  - {标签2}
  - {标签3}
---

# {文章标题}

![封面](imgs/img-01.jpg)

{文章正文...}

![图片描述](imgs/img-02.png)

{更多内容...}
```

### Step 8: 凝练标题并重命名 ⭐

**这是关键步骤：将文章总结成一个凝练的标题，然后重命名目录和文件。**

#### 标题凝练规则

1. **提取核心主题**：从文章内容中提取 1-2 个核心关键词
2. **格式**：`{核心主题}-{补充说明}` 或 `{动词}{对象}-{方法/工具}`
3. **长度**：控制在 10-20 个字符
4. **避免**：不要使用原标题（通常太长）
5. **使用中文**：除非原文是英文技术术语

#### 标题凝练示例

| 原标题 | 凝练标题 |
|--------|----------|
| 别再用提示词去 AI 味了，方向就是错的 | 去AI味的正确方法-WritingStyleSkill |
| 从海外公司注册到 Stripe 收款，跑通了出海收付款全流程 | 海外公司注册与Stripe收款指南 |
| 上一篇近百万阅读后，我把个人AI系统升级到了第二代｜架构全公开 | AI系统V2架构-25个优化方法 |
| Skills的最正确用法，是将整个Github压缩成你自己的超级技能库 | GitHub开源项目Skill化指南-打造超级技能库 |

#### 重命名命令

```bash
OLD_DIR="/path/to/x-to-markdown/{作者}/{文章ID}"
NEW_TITLE="凝练后的标题"

# 重命名目录
mv "$OLD_DIR" "/path/to/x-to-markdown/{作者}/${NEW_TITLE}"

# 重命名 Markdown 文件
mv "/path/to/x-to-markdown/{作者}/${NEW_TITLE}/{文章ID}.md" \
   "/path/to/x-to-markdown/{作者}/${NEW_TITLE}/${NEW_TITLE}.md"
```

## 元信息提取规则

从无障碍树中提取以下信息：

| 字段 | 来源 | 示例 |
|------|------|------|
| author | heading 或 link 文本 | "宝玉" |
| username | @mention 链接 | "@dotey" |
| title | 首段文本或推文内容前100字符 | |
| date | 时间链接文本 | "4:44 AM · Feb 15, 2026" |
| stats | group 中的按钮文本 | "45 replies, 238 reposts, 943 likes" |

## 标签生成规则

根据文章内容自动生成 3-5 个标签：

1. 提取文章中的关键词（技术名词、产品名、概念）
2. 识别文章主题分类（教程、分享、新闻等）
3. 提取涉及的平台/工具名称

## 图片链接格式

使用相对路径，带描述性 alt 文本。**必须使用校验后的正确扩展名**：

```markdown
![封面](imgs/img-01.jpg)
![流程图](imgs/img-02.png)
![截图说明](imgs/img-03.webp)
```

## 常见问题

| 问题 | 解决方案 |
|------|----------|
| 图片下载失败 | 检查 URL 格式，添加 `?name=large` 参数 |
| 图片格式错误 | 执行 Step 4 格式校验，修正扩展名 |
| 内容未完全加载 | 等待几秒后重新获取 snapshot |
| 视频无法下载 | 使用 yt-dlp 命令行工具 |
| 作者名含特殊字符 | 替换为下划线或拼音 |
| 标题含特殊字符 | 替换为连字符或移除 |

## 完整示例

```bash
# 1. 打开页面
X_URL="https://x.com/Khazix0918/status/2013812311388229792"
agent-browser open "$X_URL"

# 2. 获取内容
agent-browser snapshot -c

# 3. 创建临时目录
AUTHOR="Khazix0918"
TWEET_ID="2013812311388229792"
OUTPUT="/Users/lytton/mac_wps_clound/Obsidian笔记知识库/宝藏资源库/x-to-markdown/${AUTHOR}/${TWEET_ID}"
mkdir -p "${OUTPUT}/imgs" "${OUTPUT}/videos"

# 4. 提取图片 URL 并下载
agent-browser eval "Array.from(document.querySelectorAll('img[src*=\"media\"]')).map(img => img.src).filter(src => src.includes('twimg')).join('\n')"
# 下载图片...

# 5. 图片格式校验 ⭐
for f in "${OUTPUT}/imgs"/*; do
  if [ -f "$f" ]; then
    actual=$(file -b "$f" | awk '{print $1}')
    filename=$(basename "$f")
    ext="${filename##*.}"
    name="${filename%.*}"
    case "$actual" in
      JPEG|JPG) correct_ext="jpg" ;;
      PNG) correct_ext="png" ;;
      GIF) correct_ext="gif" ;;
      WebP) correct_ext="webp" ;;
      *) correct_ext="$ext" ;;
    esac
    if [ "$ext" != "$correct_ext" ]; then
      mv "$f" "${OUTPUT}/imgs/${name}.${correct_ext}"
    fi
  fi
done

# 6. 关闭浏览器
agent-browser close

# 7. 生成 Markdown 文件（使用校验后的扩展名）
# 写入 ${OUTPUT}/${TWEET_ID}.md

# 8. 凝练标题并重命名
NEW_TITLE="GitHub开源项目Skill化指南-打造超级技能库"
BASE_DIR="/Users/lytton/mac_wps_clound/Obsidian笔记知识库/宝藏资源库/x-to-markdown/${AUTHOR}"
mv "${BASE_DIR}/${TWEET_ID}" "${BASE_DIR}/${NEW_TITLE}"
mv "${BASE_DIR}/${NEW_TITLE}/${TWEET_ID}.md" "${BASE_DIR}/${NEW_TITLE}/${NEW_TITLE}.md"
```

## 工作流程检查清单

```
X Article Download Progress:
- [ ] Step 1: 打开页面获取无障碍树
- [ ] Step 2: 创建临时输出目录（用 ID）
- [ ] Step 3: 提取并下载图片
- [ ] Step 4: 图片格式校验 ⭐ 重要
- [ ] Step 5: 下载视频（如有）
- [ ] Step 6: 关闭浏览器
- [ ] Step 7: 生成 Markdown 文档（使用正确扩展名）
- [ ] Step 8: 凝练标题并重命名目录和文件 ⭐
```

