Очистить хранилище паролей в экземпляре mechanize.Browser?

Мне нужно соскрести данные с веб-сайта программно и я использую 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:

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 ответов

Другие вопросы по тегам