繁体   English   中英

urllib2超时,但没有关闭套接字连接

[英]urllib2 times out but doesn't close socket connection

我正在制作一个python URL采集器程序。 就我的目的而言,我希望它真的非常快地超时,所以我正在做

urllib2.urlopen("http://.../", timeout=2)

当然,它应该正确地超时。 但是,关闭与服务器的连接并不麻烦,因此服务器认为客户端仍处于连接状态。 如何要求urllib2在超时后仅关闭连接?

运行gc.collect()不起作用,如果我不能帮忙,我不想使用httplib。

我能得到的最接近的是:第一次尝试会超时。 服务器报告连不上就像第二次尝试超时。 然后,服务器报告连接已关闭, 就像第三次尝试超时一样。 广告无限。

非常感谢。

我怀疑套接字在堆栈框架中仍处于打开状态。 当Python引发异常时,它将存储堆栈帧,以便调试器和其他工具可以查看堆栈并进行内部检查。

由于历史原因,现在为了向后兼容,堆栈信息(基于每个线程)存储在sys中(请参阅sys.exc_info(),sys.exc_type和其他信息)。 这是Python 3.0中已删除的内容之一。

这对您来说意味着堆栈仍在运行并被引用。 该堆栈包含具有打开套接字的某些功能的本地数据。 这就是为什么插座尚未关闭的原因。 只有在删除堆栈跟踪时,所有内容才会被gc'ed。

要测试是否是这种情况,请插入类似

try:
  1/0
except ZeroDivisionError:
  pass

在您的except子句中。 这是用其他方法替换当前异常的快速方法。

这是一个hack,但是以下代码有效。 如果请求在另一个函数中并且没有引发异常,则套接字始终处于关闭状态。

def _fetch(self, url):
    try:
        return urllib2.urlopen(urllib2.Request(url), timeout=5).read()
    except urllib2.URLError, e:
        if isinstance(e.reason, socket.timeout):
            return None
        else:
            raise e

def fetch(self, url):
    x = None
    while x is None:
        x = self._fetch(url)
        print "Timeout"
    return x

有人有更好的方法吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM