Ошибка HTTP 401 при использовании скрипта очистки Mechanize для Python

Я пишу скрипт для автоматического извлечения информации с веб-сайта каталога моей компании с помощью mechanize. Однако интерпретатор возвращает _response.httperror_seek_wrapper: Ошибка HTTP 401: требуется авторизация onbr.open(url) при запуске сценария. Это часть моего кода, где интерпретатор сталкивается с ошибкой.

from sys import path 
path.append("./mechanize/mechanize")
import _mechanize 
from base64 import b64encode 

def login (url, username, password):
    b64login = b64encode('%s:%s' % (username, password))
    br = _mechanize.Browser()
    br.set_handle_robots(False)
    br.addheaders.append(('Authorization','Basic %s' % b64login)) 
    br.open(url)
    r = br.response()
    print r.read()

Сайт, к которому я пытаюсь получить доступ, является внутренним сайтом в сети моей компании и использует сертификат GlobalSign для аутентификации на компьютерах, выпущенных компанией.

Я уверен, что вводимая мной аутентификационная информация верна, и я везде искал решение. Любые подсказки о том, как решить эту проблему? Спасибо!


person xag9bb    schedule 04.06.2014    source источник
comment
Можете дать ссылку на сайт? Трудно ответить на этот вопрос, не посмотрев!   -  person coder006    schedule 06.06.2014
comment
Мне не разрешено раскрывать эту информацию по соображениям безопасности. Но я могу сказать вам, что это внутренний сайт, и доступ к нему невозможен, если вы не находитесь внутри сети компании. Если я запущу код в другой сети, интерпретатор вернет [Errno 104] Connection reset by peer   -  person xag9bb    schedule 07.06.2014


Ответы (1)


Похоже, ваши методы аутентификации не совпадают. Вы заявляете, что ваша компания использует сертификаты GlobalSign, но ваш код использует обычную аутентификацию. Они НЕ равны!!

Кратко ознакомившись с документацией по Mechanize (которая ограничена), вы не реализуйте аутентификацию, вручную добавляя заголовки. У него есть собственный метод add_password для обработки аутентификации.

Кроме того, в соответствии с общей политикой HTTP-аутентификации вам следует НЕ использовать упреждающую аутентификацию, самостоятельно добавляя заголовки аутентификации. Вы должны настроить свой код с необходимой аутентификацией (на основе документации вашей библиотеки) и позволить ему обрабатывать согласование аутентификации.

person ke4ktz    schedule 04.06.2014
comment
Спасибо за быстрый ответ! Я пытался использовать метод add_password, но все равно получаю ту же ошибку. Есть ли у вас другие предложения по возможному решению? - person xag9bb; 05.06.2014
comment
Единственные методы аутентификации, упомянутые в их документации (с которыми вы должны быть знакомы), это Basic и Digest. Вполне возможно, что он не поддерживает необходимую вам аутентификацию. Возможно, вам придется найти другую библиотеку для выполнения того, что вы хотите. - person ke4ktz; 06.06.2014
comment
Я использовал инструмент отладки в классе браузера/завитке и, глядя на заголовок, это обычная аутентификация («WWW-Authenticate: Basic realm = 'имя области'»). Я попытался передать тип области (Basic) в метод add_password, и мне не повезло. Любые другие идеи о том, что проблема может быть? - person xag9bb; 07.06.2014
comment
Вы должны увидеть попытку подключения без значения заголовка аутентификации. Сервер должен отклонить и ответить ответом заголовка WWW-Authenticate, по одному для каждого поддерживаемого метода. Затем должна быть предпринята еще одна попытка с заголовком Authorization, соответствующим одному из требуемых методов аутентификации. - person ke4ktz; 09.06.2014
comment
Вот что я получаю: send: 'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: 'hostname'\r\nConnection: close\r\nAuthorization: Basic 'b64encoded_string'\r\nUser- Agent: Python-urllib/2.7\r\n\r\n' reply: 'HTTP/1.1 401 Authorization Required\r\n' header: Date: 'date' header: Server: Apache header: WWW-Authenticate: Basic realm='realm' header: Content-Length: 533 header: Connection: close header: Content-Type: text/html; charset=iso-8859-1 header: Set-Cookie: 'cookie' Видите ли вы что-нибудь, что может быть полезно для выяснения проблемы? - person xag9bb; 09.06.2014
comment
Вы удалили вызов метода br.addheaders.append() в своем коде? Упреждающая аутентификация НЕ не рекомендуется и может прерывать подтверждение аутентификации, не позволяя клиенту отправить следующую попытку подключения после получения ответа об ошибке 401. - person ke4ktz; 10.06.2014
comment
Я пытался использовать метод add_password() без br.addheaders.append(), и все равно не повезло. Я получаю все те же ошибки. - person xag9bb; 12.06.2014
comment
После удаления br.addheaders.append() вы должны увидеть, как приложение выполняет GET без заголовков аутентификации. Сервер ответит 401. Затем ваше приложение должно выдать еще один GET с заголовком аутентификации. Все это должно происходить автоматически при вызове br.open(). Вы видите это? - person ke4ktz; 14.06.2014
comment
Если я удалю все функции аутентификации (addheaders.append() и add_password()), то получу ответ об ошибке 104 со следующим выводом: send: 'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: 'hostname'\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n'. - person xag9bb; 19.06.2014
comment
Если вы используете только add_password(), вы должны увидеть, что ваш клиент попытается подключиться снова, за исключением того, что он будет содержать заголовки аутентификации. Если он не пытается подключиться или не проверяет, эта библиотека вам не подойдет. - person ke4ktz; 19.06.2014