文章提取器Skill article-extractor

此技能用于从网页URL自动提取干净的文章内容,移除广告、导航和其他杂乱元素,适用于博客文章、新闻文章、教程等。关键词:文章提取、网页抓取、内容清洗、自动化工具、数据提取、Bash脚本。

后端开发 0 次安装 0 次浏览 更新于 3/16/2026

name: article-extractor description: 从URL提取干净的文章内容(博客文章、文章、教程)并保存为可读文本。当用户想要从URL下载、提取或保存文章/博客文章,去除广告、导航或杂乱内容时使用。 allowed-tools:

  • Bash
  • Write

文章提取器

此技能从网页文章和博客帖子中提取主要内容,去除导航、广告、新闻通讯注册和其他杂乱内容。保存干净、可读的文本。

何时使用此技能

在以下情况激活:

  • 用户提供文章/博客URL并希望获取文本内容
  • 用户要求“下载此文章”
  • 用户想要“从[URL]提取内容”
  • 用户要求“将此博客文章保存为文本”
  • 用户需要干净的文章文本,无干扰元素

工作原理

优先级顺序:

  1. 检查工具是否安装(reader或trafilatura)
  2. 下载并提取文章使用最佳可用工具
  3. 清理内容(移除额外空格,适当格式化)
  4. 保存到文件以文章标题为文件名
  5. 确认位置并显示预览

安装检查

按顺序检查文章提取工具:

选项1:reader(推荐 - Mozilla的Readability)

command -v reader

如果未安装:

npm install -g @mozilla/readability-cli
# 或
npm install -g reader-cli

选项2:trafilatura(基于Python,效果很好)

command -v trafilatura

如果未安装:

pip3 install trafilatura

选项3:备用方法(curl + 简单解析)

如果无可用工具,使用基本curl + 文本提取(可靠性较低但可用)

提取方法

方法1:使用reader(最适合大多数文章)

# 提取文章
reader "URL" > article.txt

优点:

  • 基于Mozilla的Readability算法
  • 优秀地去除杂乱内容
  • 保留文章结构

方法2:使用trafilatura(最适合博客/新闻)

# 提取文章
trafilatura --URL "URL" --output-format txt > article.txt

# 或带更多选项
trafilatura --URL "URL" --output-format txt --no-comments --no-tables > article.txt

优点:

  • 提取非常准确
  • 处理多种网站结构良好
  • 支持多语言

选项:

  • --no-comments: 跳过评论部分
  • --no-tables: 跳过数据表
  • --precision: 偏好精确度而非召回率
  • --recall: 提取更多内容(可能包含一些噪音)

方法3:备用方法(curl + 基本解析)

# 下载并提取基本内容
curl -s "URL" | python3 -c "
from html.parser import HTMLParser
import sys

class ArticleExtractor(HTMLParser):
    def __init__(self):
        super().__init__()
        self.in_content = False
        self.content = []
        self.skip_tags = {'script', 'style', 'nav', 'header', 'footer', 'aside'}
        self.current_tag = None

    def handle_starttag(self, tag, attrs):
        if tag not in self.skip_tags:
            if tag in {'p', 'article', 'main', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'}:
                self.in_content = True
        self.current_tag = tag

    def handle_data(self, data):
        if self.in_content and data.strip():
            self.content.append(data.strip())

    def get_content(self):
        return '

'.join(self.content)

parser = ArticleExtractor()
parser.feed(sys.stdin.read())
print(parser.get_content())
" > article.txt

注意: 此方法可靠性较低,但无需依赖项。

获取文章标题

提取标题用于文件名:

使用reader:

# reader输出带标题的markdown
TITLE=$(reader "URL" | head -n 1 | sed 's/^# //')

使用trafilatura:

# 获取元数据包括标题
TITLE=$(trafilatura --URL "URL" --json | python3 -c "import json, sys; print(json.load(sys.stdin)['title'])")

使用curl(备用方法):

TITLE=$(curl -s "URL" | grep -oP '<title>\K[^<]+' | sed 's/ - .*//' | sed 's/ | .*//')

文件名创建

清理标题以适用于文件系统:

# 获取标题
TITLE="Article Title from Website"

# 清理用于文件系统(移除特殊字符,限制长度)
FILENAME=$(echo "$TITLE" | tr '/' '-' | tr ':' '-' | tr '?' '' | tr '"' '' | tr '<' '' | tr '>' '' | tr '|' '-' | cut -c 1-100 | sed 's/ *$//')

# 添加扩展名
FILENAME="${FILENAME}.txt"

完整工作流程

ARTICLE_URL="https://example.com/article"

# 检查工具
if command -v reader &> /dev/null; then
    TOOL="reader"
    echo "使用reader(Mozilla Readability)"
elif command -v trafilatura &> /dev/null; then
    TOOL="trafilatura"
    echo "使用trafilatura"
else
    TOOL="fallback"
    echo "使用备用方法(可能准确性较低)"
fi

# 提取文章
case $TOOL in
    reader)
        # 获取内容
        reader "$ARTICLE_URL" > temp_article.txt

        # 获取标题(markdown中#后的第一行)
        TITLE=$(head -n 1 temp_article.txt | sed 's/^# //')
        ;;

    trafilatura)
        # 从元数据获取标题
        METADATA=$(trafilatura --URL "$ARTICLE_URL" --json)
        TITLE=$(echo "$METADATA" | python3 -c "import json, sys; print(json.load(sys.stdin).get('title', 'Article'))")

        # 获取干净内容
        trafilatura --URL "$ARTICLE_URL" --output-format txt --no-comments > temp_article.txt
        ;;

    fallback)
        # 获取标题
        TITLE=$(curl -s "$ARTICLE_URL" | grep -oP '<title>\K[^<]+' | head -n 1)
        TITLE=${TITLE%% - *}  # 移除站点名称
        TITLE=${TITLE%% | *}  # 移除站点名称(备选)

        # 获取内容(基本提取)
        curl -s "$ARTICLE_URL" | python3 -c "
from html.parser import HTMLParser
import sys

class ArticleExtractor(HTMLParser):
    def __init__(self):
        super().__init__()
        self.in_content = False
        self.content = []
        self.skip_tags = {'script', 'style', 'nav', 'header', 'footer', 'aside', 'form'}

    def handle_starttag(self, tag, attrs):
        if tag not in self.skip_tags:
            if tag in {'p', 'article', 'main'}:
                self.in_content = True
        if tag in {'h1', 'h2', 'h3'}:
            self.content.append('
')

    def handle_data(self, data):
        if self.in_content and data.strip():
            self.content.append(data.strip())

    def get_content(self):
        return '

'.join(self.content)

parser = ArticleExtractor()
parser.feed(sys.stdin.read())
print(parser.get_content())
" > temp_article.txt
        ;;
esac

# 清理文件名
FILENAME=$(echo "$TITLE" | tr '/' '-' | tr ':' '-' | tr '?' '' | tr '"' '' | tr '<>' '' | tr '|' '-' | cut -c 1-80 | sed 's/ *$//' | sed 's/^ *//')
FILENAME="${FILENAME}.txt"

# 移动到最终文件名
mv temp_article.txt "$FILENAME"

# 显示结果
echo "✓ 已提取文章: $TITLE"
echo "✓ 已保存到: $FILENAME"
echo ""
echo "预览(前10行):"
head -n 10 "$FILENAME"

错误处理

常见问题

1. 工具未安装

  • 尝试替代工具(reader → trafilatura → 备用)
  • 提供安装建议:“安装reader:npm install -g reader-cli”

2. 付费墙或需要登录

  • 提取工具可能失败
  • 通知用户:“此文章需要认证。无法提取。”

3. 无效URL

  • 检查URL格式
  • 尝试带或不带重定向

4. 未提取到内容

  • 网站可能使用大量JavaScript
  • 尝试备用方法
  • 如果提取失败,通知用户

5. 标题中特殊字符

  • 清理标题以适用于文件系统
  • 移除:/, :, ?, ", <, >, |
  • 替换为-或移除

输出格式

保存文件包含:

  • 文章标题(如果可用)
  • 作者(如果从工具获取)
  • 主要文章文本
  • 章节标题
  • 无导航、广告或杂乱内容

移除内容:

  • 导航菜单
  • 广告和促销内容
  • 新闻通讯注册表单
  • 相关文章侧边栏
  • 评论部分(可选)
  • 社交媒体按钮
  • Cookie通知

最佳结果技巧

1. 对大多数文章使用reader

  • 最佳通用工具
  • 基于Firefox阅读器视图
  • 适用于大多数新闻站点和博客

2. 使用trafilatura用于:

  • 学术文章
  • 新闻站点
  • 复杂布局的博客
  • 非英语内容

3. 备用方法限制:

  • 可能包含一些噪音
  • 段落检测准确性较低
  • 对简单站点比无工具好

4. 检查提取质量:

  • 始终向用户显示预览
  • 询问是否正确
  • 如果需要,提供尝试不同工具选项

示例用法

简单提取:

# 用户:“提取https://example.com/article”
reader "https://example.com/article" > temp.txt
TITLE=$(head -n 1 temp.txt | sed 's/^# //')
FILENAME="$(echo "$TITLE" | tr '/' '-').txt"
mv temp.txt "$FILENAME"
echo "✓ 已保存到: $FILENAME"

带错误处理:

if ! reader "$URL" > temp.txt 2>/dev/null; then
    if command -v trafilatura &> /dev/null; then
        trafilatura --URL "$URL" --output-format txt > temp.txt
    else
        echo "错误:无法提取文章。请安装reader或trafilatura。"
        exit 1
    fi
fi

最佳实践

  • ✅ 提取后始终显示预览(前10行)
  • ✅ 保存前验证提取成功
  • ✅ 清理文件名以适用于文件系统兼容性
  • ✅ 如果主要方法失败,尝试备用
  • ✅ 通知用户使用了哪个工具
  • ✅ 保持文件名长度合理(< 100字符)

提取后

向用户显示:

  1. “✓ 已提取:[文章标题]”
  2. “✓ 已保存到:[文件名]”
  3. 显示预览(前10-15行)
  4. 文件大小和位置

如果需要询问:

  • “您希望我从此内容中创建一个Ship-Learn-Next计划吗?”(如果使用ship-learn-next技能)
  • “我应该提取另一篇文章吗?”