ファイルのダウンロード
連番を開くスクリプトを書いたので、せっかくだから開いたurlからファイルをダウンロードするスクリプトをつくってみようかと思ったのだけれど巧くいかない。
urllibのリファレンスに
urlretrieve( url[, filename[, reporthook[, data]]])
URL で表されるネットワーク上のオブジェクトを、必要に応じてローカルなファイルにコピーします
ってあったので使ってみたのだけれど、コレ、404ファイルもダウンロード(?)してきちゃう。
指定したurlが間違っていても気付かない。困った。
とりあえず、吐き出すモンぜんぶ吐き出させて指定したurlのファイル有無を判定できるか調べてみる。
#!/bin/env python # -*- coding: shift_jis -*- import urllib def feedback(count,size, total): print "count :%d" % count print "size :%d" % size print "total :%d" % total (file, header) = urllib.urlretrieve("http://www.google.co.jp/","test.html",feedback) print file print header
feedback ダウンロードのレポート(ブロックのカウントとサイズ、トータル)
file 指定したファイル名
header HTTP応答ヘッダ
応答ヘッダで判定すればいいのかな?
とりあえずググッてみたら、外人さんのソースにこんなのがあった。
(tmp, headers) = urllib.urlretrieve("http://www.google.co.jp/","test.html")
if str(headers).count("Content-Length") == 0:
print "ERROR: File not found (404 error)"
headersの中のContent-Lengthの数を数えて、それが0だったら404エラーと判定しているみたい。
でも、これだとContent-Lengthさえ応答ヘッダに含まれていればやっぱり存在しないファイルでもダウンロードしてきちゃうよ〜ん
とりあえず試してみた
#!/bin/env python # -*- coding: shift_jis -*- import urllib (tmp, headers) = urllib.urlretrieve("http://www.google.co.jp/aa/bb/cc.gif","test.gif") print str(headers).count("Content-Length") print headers if str(headers).count("Content-Length") == 0: print "ERROR: File not found (404 error)" else: print "OK"
ちゃんと"ERROR: File not found (404 error)"がでた。
でも、よく見るとgoogleの応答ヘッダには「Content-length: 1223」とある。
う〜ん「Length」では「length」をカウントしないので404を出してしまう。やっぱり駄目ジャン。
要再考。
追記urllib2モジュールでは、ちゃんと404を検出するらしい。
>>> import urllib >>> urllib.urlopen("http://www.google.co.jp/aa/bb/cc.gif")> >>> import urllib2 >>> urllib2.urlopen("http://www.google.co.jp/aa/bb/cc.gif") Traceback (most recent call last): File " ", line 1, in -toplevel- urllib2.urlopen("http://www.google.co.jp/aa/bb/cc.gif") File "c:\Python23\lib\urllib2.py", line 129, in urlopen return _opener.open(url, data) File "c:\Python23\lib\urllib2.py", line 326, in open '_open', req) File "c:\Python23\lib\urllib2.py", line 306, in _call_chain result = func(*args) File "c:\Python23\lib\urllib2.py", line 901, in http_open return self.do_open(httplib.HTTP, req) File "c:\Python23\lib\urllib2.py", line 895, in do_open return self.parent.error('http', req, fp, code, msg, hdrs) File "c:\Python23\lib\urllib2.py", line 352, in error return self._call_chain(*args) File "c:\Python23\lib\urllib2.py", line 306, in _call_chain result = func(*args) File "c:\Python23\lib\urllib2.py", line 412, in http_error_default raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) HTTPError: HTTP Error 404: Not Found >>>
ちゃんと例外がでる、urllib2を使ったほうがいいみたい。
※参考
urllib.urlopen() fails to raise exception
http://mail.python.org/pipermail/python-bugs-list/2004-July/023990.html