指定された 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 関数の出力がおかしなことになっているが、それは次の課題にしよう。
