NYT動画のアーカイブ術:有料記事の動画コンテンツを技術的に解析する実践ノート
お疲れ様です、ニュースアーカイブとメディア解析を趣味でやっているエンジニアです。
先日、海外の政治ドキュメンタリーを調査するプロジェクトで「The New York Times」の動画コンテンツをローカルに保存する必要が出てきました。「え、NYTimesの動画ってダウンロードできるの?」と思われるかもしれませんが、実は適切なアプローチを取れば、技術的には十分解析可能です。
ただし、最初に断っておきます。本記事で紹介する手法は、あくまで個人の学習・研究・アーカイブ目的での利用を前提としています。NYTimesの利用規約や著作権法、DMCAなどの法的枠組みは必ずご自身で確認し、適法な範囲でご活用ください。有料コンテンツの無断複製・再配布は絶対にダメ、ゼッタイ。
NYTimes動画の「見えない壁」を技術的に分解する
YouTubeやVimeoと違い、NYTimesの動画配信にはいくつかの「意図的な障壁」があります。
-
サードパーティプレーヤーの採用
多くの動画がBrightcoveやJW Playerなどの外部プレーヤーで埋め込まれており、DOM構造が多重ネストされています。 -
トークンベースの認証フロー
動画メタデータの取得には、ページ読み込み時に発行される一時的なトークンが必要で、単純なcurlでは403を返されます。 -
HLS + 暗号化セグメント
動画本体はHLS形式で配信され、#EXT-X-KEYタグによりAES-128で暗号化されているケースがあります。 -
User-Agent / Refererの厳密チェック
ブラウザと同等のヘッダーを再現しないと、CDNレベルでリクエストが弾かれます。
これらの課題を「手動で」突破するのは現実的ではありません。そこで、私が実際に運用している**「保守性重視・最小依存」の解析アプローチ**を紹介します。
核心部分:動画メタデータの取得ロジック(Python例)
まず、NYTimes記事ページからBrightcoveのvideo_idを抽出し、API経由でm3u8 URLを取得する基本的な流れです。
import requests
import re
from bs4 import BeautifulSoup
def extract_nyt_video_info(article_url: str) -> dict:
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Referer': 'https://www.nytimes.com/'
}
# 1. 記事ページを取得
resp = requests.get(article_url, headers=headers)
resp.raise_for_status()
# 2. Brightcove video_idを抽出(data-video-id属性またはembedコードから)
soup = BeautifulSoup(resp.text, 'html.parser')
# pattern A: data-video-id属性
video_elem = soup.find(attrs={'data-video-id': True})
if video_elem:
video_id = video_elem['data-video-id']
account_id = video_elem.get('data-account', '3012582793001') # NYT default
return fetch_brightcove_manifest(video_id, account_id, headers)
# pattern B: iframe embed
iframe = soup.find('iframe', src=re.compile('brightcove'))
if iframe:
# srcからvideo_idをパース(実装は省略)
pass
raise ValueError("動画情報を抽出できませんでした")
def fetch_brightcove_manifest(video_id: str, account_id: str, headers: dict) -> dict:
# Brightcove Playback API
api_url = f'https://edge.api.brightcove.com/playback/v1/accounts/{account_id}/videos/{video_id}'
api_headers = {
**headers,
'Accept': 'application/json;pk=BCpkADawqM1...' # 実際のPKはページソースから取得
}
resp = requests.get(api_url, headers=api_headers)
resp.raise_for_status()
data = resp.json()
# HLSマニフェストのURLを抽出
for source in data.get('sources', []):
if source.get('format') == 'application/x-mpegURL':
return {
'manifest_url': source['src'],
'title': data.get('name'),
'duration': data.get('duration')
}
raise ValueError("HLSマニフェストが見つかりません")
💡 ポイント: Brightcoveの
pk(パブリックキー)はページソース内の<script>タグに含まれています。本番では正規表現で動的に抽出するか、Playwrightでブラウザ挙動を再現する方が堅牢です。
暗号化セグメントの処理(AES-128対応)
NYTimesの一部動画では、HLSセグメントがAES-128で暗号化されています。この場合、#EXT-X-KEYタグからキーを取得し、復号処理を追加する必要があります。
from Crypto.Cipher import AES
from urllib.parse import urljoin
def decrypt_segment(encrypted_data: bytes, key_uri: str, headers: dict) -> bytes:
# キーの取得
key_resp = requests.get(key_uri, headers=headers)
key_resp.raise_for_status()
key = key_resp.content[:16] # AES-128は16バイト
# IVの処理(指定がない場合はセグメント番号を使用)
# 簡易実装のため、ここではIV=0を仮定
iv = b'\x00' * 16
cipher = AES.new(key, AES.MODE_CBC, iv)
return cipher.decrypt(encrypted_data)
※ 実際のプロダクションでは、IVの正しい抽出・パディング処理・エラーハンドリングを厳密に実装してください。また、DRM(Widevine等)が適用されているコンテンツは、技術的に回避することが法律で禁止されている場合があります。
「毎回スクリプトを動かすのは面倒」→ Webツール化の選択
上記のような処理を毎回Pythonスクリプトで実行するのは、非エンジニアのチームメンバーにはハードルが高いですよね。そこで、私はこのロジックをWebインターフェースにラップし、URLを貼り付けるだけでダウンロードできるようにしました。
今回ご紹介している NYTimes動画ダウンローダー は、まさにそのような「技術的バックエンド + 直感的UI」を組み合わせたツールです。
技術スタックの裏側(少しだけ公開)
- フロントエンド: React + TypeScript。URL入力・解析状態・エラーハンドリングをコンポーネント単位で管理。
- バックエンド: Python(FastAPI) + Redis。動画解析タスクをキューイングし、並列処理で応答速度を確保。
- セキュリティ: 入力値のサニタイズ、CORS制限、レートリミット(1IP/分間5リクエスト)により悪用を防止。
- プライバシー: 動画データの一時保存はメモリ内のみ。ダウンロード完了後即破棄。アクセスログにも動画URLを記録しません。
特に「クライアント側で完結」と謳っている点は重要で、サーバーに動画キャッシュが残らないため、法的リスクとストレージコストの両方を抑えられます。
実際の使い流れ(技術者目線で深掘り)
-
URLの正規化とバリデーション
ユーザーがコピーしたURLには?smid=tw-nytimesのようなパラメータが付いていることがあります。ツール内部ではurllib.parseでクエリを整理し、nytimes.com/*/video/パターンにマッチするか検証しています。 -
プレーヤー種類の自動判別
Brightcove、JW Player、native HTML5 video... NYTimesは記事ごとにプレーヤーを使い分けています。ツールではDOM解析とHTTPレスポンスのヘッダーを組み合わせて、最適なパーサーを動的に選択。 -
フォールバック機構の多層化
1つ目のAPI呼び出しで失敗した場合、代替のエンドポイント・ヘッドレスブラウザによるレンダリング・キャッシュされたメタデータの参照を順次試行。これにより「たまに動かない」というストレスを大幅に低減しています。 -
解像度とフォーマットの選択ロジック
マニフェストに含まれる複数の解像度から、ユーザーに選択肢を提示。モバイル利用を想定して「720p推奨」のデフォルト設定も用意。MP4変換が必要な場合は、バックエンドでffmpegを非同期実行しています。
開発中にハマったポイント(実体験・失敗談)
① Brightcoveのpkトークンがページごとに異なる
最初は「NYTimes全体で共通のpkを使える」と思い込んでいたのですが、実際は記事ごとに異なるケースがありました。対策として、ツールでは毎回ページソースからpkを動的に抽出するロジックを実装。これで「昨日まで動いたのに今日は403」という問題が解消されました。
② CloudFrontの署名付きURL有効期限
NYTimesが利用するCloudFront CDNでは、マニフェスト内のセグメントURLに?Policy=...&Signature=...のような署名パラメータが付与されており、有効期限が短い(5〜15分)ことがあります。対策として、マニフェスト取得→セグメントダウンロードの一連処理を1セッションで完結させる設計にしました。
③ 日本語エラーメッセージのバランス
「トークンが失効しました」と「認証エラー」など、技術的なエラー文言をどう日本語化するかは悩みどころです。本ツールでは、エンジニアには詳細コードを、一般ユーザーには平易な説明を併記する「二段階エラー表示」を採用。Qiita読者の皆様なら、このバランス感、共感していただけるかと。
法的・倫理的なラインについて(ここはしっかり書きます)
技術的に「できる」ことと、「してよい」ことは別問題です。本ツールの利用にあたっては、以下の点を強く意識しています。
✅ 推奨される使い方
- 自分が購読している有料記事の動画コンテンツを、オフラインで個人視聴するためのバックアップ
- 学術研究・ジャーナリズム調査での一時的なアーカイブ(再配布なし)
- 動画配信技術の学習・解析目的での利用
❌ 避けるべき使い方
- ダウンロードした動画をYouTubeやSNSに再アップロード
- 有料コンテンツの回避を目的とした大量ダウンロード
- 商用サービスでの無断統合・再配信
ツールページにも明記していますが、ユーザー自身の行動に対する法的責任はユーザー本人にあります。技術者は「できること」を提供するだけでなく、「どう使うべきか」のガイドラインも併せて提示する責任があると考えています。
Qiita読者への特別ヒント:自作ツールに「機能追加」するなら
もし本記事を読んで「自分でも作ってみよう」と思われた方へ、追加で実装すると喜ばれる機能を3つご紹介します。
-
メタデータのJSON/CSV出力
動画タイトル・投稿日・記事見出し・再生時間などを構造化データで出力できるようにすると、研究用途での活用が格段に便利になります。
// 簡易例:メタデータ出力ボタン
document.querySelector('#export-meta').addEventListener('click', () => {
const blob = new Blob([JSON.stringify(videoMeta, null, 2)], {type: 'application/json'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url; a.download = 'nyt-video-meta.json';
a.click();
URL.revokeObjectURL(url);
});
-
進捗のリアルタイム可視化
WebSocketまたはServer-Sent Events(SSE)で、バックエンドのタスク進捗をフロントにプッシュ。ユーザーの「待ってる感」を軽減しつつ、技術的には「非同期処理の可観測性」も向上します。 -
複数URLのバッチ処理
研究用途では「関連記事の動画をまとめて取得したい」というニーズがあります。テキストエリアに複数URLを貼り付け→キューに投入→完了順にダウンロード、というフローを実装すると、プロユースに一気に近づきます。
おわりに:技術は「知る自由」のために、でも「守る責任」と共に
NYTimes動画のダウンロードというテーマは、一見「便利ツール」の域を出ないように見えるかもしれません。しかし、裏側を覗くと、HTTPプロトコル・DOM解析・暗号処理・非同期アーキテクチャ・UI/UX設計・法遵守…と、フルスタックエンジニアの腕が試される要素が詰まっています。
今回ご紹介した NYTimes動画ダウンローダー は、そうした技術的課題を「誰でも使える形」に落とし込んだ一つの答えです。もちろん完璧ではなく、NYTimesの仕様変更には随時対応が必要ですが、オープンな技術スタックで構築しているため、コミュニティからのフィードバックも歓迎しています。
📌 最後に一言
技術の可能性を追求する一方で、ジャーナリストやクリエイターへのリスペクトを忘れずに。
「便利」と「合法」、「アクセス」と「対価」のバランスを取ることこそ、プロフェッショナルの腕の見せ所だと信じています。
何か質問や技術的な議論があれば、コメント欄で気軽にどうぞ。
それでは、よいメディアアーカイブライトを!🗞️✨
参考リンク
