Yahoo Newsの記事は一定期間で削除されることがあります。個人的な記録としてローカルに保存しておきたい場合、いくつかの手段があります。

ここでは、以下の5つの方法を同一の記事に対して実行し、結果を比較しました。

  • SingleFile CLI — 単一HTMLファイルとして保存
  • Playwright PDF — ページをPDF化
  • ArchiveBox — 複数形式を一括保存(WARC含む)
  • WARC — 標準的なウェブアーカイブ形式
  • yt-dlp — 記事内の動画をダウンロード

比較結果

手段形式フォルダサイズ広告動画
SingleFile CLI単一HTML1.3MB含まれる×
Playwright PDFPDF2.5MB含まれにくい×
ArchiveBox複数形式一括43MB含まれる
yt-dlpMP427MB-

ArchiveBoxの43MBにはSingleFile・PDF・WARC・本文抽出などが全て含まれています。全手段を併用した場合、1記事あたり約74MBのストレージを消費します。

SingleFile CLI

SingleFile は、Webページを画像・CSS込みの単一HTMLファイルとして保存するツールです。

SingleFile CLI GitHubChrome拡張版が有名ですが、CLI版もあります。

インストールと実行

npm install -g single-file-cli
single-file 'https://news.yahoo.co.jp/articles/xxxxx' output.html

不要な要素の除去

--removed-elements-selector オプションで特定の要素を除去することもできます。

single-file 'https://news.yahoo.co.jp/articles/xxxxx' output.html \
  --removed-elements-selector='header, footer, nav, aside, [id^="yads_"]'

ただし、CSSセレクタの指定によっては記事の構成要素(配信元情報、更新日時など)まで意図せず削除してしまう可能性があるため、除去する場合は保存結果を確認する必要があります。

特徴

  • 画像をBase64で埋め込むため、HTMLファイル1つで完結します
  • ブラウザでそのまま開けます
  • ページの見た目をほぼそのまま再現できます
  • 広告もそのまま保存されます
  • JavaScriptによる動的な要素(遅延読み込みの画像など)は取りこぼす場合があります

Playwright PDF

Playwrightでページを開き page.pdf() でPDF化する方法です。

スクリプト

from datetime import datetime
from playwright.sync_api import sync_playwright

def save_article_pdf(url: str, output_path: str):
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto(url, wait_until="networkidle")

        saved_at = datetime.now().strftime("%Y-%m-%d %H:%M")
        page.pdf(
            path=output_path,
            format="A4",
            margin={"top": "20mm", "right": "15mm", "bottom": "25mm", "left": "15mm"},
            print_background=True,
            display_header_footer=True,
            header_template=(
                '<div style="font-size:8px; width:100%; text-align:right;'
                ' padding-right:15mm; color:#888;">'
                '<span class="pageNumber"></span> / <span class="totalPages"></span></div>'
            ),
            footer_template=(
                f'<div style="font-size:7px; width:100%; padding:0 15mm;'
                f' color:#888; display:flex; justify-content:space-between;">'
                f'<span>出典: {url}</span>'
                f'<span>保存日時: {saved_at}</span></div>'
            ),
        )
        browser.close()

広告が含まれにくい理由

Playwrightで生成したPDFには広告がほとんど含まれていませんでした。これは以下の理由によるものと考えられます。

  • page.pdf() はCSSの @media print で描画するため、印刷時に非表示になる要素(広告枠など)は出力されません
  • Playwrightはクッキーやログイン状態のないクリーンなブラウザコンテキストで動作するため、広告配信スクリプトの挙動が通常のブラウザとは異なります

意図的に要素を除去しているわけではなく、印刷モードの仕様により結果的に広告が除かれています。

特徴

  • PDF形式のため閲覧が容易です
  • フッターに元URLと保存日時を記載でき、出典情報を保持できます
  • ページ全体をそのまま保存しつつ、広告は印刷モードの仕様により含まれにくくなります
  • 2.5MBとコンパクトです

ArchiveBox

ArchiveBox は、URLを渡すだけで複数形式のアーカイブを一括生成するセルフホスト型のツールです。

ArchiveBoxのトップページDockerでの運用が推奨されています。

セットアップと実行

mkdir -p archivebox/data && cd archivebox

# 初期化
docker run --rm -v "$(pwd)/data:/data" archivebox/archivebox:latest init --setup

# 記事を保存
docker run --rm -v "$(pwd)/data:/data" archivebox/archivebox:latest \
  add 'https://news.yahoo.co.jp/articles/xxxxx'

# Web UIで閲覧
docker run -d -p 8100:8000 -v "$(pwd)/data:/data" archivebox/archivebox:latest server 0.0.0.0:8000

生成されるファイル

1記事のアーカイブで以下のファイルが生成されました。

ファイル内容サイズ
singlefile.htmlSingleFile形式の単一HTML6.5MB
output.pdfページ全体のPDF6.7MB
output.htmlDOMスナップショット764KB
readability/content.htmlReadabilityによる本文抽出14KB
readability/content.txtプレーンテキスト本文3KB
mercury/Mercury Parserによる本文抽出-
htmltotext.txt全テキスト58KB
warc/*.warc.gzWARC形式619KB
media/メディアファイル-
archive.org.txtWayback Machineへの登録URL-

特徴

  • 1コマンドでSingleFile・PDF・WARC・本文抽出など複数形式を一括保存できます
  • Web UIで保存済みの記事を検索・閲覧できます
  • Readability / Mercuryによる本文抽出も自動で行われます
  • Wayback Machineへの自動登録もデフォルトで有効です
  • ページ全体をそのまま保存するため、広告やコメントも含まれます
  • 1記事あたり43MBと、ストレージ消費は大きくなります

WARC形式

WARC(Web ARChive)はInternet Archiveが採用している標準的なアーカイブ形式(ISO 28500)です。今回はArchiveBoxが内部でwgetを使って自動生成したものを確認しました。

619KBの .warc.gz ファイルが生成され、54のWARCレコード(HTTPリクエスト/レスポンスのペア)が記録されていました。HTTPレベルでの通信をそのまま記録する形式のため、ページの取得時の状態を再現できます。

wgetが取得する範囲はHTMLと関連リソース(CSS・画像等)であり、JavaScriptで動的に読み込まれる広告は含まれにくくなります。

閲覧には ReplayWeb.page などの専用ツールが必要です。ブラウザ上でWARCファイルをドラッグ&ドロップして開く形式のWebアプリです。

ReplayWeb.page

なお、WARCはArchiveBoxの出力に含まれるため、個別に生成する必要はありません。

yt-dlp(動画の保存)

記事に埋め込まれた動画は、上記のいずれの手段でも保存されません。動画が必要な場合は yt-dlp で別途ダウンロードします。

yt-dlpはYahoo Japan Newsに対応したエクストラクター(yahoo:japannews)を持っており、記事URLを指定するだけで動画を取得できます。

インストール

brew install yt-dlp ffmpeg

または:

pip install yt-dlp

ffmpegはHLSのデコードに必要です。

実行

yt-dlp 'https://news.yahoo.co.jp/articles/xxxxx'

出力先を指定する場合:

yt-dlp -o '~/Downloads/%(title)s.%(ext)s' 'https://news.yahoo.co.jp/articles/xxxxx'

動作の仕組み

Yahoo Newsの記事ページには、サーバーサイドレンダリング時に埋め込まれたJSON(__PRELOADED_STATE__)が含まれています。この中に動画のメタデータがあります。

"video":{"autostart":1,"vid":XXXXXXXX,"credit":"...","durationString":"X:XX"}

yt-dlpはこのJSONからvidを抽出し、Yahoo側の動画配信APIからHLSマニフェスト(.m3u8)を取得します。配信はAES-128で暗号化されていますが、鍵はマニフェスト内に記載されており、ffmpegが復号を行います。

今回の検証では、HD(1280x720)の約1分の動画が27MBのMP4として保存されました。

動画がない記事

テキストのみの記事を指定すると、yt-dlpは動画を検出できずエラーになります。

出力フォルダの構成

今回の検証で生成されたファイルを手段ごとに整理すると、以下のようになります。

output/
├── singlefile/          1.3MB   単一HTML
├── playwright-pdf/      2.5MB   PDF(出典情報付き)
├── archivebox/           43MB   全形式一括(SingleFile, PDF, WARC, 本文抽出等)
└── yt-dlp/               27MB   動画(MP4)

全手段を併用した場合、1記事あたり約74MBです。ArchiveBox単体でもSingleFile・PDF・WARCを含む43MBになるため、ArchiveBox + yt-dlpの組み合わせ(約70MB/記事)が最もカバー範囲が広くなります。

100記事を保存する場合、ArchiveBoxだけで約4.3GB、動画込みで約7GBの見積もりになります。

用途による使い分け

実際に試した結果、1つの手段ですべてをカバーするのは難しく、用途に応じた使い分けが現実的でした。

  • 原本の忠実な保存 → ArchiveBox(広告込みでもページの完全な記録として保持。WARC・本文抽出も自動生成)
  • 閲覧用のPDF保存 → Playwright PDF(印刷モードにより広告が除かれ、出典情報付き)
  • 手軽な単体保存 → SingleFile CLI(HTMLファイル1つで完結)
  • 動画の保存 → yt-dlp(記事内の埋め込み動画をMP4で取得)

なお、いずれの手段でも、CSSセレクタの指定による要素の除去を行う場合は、記事の構成要素(配信元、更新日時など)まで意図せず削除してしまうリスクがあります。アーカイブの信頼性を重視するなら、ページ全体をそのまま保存するのが安全です。

著作権について

ダウンロードしたコンテンツの著作権は配信元(各テレビ局・メディア)に帰属します。私的使用の範囲(著作権法第30条)を超える利用(再配布・転載・商用利用)は著作権侵害となります。