urllib2.urlopen()实际上是否获取页面?

时间:2010-06-09 19:22:26

标签: python urllib2

当我使用urllib2.urlopen()时,我只是对标题读取进行了操作,还是实际上将整个网页带回来了?

IE实际上是在urlopen调用还是read()调用上获取HTML页面?

handle = urllib2.urlopen(url)
html = handle.read()

我问的原因是这个工作流程......

  • 我有一个网址列表(其中一些包含短网址服务)
  • 如果我之前没有看过该网址,我只想阅读网页
  • 我需要调用urlopen()并使用geturl()来获取链接所在的最终页面(在302重定向之后),所以我知道我是否已经抓取它。
  • 如果我已经解析了那个页面,我不想承担必须抓取html的开销。

谢谢!

6 个答案:

答案 0 :(得分:6)

我刚用wireshark进行测试。当我调用urllib2.urlopen('url-for-a-700mbyte-file')时,只会立即检索标题和一些正文包。直到我打电话给read(),大部分身体都来到了网络。这与我通过阅读httplib模块的源代码看到的相符。

因此,为了回答原始问题,urlopen()不会通过网络获取整个主体。它获取标题,通常是身体的某些。当你调用read()时,会获取正文的其余部分。

可以预期部分正文获取,因为:

  1. 除非您一次读取一个字节的http响应,否则无法确切知道传入标头的长度,因此无法知道正文开始之前要读取的字节数。

  2. http客户端无法控制服务器捆绑到响应的每个tcp帧中的字节数。

  3. 实际上,由于某些正文通常与标题一起被提取,因此您可能会发现在urlopen()调用中完全获取了小主体(例如小的html页面)。

答案 1 :(得分:3)

urllib2始终使用HTTP方法GET(或POST),因此不可避免地会获得整页。要改为使用HTTP方法HEAD(只获取标题 - 足以跟随重定向!),我认为您只需要将urllib2.Request子类化为您自己的类并覆盖一个简短方法:< / p>

class MyRequest(urllib2.Request):

    def get_method(self):
        return "HEAD"

并将适当初始化的MyRequest实例传递给urllib2.urlopen

答案 2 :(得分:1)

使用本地Web服务器进行测试,urllib2.urlopen(url)会触发HTTP请求,而.read()则不会。

答案 3 :(得分:0)

另外,如果你使用Scrapy,它会智能地为你做好。如果已经做得很好elsewhere,那么滚动自己的解决方案毫无意义。

答案 4 :(得分:0)

您可以选择阅读部分答案,例如......

urllib2.Request(url, None, requestHeaders).read(CHUNKSIZE)

这只从服务器读取CHUNKSIZE字节,我刚检查过。

答案 5 :(得分:-1)

docssource看,我很确定它会获取页面的内容。返回的对象包含页面。