Internet Archiveから最新データを取得する(curl,xmllint,jq)

Get latest data from Internet Archive

インターネットアーカイブというものをご存じでしょうか?最近裁判になっていたりと色々と世間を騒がせたものですが、1996年に設立された非営利団体で、皆さんも知らず知らずのうちに使ったことがあるかもしれません。
この記事はそのインターネットアーカイブからLinuxのcurlとxmllint、jqコマンドを使って最新データ取得する方法について説明していきます。

インターネットアーカイブとは

インターネットアーカイブInternet Archive)は、WWW・マルチメディア資料のアーカイブ閲覧サービスとして有名なウェイバックマシンWayback Machine)を運営しているアメリカの団体である。本部はカリフォルニア州サンフランシスコのリッチモンド地区に置かれている。アーカイブにはプログラムが自動で、または利用者が手動で収集したウェブページのコピー(ウェブアーカイブ)が混在しており、これは「WWWのスナップショット」と呼ばれる。そのほか、ソフトウェア・映画・本・録音データ(音楽バンドなどの許可によるライブ公演の録音も含む)などがある。アーカイブは、それらの資料を無償で提供している。(Wikipediaより抜粋)

元々はウェブページの保存をすることから始まったものでしたが、現在では利用者自身が所有するソフト・映画・本・録音データなども公開されるものになっています。

インターネットアーカイブの違法性

インターネットアーカイブは、フェアユース原則に基づく非営利の図書館として文化的・歴史的資料を保存する公益的役割を担っています。
要は、通常の図書館で本を無料で借りて読むのと同じ原理で合法とされているということです。
また、権利者へのオプトアウト(許諾しない)制度も設けているため、完全に合法だとは言い切れませんが、現状インターネットアーカイブを普通に利用することは違法とされていません。

インターネットアーカイブは名前の通りインターネット上で公開・利用が可能なサイトとなっています。
その為、Curlコマンドなどでデータの取得ができます。
※スクリプトなどで連続してダウンロードすることは相手のサーバーに負荷をかけてしまうので控えましょう

それでは実際にインターネットアーカイブからデータの取得を行っていきます。

インターネットアーカイブからデータを取得する

今回はインターネットアーカイブの最新データのリストを取得していきたいと思います。
インターネットアーカイブのRSSフィードを生成するURLは以下のものとなっています。
https://archive.org/services/collection-rss.php
このURLでは、インターネットアーカイブの特定のコレクションの更新情報をRSSフィードとして取得が可能です。

curl -s https://archive.org/services/collection-rss.php

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <link>https://archive.org</link>
    <title>Internet Archive</title>
    <description>The most recent additions to the Internet Archive collections.  This RSS feed is generated dynamically</description>

RSSフィードなので、curlで取得するとxml構造のデータが返ってきます。
今回はxmllintというパッケージを使ってここから整形をしていきます。

xmllintのインストール

# Ubuntu,Debianの場合
sudo apt-get install xmllint
# SUSEの場合
sudo zypper install xmllint

RSSフィードを取得・整形

次にxmllint –formatを使ってみやすい形に整形していきます。
シェルスクリプトで作成したのが以下になります。

#!/bin/bash

# 出力用フォルダ作成
WORKDIR="$HOME/bin/internet-archive/latest-archive"
mkdir -p "$WORKDIR"

cd "$WORKDIR"
curl -s "https://archive.org/services/collection-rss.php" | \
    xmllint --format - | \
    grep -E "<title>|<link>|<category>" | \
    sed 's/<[^>]>//g' | \
    sed 's/^[ \t]//' > "$WORKDIR/"latest_uploads.txt


awk 'NR%2{printf "%s - ",$0;next;}1'  "$WORKDIR/"latest_uploads.txt

latest_uploadsの中身を見てみますと無事に最新のインターネットアーカイブのフィードが取得できていることがわかります。

~/bin/internet-archive> cat latest_uploads.txt
.# title(タイトル)
.# link(リンク先)
.# category(カテゴリー)
Пёс-2 
https://archive.org/details/NTV_20241114_052500_Pyos-2
movies/TV-NTV
2024-11-14-ew
https://archive.org/details/2024-11-14-ew
texts/eugeneweekly
independent-media-central-america 2024-11-04T13:17:00PST to 2024-11-04T05:56:24PST
https://archive.org/details/IMCA-20241104131700-crawler01
web/independent-media-central-america
SUDAN_20241114_063000
https://archive.org/details/SUDAN_20241114_063000
movies/TV-SUDAN
Archive-It Crawl Data: Partner 2517 Collection 22185 Crawl Job 2046385
https://archive.org/details/ARCHIVEIT-22185-2024103116-00001
web/ArchiveIt-Collection-22185
Harakiri (Deluxe Edition)
https://archive.org/details/serj_tankian_harakiri_deluxe_edition_2012-01-01
audio/opensource_audio

カテゴリーごとにファイルを作成

#!/bin/bash

INPUT_FILE="latest-archive/latest_uploads.txt"
OUTPUT_DIR="latest-archive"

# 現在のカテゴリーを格納する変数
current_category=""
current_title=""
current_link=""

# 1行ずつ処理する
while IFS= read -r line; do
    #カテゴリーでファイル作成
    if [[ $line =~ \<category\>(.*)\</category\> ]]; then
        if [[ -n $current_category && -n $current_title && -n $current_link ]]; then
            category_file="${OUTPUT_DIR}/${current_category%/*}_latest.txt"
            echo "Title: $current_title" >> "$category_file"
            echo "Link: $current_link" >> "$category_file"
            echo "" >> "$category_file"
        fi
        
        current_category="${BASH_REMATCH[1]}"
        current_title=""
        current_link=""
    fi
    
    # タイトルの処理
    if [[ $line =~ \<title\>(.*)\</title\> ]]; then
        current_title="${BASH_REMATCH[1]}"
    fi
    
    # リンクの処理
    if [[ $line =~ \<link\>(.*)\</link\> ]]; then
        current_link="${BASH_REMATCH[1]}"
    fi
done < "$INPUT_FILE"

# 最後のエントリーを保存
if [[ -n $current_category && -n $current_title && -n $current_link ]]; then
    category_file="${OUTPUT_DIR}/${current_category%/*}_latest.txt"
    echo "Title: $current_title" >> "$category_file"
    echo "Link: $current_link" >> "$category_file"
    echo "" >> "$category_file"
fi

先ほどのシェルを実行するとlatest-archiveディレクトリ内にカテゴリーごとに分けられたtxtファイルが作成されていると思います。

~/bin/internet-archive/latest-archive> ls
# このようにカテゴリー分けされたテキストが生成されていればOK
audio_latest.txt       data_latest.txt   latest_uploads.txt  texts_latest.txt
collection_latest.txt  image_latest.txt  movies_latest.txt   web_latest.txt

~/bin/internet-archive/latest-archive> cat data_latest.txt 
Title: Archive-It Crawl Data: Partner 1067 Collection 23094 Crawl Job 2050793
Link: https://archive.org/details/ARCHIVEIT-23094-2024111407-00000

Title: Nat'l Security Adviser & White House Press Sec. Hold Briefing
Link: https://archive.org/details/CSPAN_20241114_062200_Natl_Security_Adviser__White_House_Press_Sec._Hold_Briefing

Title: spn2-20241114072909
Link: https://archive.org/details/spn2-20241114072909

このLink先にアクセスして、直接ダウンロードするのもいいです
「ここまでやったらターミナル上で完結させたい」という方向けにダウンロードするシェルスクリプトを作成しました。

jqコマンドのインストール

# SUSEの場合
sudo zypper install jq
# Ubuntu/debianの場合
sudo apt-get install jq

メタデータを先に取得することで、必要なファイルの正確な場所と情報を確認できます 。要は余分なファイルのダウンロードを控えるためです。
URLエンコードが必要なのは、ファイル名に特殊文字や空白が含まれる場合でも正しくダウンロードされるためです。

#!/bin/bash
# ./download-archive.sh Link先
url="$1"
if [ -z "$url" ]; then
    echo "Please set Archive-URL"
    exit 1
fi
identifier=$(echo "$url" | sed 's|.*/details/||')
# メタデータを取得してファイル一覧を表示
echo "Available files:"
files=$(curl -s "https://archive.org/metadata/$identifier" | \
       jq -r '.files[] | select(.name!="") | .name' | \
       nl -w1 -s'. ')
echo "$files"
echo -e "\nEnter number to download (1,2,...): "
read number
# 選んだ番号に対応するファイル名を取得
filename=$(echo "$files" | awk -v num="$number" '$1 == num"." {$1=""; print $0}' | xargs)
if [ -n "$filename" ]; then
    echo "Downloading: $filename"

    # URLエンコードされたファイル名を作成
    encoded_filename=$(printf '%s' "$filename" | perl -MURI::Escape -ne 'chomp; print uriescape($)')
    curl -L "https://archive.org/download/$identifier/$encoded_filename" \
         -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" \
         --output "$filename"

    filesize=$(stat -f%z "$filename" 2>/dev/null || stat -c%s "$filename" 2>/dev/null)
 fi

実際に使用した例を載せておきます。

sh download-archive.sh https://archive.org/details/sematary-truey-jeans-rainbow-bridge-3
Available files:
1. SEMATARY - TRUEY JEANS [RAINBOW BRIDGE 3].mp4
2. __ia_thumb.jpg
3. sematary-truey-jeans-rainbow-bridge-3.thumbs/SEMATARY - TRUEY JEANS [RAINBOW BRIDGE 3]_000001.jpg
4. sematary-truey-jeans-rainbow-bridge-3.thumbs/SEMATARY - TRUEY JEANS [RAINBOW BRIDGE 3]_000058.jpg
5. sematary-truey-jeans-rainbow-bridge-3.thumbs/SEMATARY - TRUEY JEANS [RAINBOW BRIDGE 3]_000090.jpg

Enter number to download (1,2,...): 
2
Downloading: __ia_thumb.jpg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  8851  100  8851    0     0   5105      0  0:00:01  0:00:01 --:--:--     0

まとめ

最後になりますが、以下の点に注意して使用してください

  • サーバー負荷を考慮し、連続的なダウンロードは控える
  • 権利者へのオプトアウト制度が設けられている
  • 一般的な利用は合法だが、適切な利用を心がける

おわり


Categories:

, ,