urllib2何时真正从URL下载文件?

2 投票
2 回答
1269 浏览
提问于 2025-04-11 09:29
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

在不看代码的情况下,我会猜测以下情况会发生:

  1. urlopen() 会打开一个连接,并发送请求。然后服务器开始发送回复。在这个时候,数据会在缓冲区里积累,直到缓冲区满了,操作系统会告诉服务器稍等一下。
  2. 接着 data.read() 会清空缓冲区,这样操作系统就会告诉服务器继续发送,剩下的回复就会被下载下来。

当然,如果回复内容比较短,或者 .read() 执行得足够快,那么缓冲区就没有时间填满,下载就会一次性完成。

撰写回答