如何知道urllib.urlretrieve是否成功?

即使远程http服务器上不存在该文件, urllib.urlretrieve将静默地返回,它只是将html页面保存到指定的文件中。 例如:

 urllib.urlretrieve('http://google.com/abc.jpg', 'abc.jpg') 

只是悄悄地返回,即使abc.jpg在google.com服务器上不存在,生成的abc.jpg不是一个有效的jpg文件,它实际上是一个html页面。 我猜测返回的头文件(一个httplib.HTTPMessage实例)可以用来实际地告诉检索成功与否,但是我找不到httplib.HTTPMessage任何文档。

任何人都可以提供关于这个问题的一些信息?

如果可能的话,考虑使用urllib2 。 它比urllib更先进,更易于使用。

您可以轻松检测到任何HTTP错误:

 >>> import urllib2 >>> resp = urllib2.urlopen("http://google.com/abc.jpg") Traceback (most recent call last): <<MANY LINES SKIPPED>> urllib2.HTTPError: HTTP Error 404: Not Found 

resp实际上是HTTPResponse对象,你可以做很多有用的事情:

 >>> resp = urllib2.urlopen("http://google.com/") >>> resp.code 200 >>> resp.headers["content-type"] 'text/html; charset=windows-1251' >>> resp.read() "<<ACTUAL HTML>>" 

我保持简单:

 # Simple downloading with progress indicator, by Cees Timmerman, 16mar12. import urllib2 remote = r"http://some.big.file" local = r"c:\downloads\bigfile.dat" u = urllib2.urlopen(remote) h = u.info() totalSize = int(h["Content-Length"]) print "Downloading %s bytes..." % totalSize, fp = open(local, 'wb') blockSize = 8192 #100000 # urllib.urlretrieve uses 8192 count = 0 while True: chunk = u.read(blockSize) if not chunk: break fp.write(chunk) count += 1 if totalSize > 0: percent = int(count * blockSize * 100 / totalSize) if percent > 100: percent = 100 print "%2d%%" % percent, if percent < 100: print "\b\b\b\b\b", # Erase "NN% " else: print "Done." fp.flush() fp.close() if not totalSize: print 

据文件是无证的

要获得访问邮件,看起来像你做的事情:

 a, b=urllib.urlretrieve('http://google.com/abc.jpg', r'c:\abc.jpg') 

b是消息实例

由于我已经了解到Python,当我input时,使用Python的内省function总是有用的

 dir(b) 

我看到很多方法或function可以玩

然后我开始用b做事

例如

 b.items() 

列出很多有趣的事情,我怀疑玩这些东西会让你得到你想操纵的属性。

对不起,这是一个初学者的答案,但我正在努力掌握如何使用自省能力来提高我的学习和刚刚出现的问题。

那么我尝试了一些与此有关的有趣的事情 – 我想知道如果我可以自动从目录中显示出来的每一个东西,不需要参数的输出,所以我写道:

 needparam=[] for each in dir(b): x='b.'+each+'()' try: eval(x) print x except: needparam.append(x) 

您可以创build一个新的URLopener(从FancyURLopenerinheritance),并以任何您想要的方式抛出exception或处理错误。 不幸的是,FancyURLopener忽略404和其他错误。 看到这个问题:

如何在urllib.urlretrieve中捕获404错误

我结束了自己的retrieve实现,在pycurl的帮助下,它支持比urllib / urllib2更多的协议,希望它可以帮助其他人。

 import tempfile import pycurl import os def get_filename_parts_from_url(url): fullname = url.split('/')[-1].split('#')[0].split('?')[0] t = list(os.path.splitext(fullname)) if t[1]: t[1] = t[1][1:] return t def retrieve(url, filename=None): if not filename: garbage, suffix = get_filename_parts_from_url(url) f = tempfile.NamedTemporaryFile(suffix = '.' + suffix, delete=False) filename = f.name else: f = open(filename, 'wb') c = pycurl.Curl() c.setopt(pycurl.URL, str(url)) c.setopt(pycurl.WRITEFUNCTION, f.write) try: c.perform() except: filename = None finally: c.close() f.close() return filename 
 class MyURLopener(urllib.FancyURLopener): http_error_default = urllib.URLopener.http_error_default url = "http://page404.com" filename = "download.txt" def reporthook(blockcount, blocksize, totalsize): pass ... try: (f,headers)=MyURLopener().retrieve(url, filename, reporthook) except Exception, e: print e 

:)我在StackOverflow上的第一篇文章,多年来一直是一个潜伏者。 🙂

可悲的是(urllib.urlretrieve)缺乏有用的信息。 所以从这个线程到目前为止,我试图写这个:

 a,b = urllib.urlretrieve(imgURL, saveTo) print "A:", a print "B:", b 

这产生了这个:

 A: /home/myuser/targetfile.gif B: Accept-Ranges: bytes Access-Control-Allow-Origin: * Cache-Control: max-age=604800 Content-Type: image/gif Date: Mon, 07 Mar 2016 23:37:34 GMT Etag: "4e1a5d9cc0857184df682518b9b0da33" Last-Modified: Sun, 06 Mar 2016 21:16:48 GMT Server: ECS (hnd/057A) Timing-Allow-Origin: * X-Cache: HIT Content-Length: 27027 Connection: close 

我想可以检查:

 if b.Content-Length > 0: 

我的下一步是testing检索失败的场景…

针对另一个服务器/网站的结果 – “B”中返回的结果有点随意,但可以testing某些值:

 A: get_good.jpg B: Date: Tue, 08 Mar 2016 00:44:19 GMT Server: Apache Last-Modified: Sat, 02 Jan 2016 09:17:21 GMT ETag: "524cf9-18afe-528565aef9ef0" Accept-Ranges: bytes Content-Length: 101118 Connection: close Content-Type: image/jpeg A: get_bad.jpg B: Date: Tue, 08 Mar 2016 00:44:20 GMT Server: Apache Content-Length: 1363 X-Frame-Options: deny Connection: close Content-Type: text/html 

在“坏”情况下(不存在的图像文件)“B”检索到一小块(Googlebot?)HTML代码并将其保存为目标,因此Content-Length为1363字节。