🐿 ウェブサイトをまるごとダウンロード
作成日: 2021/11/09
0

私のプログラミング学習は、まず実現したいことを大ざっぱにまとめ、次に書籍とウェブページから関連情報(主にコード)を探してきて、それらを組み合わせてチューニングして仕上げる、という工程になっています。
今回参照したのは次のウェブページ:
『【Python】Webスクレイピング サイトをマルッとダウンロード』
https://qiita.com/ononoy/items/c382ca698b7efe9e6119
筆者の方の説明にあるように、これは『Pythonによるスクレイピング&機械学習 開発テクニック BeautifulSoup,scikit-learn,TensorFlowを使ってみよう』(クジラ飛行机著、ソシム)という単行本を学習した記録です。この記事をまとめるまで気づかなかったのですが、実はこの本私の本棚にありました。😊
基本的に当該ウェブ記事のコードで動作するということらしいのですが、実際に2つのサイトに適用する中で2か所の修正が必要でした。
1.文字コード判定がうまくいかなくて UnicodeDecodeErrorで終了する。
⇒対処:urlretrieve の代わりに requests.get を使い、apparent_encoding で文字コードを取得する。必ずしも正確な文字コードを返してこないので、場合に応じて対処するコードを書く。以下のように修正。

def enum_links(url):
    global myencoding
... 中略 ...
    try:
        print("download=", url)
        r = requests.get(url, headers=myheader)
        r.encoding = r.apparent_encoding
        print("encoding =", r.encoding)
        time.sleep(2)
        if r.encoding == 'CP932':
            myencoding = 'utf-8'
        elif r.encoding == 'Windows-1254':
            myencoding = 'utf-8'
        else:
            myencoding = 'shift_jis'
        
        ext = os.path.splitext(savepath)[1][1:]
        if ext in ['html', 'htm', 'txt', 'css', 'cgi', 'py']:
            fo = open(savepath, 'w', encoding=myencoding)  # テキストファイル
            fo.write(r.text)
            fo.close()
        else:
            fo = open(savepath, 'wb')  # バイナリファイル
            fo.write(r.content)
            fo.close()
        return savepath
    ... 後略 ...

2.リンク先がディレクトリの場合(/root/subdir/ など)、index.html の分析をしないので、その先のダウンロードがおこなわれない。ディレクトリの場合の処理を追加。修正は以下のとおり。

def analize_html(url, root_url):
    global test_files
    global myencoding
    ... 中略 ...
    html = open(savepath, "r", encoding=myencoding).read()
    links = enum_links(html, url)
    for link_url in links:
        if link_url.find(root_url) != 0:
            if not re.search(r".css$", link_url): continue
        if re.search(r".(html|htm)$", link_url):
            analize_html(link_url, root_url)
            continue
        if re.search(r"/$", link_url):
            analize_html(link_url, root_url)
            continue
        
        enum_links(link_url)

これで何とか、ほぼすべてのファイルをダウンロードできるようになりました。ただ、3つのhtmlファイルは想定外の文字コードのため(うち1つは encoding = None !!!)、ダウンロードに失敗しました。文字コードはやっかいです。


pythonで自然言語処理プログラムが書けるようになりたいと思っています。Ticketnoteで自分の到達度を確認できれば嬉しいです。