Python:从urllib2.urlopen调用获取HTTP头?

时间:2009-05-09 14:11:51

标签: python urllib forwarding

urllib2拨打urlopen时,urllib2是否会抓取整个页面?

我想在不获取页面的情况下阅读HTTP响应标头。看起来urlopen打开HTTP连接然后获取实际的HTML页面......或者只是通过import urllib2 myurl = 'http://www.kidsidebyside.org/2009/05/come-and-draw-the-circle-of-unity-with-us/' page = urllib2.urlopen(myurl) // open connection, get headers html = page.readlines() // stream page 调用开始缓冲页面?

{{1}}

6 个答案:

答案 0 :(得分:48)

使用response.info()方法获取标题。

来自urllib2 docs

  

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

     

...

     

此函数返回一个类似文件的对象,其中包含两个方法:

     
      
  • geturl() - 返回检索到的资源的URL,通常用于确定是否遵循重定向
  •   
  • info() - 以httplib.HTTPMessage实例的形式返回页面的元信息,例如标题(参见HTTP标题的快速参考)
  •   

因此,对于您的示例,请尝试逐步查看response.info().headers的结果。

请注意python issue 4773中记录了使用httplib.HTTPMessage的主要警告。

答案 1 :(得分:40)

如何发送HEAD请求而不是普通的GET请求呢?以下剪辑(从类似的question复制)就是这样做的。

>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]

答案 2 :(得分:20)

实际上,似乎urllib2可以执行HTTP HEAD请求。

上面链接到@reto的question显示了如何让urllib2执行HEAD请求。

这是我的看法:

import urllib2

# Derive from Request class and override get_method to allow a HEAD request.
class HeadRequest(urllib2.Request):
    def get_method(self):
        return "HEAD"

myurl = 'http://bit.ly/doFeT'
request = HeadRequest(myurl)

try:
    response = urllib2.urlopen(request)
    response_headers = response.info()

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response_headers.dict

except urllib2.HTTPError, e:
    # Prints the HTTP Status code of the response but only if there was a 
    # problem.
    print ("Error code: %s" % e.code)

如果您使用Wireshark网络协议analazer进行检查,您可以看到它实际上发送的是HEAD请求,而不是GET。

这是来自上面代码的HTTP请求和响应,由Wireshark捕获:

  

HEAD / doFeT HTTP / 1.1
接受编码:身份
主持人:   bit.ly
连接:关闭用户代理:Python-urllib / 2.7

     

HTTP / 1.1 301已移动
服务器:nginx
日期:2012年2月19日,星期日   格林威治标准时间13:20:56内容类型:text / html;字符集= UTF-8
  缓存控制:私有; max-age = 90
位置:   http://www.kidsidebyside.org/?p=445
MIME-版本:1.0
  内容长度:127

连接:关闭
Set-Cookie:   _bit = 4f40f738-00153-02ed0-421cf10a; domain = .bit.ly; expires = Fri Aug 17 13:20:56 2012; path = /;仅Http

但是,如其他问题中的一条评论中所述,如果相关网址包含重定向,则urllib2将向目标执行GET请求,而不是HEAD。如果您真的只想提出HEAD请求,这可能是一个主要的缺点。

上述请求涉及重定向。这是对目的地的请求,由Wireshark捕获:

  

GET / 2009/05 /与我们/ HTTP / 1.1的团结一致   Accept-Encoding:identity
主持人:www.kidsidebyside.org
  连接:关闭用户代理:Python-urllib / 2.7

使用urllib2的另一种方法是使用Joe Gregorio的httplib2库:

import httplib2

url = "http://bit.ly/doFeT"
http_interface = httplib2.Http()

try:
    response, content = http_interface.request(url, method="HEAD")
    print ("Response status: %d - %s" % (response.status, response.reason))

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response.__dict__

except httplib2.ServerNotFoundError, e:
    print (e.message)

这样做的好处是可以对初始HTTP请求和重定向到目标URL的请求使用HEAD请求。

这是第一个请求:

  

HEAD / doFeT HTTP / 1.1
主机:bit.ly
接受编码:gzip,   deflate
user-agent:Python-httplib2 / 0.7.2(gzip)

这是到目的地的第二个请求:

  

HEAD / 2009/05 /与我们/ HTTP / 1.1的团结一致的圈子   主持人:www.kidsidebyside.org
接受编码:gzip,deflate
  user-agent:Python-httplib2 / 0.7.2(gzip)

答案 3 :(得分:8)

urllib2.urlopen执行HTTP GET(如果提供数据参数,则执行POST),而不是HTTP HEAD(如果执行后者,则无法对页面主体执行读取或其他访问)。

答案 4 :(得分:5)

一衬垫:

$ python -c "import urllib2; print urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)).open(urllib2.Request('http://google.com'))"

答案 5 :(得分:-1)

def _GetHtmlPage(self, addr):
  headers = { 'User-Agent' : self.userAgent,
            '  Cookie' : self.cookies}

  req = urllib2.Request(addr)
  response = urllib2.urlopen(req)

  print "ResponseInfo="
  print response.info()

  resultsHtml = unicode(response.read(), self.encoding)
  return resultsHtml