当读取发生在urllib时

时间:2018-06-11 14:18:28

标签: python python-3.x urllib

请考虑以下代码:

r = urllib.request.urlopen("https://example.com")
print(r.read())  # Does reading occurs at this point?

我的问题是,在调用urlopen()或调用read()时读取的时间是什么时候。

1 个答案:

答案 0 :(得分:1)

在再次阅读文档并进行一些测试之后,我可以说两者都可以进行阅读。

urlopen是一个阻塞调用,实际上等待了标题部分的结尾。此时,代码和标头属性可用。

但是如果服务器是slooooow,urlopen可能会在收到所有数据部分之前返回。在这种情况下,如果收到的字节少于n个,read(n)可能会阻塞,read()将阻塞,直到收到所有响应为止。

代码证明:

服务器:

class ReqHandler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        print("GOT", self.command)
        print("Headers", self.headers)
        self.wfile.write(b"HTTP/1.1 200 OK\r\n")
        time.sleep(2)
        self.wfile.write(b"Server: BaseHTTP/0.6 Python/3.6.2\r\n\
Date: Mon, 11 Jun 2018 15:47:00 GMT\r\n\r\n")
        time.sleep(2)
        self.wfile.write("""<html>
<header><title>Test page</title></html>
<body><h1>Test</h1>
<p>This is a simple test...</p>""".encode())
        time.sleep(5)
        self.wfile.write("""<p>and here is the end of the page</p>
</body></html>""".encode())

server = http.server.HTTPServer(('localhost', 8080), ReqHandler)
server.handle_request()

客户端:

def ask():
    print(time.asctime())
    r = urllib.request.urlopen("http://localhost:8080/test_page")
    print(time.asctime())
    print(r.read(10))
    print(time.asctime())
    print(r.read())
    print(time.asctime())

ask()

这是客户端的一个例子:

Mon Jun 11 18:13:12 2018
Mon Jun 11 18:13:15 2018
b'<html>\n<he'
Mon Jun 11 18:13:17 2018
b'ader><title>Test page</title></html>\n<body><h1>Test</h1>\n<p>Ceci est un simple test</p><p>mais avec des charact\xe8res accentu\xe9s</p>\n</body></html>'
Mon Jun 11 18:13:22 2018

所以:

  • urlopen等待3秒,直到标题部分的结尾
  • 首先阅读(read(10))等待消息的第一部分2秒以上
  • 第二次阅读(read())在消息结束时等待5秒钟