gpt4 book ai didi

python - 使用 urllib2 或任何其他 http 库读取超时

转载 作者:IT老高 更新时间:2023-10-28 20:22:51 27 4
gpt4 key购买 nike

我有读取这样的网址的代码:

from urllib2 import Request, urlopen
req = Request(url)
for key, val in headers.items():
req.add_header(key, val)
res = urlopen(req, timeout = timeout)
# This line blocks
content = res.read()

超时适用于 urlopen() 调用。但是随后代码到达了我想要读取响应数据的 res.read() 调用,并且在那里没有应用超时。因此,读取调用可能几乎永远挂起,等待来自服务器的数据。我发现的唯一解决方案是使用信号来中断 read(),因为我正在使用线程,所以不适合我。

还有哪些其他选择?是否有用于处理读取超时的 Python 的 HTTP 库?我查看了 httplib2 和请求,它们似乎遇到了与上述相同的问题。我不想使用 socket 模块编写我自己的非阻塞网络代码,因为我认为应该已经有一个库。

更新:以下解决方案都不适合我。下载大文件的时候,你可以自己看看设置socket或者urlopen超时是没有效果的:

from urllib2 import urlopen
url = 'http://iso.linuxquestions.org/download/388/7163/http/se.releases.ubuntu.com/ubuntu-12.04.3-desktop-i386.iso'
c = urlopen(url)
c.read()

至少在装有 Python 2.7.3 的 Windows 上,超时完全被忽略了。

最佳答案

如果不通过线程或其他方式使用某种异步计时器,任何库都无法做到这一点。原因是 timeout httplib 中使用的参数, urllib2和其他库设置 timeout在基础 socket . documentation 中解释了这实际上做了什么。 .

SO_RCVTIMEO

Sets the timeout value that specifies the maximum amount of time an input function waits until it completes. It accepts a timeval structure with the number of seconds and microseconds specifying the limit on how long to wait for an input operation to complete. If a receive operation has blocked for this much time without receiving additional data, it shall return with a partial count or errno set to [EAGAIN] or [EWOULDBLOCK] if no data is received.

粗体部分是关键。一个 socket.timeout只有在 timeout 的持续时间内没有接收到单个字节时才会引发 window 。换句话说,这是一个 timeout在接收到的字节之间。

使用 threading.Timer 的简单函数可能如下。

import httplib
import socket
import threading

def download(host, path, timeout = 10):
content = None

http = httplib.HTTPConnection(host)
http.request('GET', path)
response = http.getresponse()

timer = threading.Timer(timeout, http.sock.shutdown, [socket.SHUT_RD])
timer.start()

try:
content = response.read()
except httplib.IncompleteRead:
pass

timer.cancel() # cancel on triggered Timer is safe
http.close()

return content

>>> host = 'releases.ubuntu.com'
>>> content = download(host, '/15.04/ubuntu-15.04-desktop-amd64.iso', 1)
>>> print content is None
True
>>> content = download(host, '/15.04/MD5SUMS', 1)
>>> print content is None
False

除了检查 None ,也可以捕获 httplib.IncompleteRead异常不在函数内部,而是在函数外部。如果 HTTP 请求没有 Content-Length,则后一种情况将不起作用。标题。

关于python - 使用 urllib2 或任何其他 http 库读取超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9548869/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com