urllib2.urloopen将永远挂起,尽管超时



希望这是一个相当简单的问题,但它让我发疯了。我在ubuntu 12.10服务器的开箱即用安装上使用Python 2.7.3。我一直在放大这个问题,直到看到这个代码片段:

import urllib2
x=urllib2.urlopen("http://casacinema.eu/movie-film-Matrix+trilogy+123+streaming-6165.html", timeout=5)

它只是永远挂起,永远不会超时。我显然做错了什么。有人能帮忙吗?非常感谢!

Matteo

看起来您遇到了代理问题。这里有一个关于如何解决这个问题的很好的解释:尝试使用Python中的urllib2访问Internet。

我已经用python 2.7.3在我的ubuntu上执行了你的代码,没有看到任何错误。

同时,考虑使用request:

import requests
response = requests.get("http://casacinema.eu/movie-film-Matrix+trilogy+123+streaming-6165.html", timeout=5)
print response.status_code

参见:

  • 代理Python '请求'模块

最初的海报说他们不明白为什么它会挂起来,但他们也想要一个办法让urllib.request.urlopen不被挂起来。我不能说如何让它不被悬挂,但如果它能帮助别人,这就是为什么它可以悬挂。

Python-urllib/3.6客户端是挑剔的。例如,它期望服务器返回HTTP/1.1 200 OK而不是HTTP 200 OK。它还期望服务器在发送报头中的connection: close时关闭连接。

诊断此问题的最佳方法是获取服务器响应的原始输出,并将其与您知道有效的另一个服务器响应进行比较。然后,如果您必须创建一个服务器并操作响应,以确定导致差异的确切原因。也许,这至少可以导致服务器上的更改,并允许它不挂起。

可以尝试使用alecxe建议的socket.setdefaulttimeout(5)。

更多细节见urllib2 doc

Sockets and Layers

Python对从web获取资源的支持是分层的。Urllib2使用httplib库,而后者又使用套接字库。

从Python 2.3开始,你可以指定套接字在超时之前等待响应的时间。这在需要获取网页的应用程序中非常有用。默认情况下,socket模块没有超时,可以挂起。目前,套接字超时没有在httplib或urllib2级别公开。但是,您可以使用

为所有套接字全局设置默认超时。
import socket
import urllib2
# timeout in seconds
timeout = 10
socket.setdefaulttimeout(timeout)

最新更新