系统winxp python 版本 2.6.6
用python 的urllib2模块做HTTP Basic Access Authentication 认证超过6次后抛出HTTPError
import urllib2
import os
import re
import time
userAgent="Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6"
routerUrl="http://192.168.1.1/"
routerUser="admin"
routerPasswd="XXXXXX"
routerTimeout=15
routerCount=0 #请求次数
fileName,fileExt=os.path.splitext(__file__)
def getRouterOpener():
password_mgr=urllib2.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password("tomato",routerUrl,routerUser,routerPasswd)
httpBasicAuthHandler=urllib2.HTTPBasicAuthHandler(password_mgr)
routerOpener=urllib2.build_opener(httpBasicAuthHandler)
routerOpener.addheaders = [('Referer',routerUrl),('User-agent', userAgent),("Cache-Control","max-age=0")]
return routerOpener
def disConnectRoute(routerOpener):
print u"正在关闭路由连接"
print u"路由连接关闭成功"
#print response.getcode()
def reConnectRoute(routerOpener):
print u"正在重新路由连接"
print u"路由连接连接成功"
def changeIp(routerOpener):
global routerCount
routerCount=routerCount+1
#disConnectRoute(routerOpener)
#reConnectRoute(routerOpener)
print "changeIp start",str(routerCount)
response=routerOpener.open(routerUrl,None,routerTimeout)
print "changeIp end"
#print response.read()
if __name__=="__main__":
routerOpener=getRouterOpener() #得到opener
#response=routerOpener.open(routerUrl,None,routerTimeout)
while(True):
try:
changeIp(routerOpener)
time.sleep(1)
except urllib2.HTTPError,e:
print e
os.system("pause")
except urllib2.URLError as reason:
print "reason",reason
except:
pass
os.system("pause")
因为要多次请求网页 所以用一个OpenerDirector 对象,当打开页面超过5次后 开始抛出HTTPError。
通过监听http发现 当 OpenerDirector对象open超过5个请求页面之后header中Authorization丢失 所以认证通不过。
进入urllib2.HTTPBasicAuthHandler类->http_error_401()->http_error_auth_reqed()后此方法在830行处判断if self.retried > 5: 则抛出HTTPError。self.retried 小于5则继续执行 在header中添Authorization。而在此类中并没有提供self.retried 恢复为0的方法。所以当OpenerDirector打开6个以上页面时self.retried则始终大于5,此时认证失败,所以抛出HTTPError
修复办法:。。。。。。
备注:参考 urllib2.AbstractDigestAuthHandler中reset_retry_count