mcpField
A
article-extractor

article-extractor

github.com/dedalus-erp-pas生産性196 回インストール
リポジトリ

article-extractor について

ウェブ記事やブログから本文を抽出するスキルで、読みやすいテキストを保存したい人向けです。reader、trafilatura、curl による簡易処理の順で試し、結果をテキストファイルに保存します。

主な機能

  1. 01ページの不要部分を除いて本文を抽出
  2. 02優先順に抽出ツールを選択
  3. 03抽出テキストの整形
  4. 04記事タイトルをファイル名に使用
  5. 05失敗時に代替方法を試行

活用シーン

  1. 01記事の URL をテキストとして保存
  2. 02ブログ本文を読書用に抽出
  3. 03タイトルと著者情報付きで記事を保存

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dedalus-erp-pas/foundation-skills --skill article-extractor

インストール後、Claude Code で/article-extractorを入力して読み込まれたか確認します。

詳細

記事の抽出

このスキルは、ウェブ記事やブログ投稿から本文を抽出し、ナビゲーション、広告、ニュースレターの登録フォームなどの不要な要素を取り除きます。読みやすく整えたテキストとして保存します。

前提条件

次のいずれかが必要です。

  • Node.js 18+ と npm — reader に必要です(npm install -g reader-cli)
  • Python 3 と pip — trafilatura に必要です(pip3 install trafilatura)

どちらもインストールされていない場合、スキルは基本的な curl ベースの抽出にフォールバックします(インストール不要)。

このスキルを使用するタイミング

ユーザーが次の操作をしたときに有効にします。

  • 記事やブログの URL を提示し、本文を求める
  • 「この記事をダウンロードして」と依頼する
  • 「[URL] から内容を抽出して」と求める
  • 「このブログ投稿をテキストとして保存して」と依頼する
  • 邪魔な要素のない記事のテキストを必要とする

動作の仕組み

優先順位:
  1. ツールがインストールされているか確認する(reader または trafilatura)
  2. 利用可能な最適なツールで記事をダウンロードして抽出する
  3. 内容を整える(余分な空白を取り除き、適切に書式を整える)
  4. 記事のタイトルをファイル名にして保存する
  5. 保存先を確認し、プレビューを表示する

インストール状況の確認

次の順序で記事抽出ツールを確認します。

オプション 1:reader(推奨 — Mozilla の Readability)
command -v reader

インストールされていない場合:

npm install -g @mozilla/readability-cli
# or
npm install -g reader-cli
オプション 2:trafilatura(Python ベースで非常に優秀)
command -v trafilatura

インストールされていない場合:

pip3 install trafilatura
オプション 3:フォールバック(curl + 簡易パース)

利用できるツールがない場合は、基本的な curl とテキスト抽出を使用します(信頼性はやや劣りますが、動作します)。

抽出方法

方法 1:reader を使用する(ほとんどの記事に最適)
# Extract article
reader "URL" > article.txt

利点:

  • Mozilla の Readability アルゴリズムに基づいています
  • 不要な要素を取り除く性能に優れています
  • 記事の構成を保持します
方法 2:trafilatura を使用する(ブログやニュースに最適)
# Extract article
trafilatura --URL "URL" --output-format txt > article.txt

# Or with more options
trafilatura --URL "URL" --output-format txt --no-comments --no-tables > article.txt

利点:

  • 非常に正確に抽出できます
  • さまざまなサイト構成に対応しています
  • 複数の言語を処理できます

オプション:

  • --no-comments:コメント欄をスキップします
  • --no-tables:データテーブルをスキップします
  • --precision:再現率より適合率を優先します
  • --recall:より多くの内容を抽出します(ノイズが含まれる場合があります)
方法 3:フォールバック(curl + 基本的なパース)
# Download and extract basic content
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 '\\n\\n'.join(self.content)

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

注: 信頼性はやや劣りますが、依存関係なしで動作します。

記事のタイトルを取得する

ファイル名に使用するタイトルを抽出します。

reader を使用する場合:
# reader outputs markdown with title at top
TITLE=$(reader "URL" | head -n 1 | sed 's/^# //')
trafilatura を使用する場合:
# Get metadata including title
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/ | .*//')

ファイル名の作成

ファイルシステムで使えるようにタイトルを整えます。

# Get title
TITLE="Article Title from Website"

# Clean for filesystem (remove special chars, limit length)
FILENAME=$(echo "$TITLE" | tr '/' '-' | tr ':' '-' | tr '?' '' | tr '"' '' | tr '<' '' | tr '>' '' | tr '|' '-' | cut -c 1-100 | sed 's/ *$//')

# Add extension
FILENAME="${FILENAME}.txt"

ワークフロー全体

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

# Check for tools
if command -v reader &> /dev/null; then
    TOOL="reader"
    echo "Using reader (Mozilla Readability)"
elif command -v trafilatura &> /dev/null; then
    TOOL="trafilatura"
    echo "Using trafilatura"
else
    TOOL="fallback"
    echo "Using fallback method (may be less accurate)"
fi

# Extract article
case $TOOL in
    reader)
        # Get content
        reader "$ARTICLE_URL" > temp_article.txt
        # Get title (first line after # in markdown)
        TITLE=$(head -n 1 temp_article.txt | sed 's/^# //')
        ;;
    trafilatura)
        # Get title from metadata
        METADATA=$(trafilatura --URL "$ARTICLE_URL" --json)
        TITLE=$(echo "$METADATA" | python3 -c "import json, sys; print(json.load(sys.stdin).get('title', 'Article'))")
        # Get clean content
        trafilatura --URL "$ARTICLE_URL" --output-format txt --no-comments > temp_article.txt
        ;;
    fallback)
        # Get title
        TITLE=$(curl -s "$ARTICLE_URL" | grep -oP '<title>\K[^<]+' | head -n 1)
        TITLE=${TITLE%% - *}  # Remove site name
        TITLE=${TITLE%% | *}  # Remove site name (alternate)
        # Get content (basic extraction)
        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('\\n')

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

    def get_content(self):
        return '\\n\\n'.join(self.content)

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

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

# Move to final filename
mv temp_article.txt "$FILENAME"

# Show result
echo "✓ Extracted article: $TITLE"
echo "✓ Saved to: $FILENAME"
echo ""
echo "Preview (first 10 lines):"
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. 抽出品質を確認する:

  • 必ずユーザーにプレビューを表示します
  • 正しく見えるかユーザーに確認します
  • 必要に応じて、別のツールを試すことを提案します

使用例

シンプルな抽出:

# User: "Extract 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 "✓ Saved to: $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 "Error: Could not extract article. Install reader or trafilatura."
        exit 1
    fi
fi

ベストプラクティス

  • ✅ 抽出後は必ずプレビュー(最初の10行)を表示します
  • ✅ 保存する前に抽出が成功したことを確認します
  • ✅ ファイルシステムとの互換性を考慮してファイル名を整えます
  • ✅ 主要な方法が失敗した場合は代替方法を試します
  • ✅ 使用したツールをユーザーに伝えます
  • ✅ ファイル名は適切な長さ(100文字未満)にします

抽出後

ユーザーに次の内容を表示します:

  1. 「✓ 抽出済み:[記事タイトル]」
  2. 「✓ 保存先:[ファイル名]」
  3. プレビュー(最初の10~15行)を表示します
  4. ファイルサイズと保存場所

必要に応じて質問します:

  • 「この内容から Ship-Learn-Next プランも作成しますか?」(ship-learn-next スキルを使用する場合)
  • 「別の記事も抽出しますか?」

コメント