最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Python中,用urllib2.urlopen(picUrl_othersite)返回的结果:<addinfourl at 27548688 whose fp = <socket._fileobject object at 0x019CDB30>>是什么意思

Python crifan 6075浏览 0评论

【已解决】Python中,用urllib2.urlopen(picUrl_othersite)返回的结果:<addinfourl at 27548688 whose fp = <socket._fileobject object at 0x019CDB30>>是什么意思

【背景】
打算urllib.urlretrieve(picUrl_othersite, saved_pic_othersite)去将网络上的图片下载到本地。
其中
picUrl_othersite = ‘https://www.crifan.com/files/pic/work_and_job/other_site/qq_com_b.gif’
是图片的网络地址,saved_pic_othersite是本地保存带路径的文件名。

结果有些图片下载很慢,甚至会死掉。
后来发现,有些网络图片,下载下来的,其实是个无效的网页,而不是图片本身。
所以希望找个timeout机制,或者下载之后检测图片的有效性。

后来想到,在下载图片之前,去通过urllib2.urlopen打开这个图片地址,看看返回值是否有效,或者是否可以正常打开。
结果去:
ret_picUrl = urllib2.urlopen(picUrl_othersite)
print ret_picUrl
但是打印的结果却是这样的:
ret_picUrl= <addinfourl at 27548688 whose fp = <socket._fileobject object at 0x019CDB30>>
对于这样的结果,完全不懂是啥意思,以为此图片链接是无法打开的,是无效的呢。

 

【解决过程】
1.网上找了下,有人:
http://topic.csdn.net/u/20110908/09/9715217d-c9c3-4327-85a5-dfa0e32c7766.html
说道,可以通过:
print ret_picUrl.headers[‘Content-Length’]
去打印出来返回内容的长度,我这里返回的是43。
但是还是不懂上述返回内容是什么含义。
以及如何去判断此图片地址是否是有效的。
2.后来去google中搜索addinfourl而找到这里:
http://epydoc.sourceforge.net/stdlib/urllib.addinfourl-class.html
但是好像还是没有看到具体什么解释。
不过倒是发现了一点,addinfourl的Known Subclasses: urllib2.HTTPError
所以,看起来,还是和urllib2.HTTPError有关的。

3.后来去手册中,搜索前面已经知道的Content-Length,然后搜到了这个:

“20.5. urllib — Open arbitrary resources by URL”,也是和Content-Length相关的。

然后就去看urllib部分的介绍,发现里面有句:

“Deprecated since version 2.6: The urlopen() function has been removed in Python 3.0 in favor of urllib2.urlopen().”

所以就又去打开:

urllib2.urlopen(url[, data][, timeout])

然后就最终发现,其实,手册里面本身就解释的很清楚了:

 

urllib2.urlopen(url[, data][, timeout])

Open the URL url, which can be either a string or a Request object.

Warning

HTTPS requests do not do any verification of the server’s certificate.

data may be a string specifying additional data to send to the server, or None if no such data is needed. Currently HTTP requests are the only ones that use data; the HTTP request will be a POST instead of a GET when the data parameter is provided. data should be a buffer in the standard application/x-www-form-urlencoded format. The urllib.urlencode() function takes a mapping or sequence of 2-tuples and returns a string in this format. urllib2 module sends HTTP/1.1 requests with Connection:close header included.

The optional timeout parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used). This actually only works for HTTP, HTTPS and FTP connections.

This function returns a file-like object with two additional methods:

  • geturl() — return the URL of the resource retrieved, commonly used to determine if a redirect was followed
  • info() — return the meta-information of the page, such as headers, in the form of an mimetools.Message instance (see Quick Reference to HTTP Headers)

   

对照其解释,

ret_picUrl = urllib2.urlopen(picUrl_othersite)

此时urlopen的返回值ret_picUrl,其实是一个Object,然后该对象有两个method方法:

(1)geturl():可以获得此网络资源,此处是图片的真实地址。而此方法,常可用来判断一个网址是否被重定向了。

即如果重定向了,那么你调用urllib2.urlopen时所给的网址,应该和这个返回的网址不同,返回的网址,才是此网络资源(文件)的真实地址。
 (2)info():返回对应的meta信息。例如headers,此处,就对应着前面已经使用了的ret_picUrl.headers[‘Content-Length’]。

而重点是,更多相关的header等信息,可以通过上面的链接Quick Reference to HTTP Headers找到。

 

然后就找到了我所要的信息:

 Content-Type [Entity]

Specifies the Internet media type of the entity-body that is sent or would have been sent if requested. Often includes a charset parameter specifying the character encoding.

   具体的解释是:

 14.17 Content-Type

The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET.

       Content-Type   = "Content-Type" ":" media-type  

Media types are defined in section 3.7. An example of the field is

       Content-Type: text/html; charset=ISO-8859-4  

Further discussion of methods for identifying the media type of an entity is provided in section 7.2.1.

   然后我此处程序里面尝试:

<p> print 'geturl=',ret_picUrl.geturl()</p><p> print 'info=',ret_picUrl.info()</p>
对应的输出是:
<table border="1" cellspacing="1" cellpadding="1" width="80%"><tbody><tr><td><font size="2">geturl= <a rel="nofollow" href="https://www.crifan.com/files/pic/work_and_job/other_site/qq_com_b.gif">https://www.crifan.com/files/pic/work_and_job/other_site/qq_com_b.gif</a><br />info= Server: NWS_imgcache_HY<br />Connection: close<br />Date: Thu, 22 Dec 2011 12:46:32 GMT<br />Cache-Control: max-age=2592000<br />Expires: Sat, 21 Jan 2012 12:46:32 GMT<br />Last-Modified: Fri, 09 Jun 2006 10:12:42 GMT<br />Content-Type: image/gif<br />Content-Length: 43</font></td></tr></tbody></table>
所以,可以很清楚的看到,这里的图片的链接,是有效的。
返回的信息,对应的表示此网络资源是gif图片,大小是43字节。
至此,才彻底说明,此图片是正常可以打开的,该网络资源是有效的。
这样,就可以通过这样的方法,去判断一个图片是否有效了,就真正实现了我的目的:在下载图片之前,先去判断是否有效。
【总结】
Python中,用urllib2.urlopen(picUrl_othersite)返回的结果:<addinfourl at 27548688 whose fp = <socket._fileobject object at 0x019CDB30>>,说明是正常的。
接着用对类似下面的代码,可以查看到返回的内容的相关详尽信息:
<p>ret_picUrl = urllib2.urlopen(picUrl_othersite)<br />print 'ret_picUrl=',ret_picUrl<br />print 'geturl=',ret_picUrl.geturl()<br />print 'info=',ret_picUrl.info() </p>
&nbsp;<wbr></wbr>

转载请注明:在路上 » 【已解决】Python中,用urllib2.urlopen(picUrl_othersite)返回的结果:<addinfourl at 27548688 whose fp = <socket._fileobject object at 0x019CDB30>>是什么意思

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
89 queries in 0.268 seconds, using 22.20MB memory