wgetの–levelと–convert-linkの検証

2020年1月20日

今回は、wgetの–level(リンクの最大深さ)と–convert-link(オフライン閲覧用のリンク修正)の内容を検証する。

対象はGNU Wget 1.20.1。

–level(リンクの最大深さ) の検証

ここでは、最大範囲まで辿られると、時間が増えないことを検証する。

クロール先の作成

HTMLを生成するshellスクリプト

COUNT=$1
BASE_URL="https://elephantcat.work/wget_test"
for i in `seq $COUNT`;do
        FILE="$i.html"

        echo "<html lang=\"en\">" > $FILE
        echo "<body>" >> $FILE
        echo "<ul>" >> $FILE
        MAXJ=`expr $i + 1`
        for j in `seq $MAXJ`;do
                URL="$BASE_URL/$j.html"
                echo "<li><a href=\"$URL\">$j</a></li>" >> $FILE
        done
        echo "</ul>" >> $FILE
        echo "</body>" >> $FILE
        echo "</html>" >> $FILE
done

上記を実行して、50個分のHTMLを生成

$ sh create_htmls.sh 30

カレントディレクトリに1.html~30.htmlが作成されます。例えば3.htmlは以下のようなものになります。

<html lang="en">
<body>
<ul>
<li><a href="https://elephantcat.work/wget_test/1.html">1</a></li>
<li><a href="https://elephantcat.work/wget_test/2.html">2</a></li>
<li><a href="https://elephantcat.work/wget_test/3.html">3</a></li>
<li><a href="https://elephantcat.work/wget_test/4.html">4</a></li>
</ul>
</body>
</html>

3.htmlは4つのリンクを持つHTMLファイルです。同様に、n.htmlは、n+1個のリンクを持つHTMLファイルであり、1.htmlから1つずつリンクを辿る度にファイルが増えるようなネットワーク構造になっています。

測定

1.htmlを起点にレベル1つずつ増やしながら、50回時間を計測します。測定用のスクリプトが以下になります。

for i in `seq 50`; do
        rm -r elephantcat.work/wget_test
        /usr/bin/time --quiet -f %e wget --quiet --recursive --level $i --page-requisites --adjust-extension --span-hosts --convert-links --restrict-file-names=windows --domains elephantcat.work --no-parent https://elephantcat.work/wget_test/1.html
done

実行すると標準出力に実行時間が1行ずつ出るので、リダイレクトしてファイル(time.log)に落とします。

$ sh measure.sh > time.log

後はExcelなどでグラフにすればOK。今回は遊びで、PerlのText::Chartを使ってみました。

use Text::Chart qw(gen_text_chart);

chomp(my @nums=<STDIN>);
my $res = gen_text_chart(
    data => \@nums,
    chart_height => 10,
    type => 'sparkline',
);

binmode(STDOUT, ":utf8");
print $res;

これを使うとテキストで棒グラフが書けます(整形が結構大変)。

結果と考察

                                █  ▄         █     2[秒]
                             ▃▁ █▅▂█▆▂ ▄▃▂▄▂▂█▆▃▂▁
                         ▃▂  █████████▇███████████
                         ██▃▄█████████████████████
                    ▂▂▁▃▇█████████████████████████
               ▁ ▁▂▄██████████████████████████████ 1
             ▅▆█▇█████████████████████████████████
         ▂▃▄▇█████████████████████████████████████
     ▂▃▅▇█████████████████████████████████████████
 ▂▄▆██████████████████████████████████████████████ 
回数     10        20        30        40        50

30回以降横ばいに見えます。レベルは最大回数を超えると取得時間が頭打ちになるということです(当然ですが)。

–convert-link(オフライン閲覧用のリンク修正)の内容検証

前節で生成し、wgetで取得した3.htmlを見てみます。

<html lang="en">
<body>
<ul>
<li><a href="1.html">1</a></li>
<li><a href="2.html">2</a></li>
<li><a href="3.html">3</a></li>
<li><a href="4.html">4</a></li>
</ul>
</body>
</html>

上にあるものと比べると、絶対URLだったリンクURLが、相対URLになってることが分かります。絶対URLでないのは、オフライン閲覧した際にリンク切れになってしまうからです。このように、オフライン閲覧などを考慮すると、(元のサイト次第ですが)HTMLの書き換えが必要となります。以降では絶対URL→相対URLの書き換え以外のリンク書き換えパターンを見ていきます(全部ではありません)。

ディレクトリ

例えば、https://elehantcat.work/、これにもファイル名がありません。通常、この内容はtext/htmlであり、多くの場合、index.htmlやらindex.phpやらindex.jspやらindex.jsやら、拡張子は違えど、共通してindex.*という形式の名前のファイルが処理していることが多いと思います。wgetでは、ディレクトリの内容を取得すると、ファイル名にはindex.htmlを使用します。リンクURLは当然ただのディレクトリなので、オフライン閲覧のためには書き換えが必要になります。

拡張子なし

例えば最近の動的に生成されるページでは、URLを見てコントローラを選ぶルーティング機能を導入しているフレームワークが多いです。そのようなフレームワークを使用すると、URLとコントローラなどが必ずしも一対一対応しないので、URLのファイル名部分に拡張子が付かなくなります。

これらのURLからファイルとして内容をダウンロードした場合、拡張子のないファイルは見た目で何のファイルか分からず、扱いに困ります。そこで、wgetではオプション(–adjust-extension)でContent-Typeから拡張子を付けてくれる機能が追加されています。このようなケースではリンク元は拡張子がついていないため、オフライン閲覧用に書き換えが必要になります。

その他

他にもいろいろありますが、あとは自分で見つけてください。マニュアルは、以下にあります。

https://www.gnu.org/software/wget/manual/wget.html

最後に

–convert-linkによるリンク書き換え処理は全部ダウンロードが終わってからなので、Ctrl+Cで止めると書き換えずに終わってしまいます。ご注意ください。