清除mechanize.Browser实例中的密码存储区?

时间:2014-09-11 16:46:43

标签: python python-2.7 mechanize-python

我需要以编程方式从网站上抓取数据并使用mechanize(v0.2.5)来执行此操作。由于我无法控制的原因,HTTP身份验证的确切密码经常更改,但是以可预测的方式。

所以我尝试循环遍历每个要尝试的密码,并忽略身份验证错误,直到找到一个有效的密码:

br = mechanize.Browser()
br.set_handle_robots(False)

for pwd in various_permutations_of_password():
    try:
        print "Trying password: %s" % pwd
        br.add_password(site, username, pwd)
        response = br.open(url)
        break
    except Exception as e:
        pass
else:
    raise e

令人惊讶的是,即使添加了正确的密码,这也不起作用。据我所知,问题是Browser对象保留并尝试使用以前的错误密码,而不是使用最新添加的密码。

我提出的最佳解决方法是在每次迭代时创建一个新的Browser实例:

for pwd in various_permutations_of_password():
    try:
        br = mechanize.Browser()
        br.set_handle_robots(False)

        print "Trying password: %s" % pwd
        br.add_password(site, username, pwd)
        response = br.open(url)
        break
    except Exception as e:
        pass
else:
    raise e

有更好的方法吗?有没有办法让Browser对象“忘记”特定网站的凭据而不会丢失其中的其他有状态浏览信息?

我还查看了库代码,并且不明白为什么当我添加一个具有相同add_password的新密码时,url的底层实现不会覆盖以前的密码:< / p>

class UserAgentBase:
    ...
    def add_password(self, url, user, password, realm=None):
        self._password_manager.add_password(realm, url, user, password)

class HTTPPasswordMgr:
    ...
    def add_password(self, realm, uri, user, passwd):
        # uri could be a single URI or a sequence
        if isinstance(uri, basestring):
            uri = [uri]
        if not realm in self.passwd:
            self.passwd[realm] = {}
        for default_port in True, False:
            reduced_uri = tuple(
                [self.reduce_uri(u, default_port) for u in uri])
            self.passwd[realm][reduced_uri] = (user, passwd)

0 个答案:

没有答案