系统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