【Python 事始め】404 エラーを補足する


指定された URL からファイルをダウンロードする方法を「【Python 事始め】進捗を表示しながらダウンロードする」に書いたが、ここで使った urllib.urlretrieve 関数はダウンロードできなかった場合(404 エラー等)でも問題なく終了してしまう。これを回避するには次のようにする。

How to catch 404 error in urllib.urlretrieve – Stack Overflow
http://stackoverflow.com/questions/1308542/how-to-catch-404-error-in-urllib-urlretrieve

urllib.FancyURLopenerhttp_error_default メソッドをオーバーライドしたクラスを作成すればよい。

myurlopener.py

# coding=utf-8
import urllib

class MyURLopener( urllib.FancyURLopener ):
    def http_error_default(
            self, url, fp, errcode, errmsg, headers ):
        print u"HTTP エラー(コード %d)が発生しました。" % errcode
        return urllib.addinfourl(
                fp, headers, "http:" + url, errcode )

if __name__ == "__main__":
    print "this is a module."

前回の記事で書いたサンプルスクリプトを修正してみよう。

download_test2.py

#!/usr/bin/python
# coding=utf-8
import urlparse
import sys
from myurlopener import MyURLopener

# コマンドライン引数から URL を得る
url = sys.argv[ 1 ]
# URL からファイル名を得る
filename = urlparse.urlparse( url )[ 2 ].split( "/" )[ -1 ]

def progress( block_count, block_size, total_size ):
    ''' コールバック関数 '''
    percentage = 100.0 * block_count * block_size / total_size
    # 改行したくないので print 文は使わない
    sys.stdout.write( "%.2f %% ( %d KB )\r"
            % ( percentage, total_size / 1024 ) )

# ダウンロード開始
MyURLopener().retrieve(
        url = url
        ,filename = filename
        ,reporthook = progress
        )
print

ハイライトした部分が修正点である。実行すると次のような表示になる。

$ python download_test2.py http://blog.remora.cx/file_404
HTTP エラー(コード 404)が発生しました。
-819200.00 % ( -1 KB )

progress 関数の出力がおかしなことになっているが、それは次の課題にしよう。

コメントを残す