对于我的项目,我必须检查网站的状态(在共享主机上)。
我使用Python请求库。
1
2
3
4
5def getStatusCode(url):
try:
return requests.head(url,timeout=0.3).status_code
except:
return -1
此代码在MacOS 10.10下使用Python3.4非常有效,其中包含http://www.google.com等网址。 如果我拔掉我的ISP电缆,我立即得到了例外。
在带有Python3.4的Ubuntu Server 14.04下,如果我拔掉我的ISP电缆,我永远不会收到超时错误。 Raspbian上的同样问题。
经过一些测试,如果我用IP http://216.58.212.100替换url,Ubuntu Server会引发异常,但由于我在共享的Web托管上,所以我无法使用IP。
经过一些研究后,我发现请求库中的超时和DNS查找之间存在差异,这种情况不是由操作系统执行,而是由操作系统执行。
所以我的问题是解决这个问题最美妙的方法是什么? 我是否需要在Python中添加额外的超时异常,如:函数调用超时
谢谢
看起来你回答了自己的问题(在SO上鼓励这样做)。我不知道更"美丽"的解决方案。我会发布您的最终代码和链接到任何有关OS不同的超时的相关研究(这对其他阅读此内容的人有用)。
谢谢查理。像我发布的链接或这里的解决方案的问题是它们的分辨率最小为1秒,而我的跳跃分辨率为毫秒级。也许有可能伪造基于IP的请求并编辑标题,以避免共享主机的问题。如果没有更好的,我会发布我的解决方案:)
现在我很好奇 - 为什么你需要毫秒级的URL请求解决方案?如果您需要并行启动数千个请求,那将需要一些工作。例如,请看这里。
事实上,我正在寻求监控我的ISP连接。我有微断开,我想要一个半秒的分辨率。使用Web请求不是非常有效,但它实际上比通过popen或子进程解析ping答案要复杂。但是当我学习Python时,我肯定错过了一些东西,我会采取更好的主张。
根据查理的鼓励,我在这里发布我的两个解决方案
对于第一个,我在请求标头中添加了主机,因此我可以将IP地址作为url和avoir DNS查找。
1
2
3
4
5
6
7
8def getStatusCode(url):
headers = {'host': 'www.example.com'}
try:
return requests.head(url,timeout=0.3,headers=headers).status_code
except:
return -1
print(getStatusCode('http://1.2.3.4'))
第二种解决方案基于信号的使用,但具有一秒的分辨率。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class timeout:
def __init__(self, seconds=1, error_message='Timeout'):
self.seconds = seconds
self.error_message = error_message
def handle_timeout(self, signum, frame):
raise TimeoutError(self.error_message)
def __enter__(self):
signal.signal(signal.SIGALRM, self.handle_timeout)
signal.alarm(self.seconds)
def __exit__(self, type, value, traceback):
signal.alarm(0)
def getStatusCode(url):
try:
return requests.head(url,timeout=0.3).status_code
except:
return -1
with timeout(seconds=1):
print(getStatusCode('http://www.example.com'))
(此解决方案来自Thomas Ahle,网址为https://stackoverflow.com/a/22348885/3896729)
现在我已经更好地理解了你的问题 - 我认为有一个更好的方法是使用你的操作系统ping应用程序,这在Python中应该不难做到 - 例如。您还应该平均1000个请求并查看平均值,标准偏差,异常值等。原因是如果一个请求需要500毫秒而您想要1毫秒的分辨率,则需要产生至少500个请求来获取任何内容接近你想要的分辨率。
使用Pythons urllib(2)的问题在于它的执行效果几乎不如系统级调用,因此您很难产生足够的线程来获得所需的时序分辨率。
最后,我会再次检查您的结果商业产品,以确保您的结果相似。例如(没有隶属关系):
http://www.thinkbroadband.com/ping。