urllib2何时真正从URL下载文件?
url = "http://example.com/file.xml"
data = urllib2.urlopen(url)
data.read()
这个问题是,文件到底什么时候会从网上下载呢?是我使用urlopen的时候,还是在调用.read()的时候?我在网络接口上看到这两次都有很高的流量。
2 个回答
5
我同意ddaa的看法。不过,如果你想了解这类事情,可以用像nc
这样的工具在你的电脑上搭建一个简单的服务器,然后在Python的交互式解释器中打开网址。
在一个终端窗口中,运行nc -l 1234
,这会在你电脑的1234端口上打开一个连接,等待其他设备的连接。nc
会接受一个连接,并显示它从这个连接中读取到的内容。你在nc
中输入的任何内容都会通过这个连接发送出去,这里指的是Python的urlopen()
。
在另一个终端窗口中运行Python,然后输入你的代码,比如:
data = urllib2.urlopen('http://127.0.0.1:1234')
data.read()
调用urlopen()
时,会建立与服务器的连接,发送请求,然后会等待响应。在这个过程中,你会看到nc
在它的终端中打印出HTTP请求。
现在在运行nc
的终端中输入一些内容。此时,urlopen()
仍然会等待,直到你在nc
中按下回车键,也就是直到它接收到一个换行符。所以urlopen()
不会返回,直到它至少读取到一个换行符。(如果你担心nc
可能会有缓冲,这不是问题。urlopen()
会一直等待,直到看到第一个换行符。)
所以需要注意的是,urlopen()
会一直等待,直到接收到第一个换行符,之后才能从连接中读取数据。实际上,HTTP的响应通常是短的多行内容,所以urlopen()
应该会很快返回。
5
在不看代码的情况下,我会猜测以下情况会发生:
urlopen()
会打开一个连接,并发送请求。然后服务器开始发送回复。在这个时候,数据会在缓冲区里积累,直到缓冲区满了,操作系统会告诉服务器稍等一下。- 接着
data.read()
会清空缓冲区,这样操作系统就会告诉服务器继续发送,剩下的回复就会被下载下来。
当然,如果回复内容比较短,或者 .read()
执行得足够快,那么缓冲区就没有时间填满,下载就会一次性完成。