import sys import time try: from urllib2 import urlopen except: from urllib.request import urlopen url = 'http://www.baidu.com' start = time.time() res = urlopen(url).read() elapsed = time.time() - start print('Elapsed time: {0}'.format(elapsed))
如果你的IE中有设置代理服务器,如上代码跑下来很可能要接近5秒,但取消代理设置之后,1秒都不需要。
pdb跟了半天,过程就不写了,直接说结论吧,问题出在urllib.py(Python 2.7.1,下同)的1534行,proxy_bypass函数:
def proxy_bypass(host): """Return a dictionary of scheme -> proxy server URL mappings. Returns settings gathered from the environment, if specified, or the registry. """ if getproxies_environment(): return proxy_bypass_environment(host) else: return proxy_bypass_registry(host)
getproxies_environment函数用来获取以“_PROXY”结尾的环境变量,如果不存在则返回空的dict。也就是说,有类似的环境变量存在则执行proxy_bypass_environment函数,没有则执行proxy_bypass_registry函数。
而导致urlopen如此之慢的罪魁祸首,就在urllib.py第1511行,proxy_bypass_registry函数中的这一句:
fqdn = socket.getfqdn(rawHost)
执行getfqdn函数,会向rawHost发送三次NetBIOS Name Query请求。也就是这三次压根不会收到返回数据的请求,导致了urlopen会慢成这样。而proxy_bypass的功能,也不过就是确定某个host要不要走代理而已。
Python 2.7.1和3.2均有这个问题,我想保留这个设计总是有一定道理的吧。不过总这么delay也不是事,所以要在IE里设置代理又要用Python写的东西,只有多设置几个环境变量了:
SET HTTP_PROXY="127.0.0.1:8118" SET HTTPS_PROXY="127.0.0.1:8118" SET NO_PROXY="localhost,127.0.0.1"
没有评论 :
发表评论