python中urllib2模块 HTTPBasicAuthHandler认证 HTTPError bug

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

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(windows,python,OS,Access,firefox)