51

拨打电话 时是否urllib2获取整个页面?urlopen

我想只阅读 HTTP 响应标头而不获取页面。看起来像是urllib2打开了 HTTP 连接,然后获得了实际的 HTML 页面......或者它只是开始通过urlopen调用缓冲页面?

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
4

6 回答 6

52

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

来自urllib2 文档

urllib2.urlopen(url[, 数据][, 超时])

...

这个函数返回一个类似文件的对象,它有两个额外的方法:

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

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

请注意,使用 httplib.HTTPMessage 的主要警告记录在python 问题 4773中。

于 2009-10-29T00:17:31.327 回答
41

发送 HEAD 请求而不是普通的 GET 请求怎么样。以下剪辑(从类似问题复制)正是这样做的。

>>> 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')]
于 2009-05-09T14:17:34.550 回答
22

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

上面@reto 链接到的问题显示了如何让 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 网络协议分析器之类的工具进行检查,您会发现它实际上是在发送 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 GMT
内容类型:text/html;charset=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=2012 年 8 月 17 日星期五 13:20:56;路径=/; HttpOnly

但是,正如另一个问题的其中一条评论中所提到的,如果有问题的 URL 包含重定向,那么 urllib2 将向目标发出 GET 请求,而不是 HEAD。如果您真的只想发出 HEAD 请求,这可能是一个主要缺点。

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

GET /2009/05/come-and-draw-the-circle-of-unity-with-us/ HTTP/1.1
接受编码:身份
主机: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,放气
用户代理:Python-httplib2/0.7.2 (gzip)

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

HEAD /2009/05/come-and-draw-the-circle-of-unity-with-us/ HTTP/1.1
主机:www.kidsidebyside.org
接受编码:gzip,放气
用户代理:Python-httplib2/0.7 .2 (gzip)

于 2012-02-19T14:27:46.290 回答
8

urllib2.urlopen 执行 HTTP GET(或 POST,如果您提供数据参数),而不是 HTTP HEAD(如果它执行后者,您当然不能对页面正文执行 readlines 或其他访问)。

于 2009-05-09T14:18:33.533 回答
5

单线:

$ python -c "import urllib2; print urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)).open(urllib2.Request('http://google.com'))"
于 2012-03-30T08:11:23.743 回答
-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  
于 2014-07-28T09:25:02.920 回答