“webkit2” download

とあるサイトで連番ファイルをダウンロードしようとした。
Fedora な筆者は当然 wget を使った、見事にアクセス拒否された。

Chrome のロケーションバーに一つづつ打ち込むと普通に表示できる。
どうやらウェブブラウザからのアクセス以外は弾くようにしているようだ。
当然多重アクセスの対策もしているっぽい。

まてよ、ウェブブラウザなら大丈夫だったら Headless で wget の代わりに。。。
Headless Chromeでファイルをダウンロード – Qiita
やっぱりダメか、筆者ですら思い付くレベルの話だし当然悪用されるだろう。
面倒臭いけど一つづつ落とすしかないか。

そういえば、ウェブブラウザなら大丈夫なんだよね。
もしかして Gir の WebKit2 でアクセスすればイケるんでね?
悪用のススメではない、あくまで興味があったから。

[“webkit2” download] で検索すると、おぉ目的の記事が。
日本語がゼロなことに苦笑。

[webkit-gtk] how to download something with webkit ?

なるほど、WebKit2 でファイルをダウンロードするには
webkit_web_context_download_uri() 関数でイケるのね。
Python3 と Gir で簡単に作れそうだ。

WebKit2.WebContext – Classes – WebKit2 4.0

当然非同期だろうから for 文なんかを使うとトンデモアクセスになってしまう。
一つのダウンロードが終ってから次のリクエストを送る必要がある。
戻り値 WebKit2.Download のシグナルを使う、メインループがいるな。
エラーが戻る場合もあるだろうから Ctrl+C で終了できたほうがいいかと。
以下初心者向きな解説はしない。

#!/usr/bin/env python3

"""
    python3 wk_download.py uri start_number end_number
"""

import gi, signal, sys, os
signal.signal(signal.SIGINT, signal.SIG_DFL)

gi.require_version('WebKit2', '4.0')
gi.require_version('Gtk', '3.0')
from gi.repository import WebKit2, Gtk

ctx = WebKit2.WebContext()

d = os.path.dirname(sys.argv[1])
i = int(sys.argv[2])
end = int(sys.argv[3])

def on_finished(dl):
    global i, end
    i += 1
    if i <= end:
        do_download(i)
    else:
        Gtk.main_quit()

def on_failed(dl, error):
    print(error.message);
    Gtk.main_quit()

def do_download(n):
    s = "{0}/{1}.jpg".format(d, n)
    print(s)
    dl = ctx.download_uri(s)
    dl.connect("finished", on_finished);
    dl.connect("failed", on_failed);

do_download(i)
Gtk.main()

イケちゃった。

XDG_DOWNLOAD_DIR が自動的にダウンロード場所に指定される。
変更できるだろうけど筆者はコレでいいから別にいいや。

久々に Python をやったら結構忘れていて自分でびっくり。
argv の何番目とか行末コロンを忘れたりとかつい // とか。