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"
没有评论 :
发表评论