Python urllib2.urlopen()是否实际获取页面?
当我使用urllib2.urlopen()时,我正在压缩。它是只读取标题还是实际返回整个网页 IE HTML页面实际上是通过urlopen调用还是read()调用获取的 我要求的原因是这个工作流Python urllib2.urlopen()是否实际获取页面?,python,urllib2,Python,Urllib2,当我使用urllib2.urlopen()时,我正在压缩。它是只读取标题还是实际返回整个网页 IE HTML页面实际上是通过urlopen调用还是read()调用获取的 我要求的原因是这个工作流 我有一个url列表(其中一些带有短url服务) 我只想阅读网页,如果我没有看到该网址之前 我需要调用urlopen()并使用geturl()获取链接指向的最后一个页面(在302重定向之后),这样我就知道我是否已经对它进行了爬网 如果我已经解析了html页面,我不想承担获取html的开销 谢谢 通过查
- 我有一个url列表(其中一些带有短url服务)
- 我只想阅读网页,如果我没有看到该网址之前
- 我需要调用urlopen()并使用geturl()获取链接指向的最后一个页面(在302重定向之后),这样我就知道我是否已经对它进行了爬网
- 如果我已经解析了html页面,我不想承担获取html的开销
谢谢 通过查看页面,我非常确定它可以获得页面的内容。返回的对象包含页面。使用本地web服务器测试时,
urlib2.urlopen(url)
发出HTTP请求,而.read()
没有。urlib2
始终使用HTTP方法GET
(或POST
),因此不可避免地会获取整个页面。要改为使用HTTP方法HEAD
(它只获取头——这足以遵循重定向!),我认为您只需要使用自己的类对urlib2.Request
进行子类化,并覆盖一个简短的方法:
class MyRequest(urllib2.Request):
def get_method(self):
return "HEAD"
并将一个适当初始化的
MyRequest
实例传递给urllib2.urlopen
,如果您使用,它会智能地发送给您。如果您自己的解决方案已经做得很好,那么就没有必要推出它。我刚刚用wireshark运行了一个测试。当我调用urllib2.urlopen('url-for-a-700mbyte-file')时,只立即检索到body的头和几个数据包。直到我调用read()时,身体的大部分才通过网络到达。这与我通过阅读httplib模块的源代码所看到的一致
因此,为了回答最初的问题,urlopen()不会通过网络获取整个主体。它获取头文件,通常还有一些正文。调用read()时,将获取正文的其余部分
部分正文提取是预期的,因为:
实际上,由于一些正文通常与标题一起获取,您可能会发现小正文(例如,小html页面)完全是通过urlopen()调用获取的。您可以选择使用以下内容读取响应的一部分:
urllib2.Request(url, None, requestHeaders).read(CHUNKSIZE)
我刚刚检查过,这只从服务器读取CHUNKSIZE字节。对于其他人,您能告诉我们您使用的是什么刮取库吗?实际上,使用Python2.6进行测试表明,在urlopen()调用中,只有一小部分主体通过网络检索。其余部分等待read()被调用。@Forest,HTTP的
GET
动词被定义为检索整个页面;可能你没有看到的部分是阻塞了操作系统和网络硬件缓冲区(顺便说一句,这是一件非常糟糕的事情)。我相信问题不是关于HTTP方法,而是关于在urllib2实现的不同阶段网络上发生了什么。查看我的答案了解详细信息。我打赌尚未检索到的正文数据包正在阻塞操作系统或硬件缓冲区(包括服务器和客户端之间的任何位置,可能在路由器上,中间是c)。。。几乎不是一件好事:-(.Alex,我很感谢你的关注,但是没有任何东西会被阻塞。HTTP运行在TCP之上,它实现了流量控制。但是在使用urlib2.urlopen
时获取什么的关注,request
模块有用吗?如果你真的想知道页面requests.head的大小(url,headers={'Accept-Encoding':'identity'})。可以使用headers.get('content-length',None)
。考虑在http中支持范围!
urllib2.Request(url, None, requestHeaders).read(CHUNKSIZE)