指定された 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.FancyURLopener
の http_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 https://blog.delphinus.dev/file_404 HTTP エラー(コード 404)が発生しました。 -819200.00 % ( -1 KB )
progress
関数の出力がおかしなことになっているが、それは次の課題にしよう。