получение 401 ошибки непоследовательно из вызова python urllib2.urlopen

#python #urllib2

#python #urllib2

Вопрос:

У меня есть скрипт на python, который выполняет серию вызовов URL с использованием urllib2. URL-адрес находится на http, но требует аутентификации. В настоящее время я пытаюсь запустить скрипт таким образом, чтобы он совершил более 100 вызовов. Каждый раз, когда я запускаю скрипт, некоторые вызовы завершаются ошибкой с кодом ошибки 401, а некоторые проходят. Все вызовы выполняются по одному и тому же URL-адресу с использованием одного и того же имени пользователя и пароля. (Каждый раз, когда я запускаю скрипт, не одни и те же вызовы завершаются с ошибкой, иногда первый вызов завершается с ошибкой, иногда он работает.)

Есть идеи, почему 401 может возникать непоследовательно?

Сообщение об ошибке, выведенное на экран, выглядит следующим образом…

Вот метод, ответственный за выполнение вызова URL:

 def simpleExecuteRequest(minX, minY, maxX, maxY, type) :
    url = 'http://myhost.com/geowebcache/rest/seed/mylayer.xml'

    msgTemplate = """<?xml version="1.0" encoding="UTF-8"?>
    <seedRequest>
    <name>mylayer</name>
    <bounds>
    <coords>
    <double>%s</double>
    <double>%s</double>
    <double>%s</double>
    <double>%s</double>
    </coords>
    </bounds>
    <gridSetId>nyc</gridSetId>
    <zoomStart>0</zoomStart>
    <zoomStop>10</zoomStop>
    <format>image/png</format>
    <type>%s</type>
    <threadCount>1</threadCount>
    </seedRequest>
    """

    message = msgTemplate%(minX, minY, maxX, maxY, type)
    headers = { 'User-Agent' : "Python script", 'Content-type' : 'text/xml; charset="UTF-8"', 'Content-length': '%d' % len(message) }
    passwordManager = urllib2.HTTPPasswordMgrWithDefaultRealm()
    passwordManager.add_password(None, url, 'username', 'xxx')
    authenticationHandler = urllib2.HTTPBasicAuthHandler(passwordManager)
    proxyHandler = urllib2.ProxyHandler({})
    opener = urllib2.build_opener(proxyHandler, authenticationHandler)
    urllib2.install_opener(opener)    

    try :
        request = urllib2.Request(url, message, headers)
        response = urllib2.urlopen(request)
        content = response.read()
        print 'success'
    except IOError, e:
        print e
 

Иногда вывод будет выглядеть следующим образом…

 <urlopen error (10053, 'Software caused connection abort')>
success
success
<urlopen error (10053, 'Software caused connection abort')>
<urlopen error (10053, 'Software caused connection abort')>
...
 

При запуске через 1 минуту это может выглядеть так…

 success
<urlopen error (10053, 'Software caused connection abort')>
success
success
<urlopen error (10053, 'Software caused connection abort')>
 

При обоих запусках одна и та же серия входных данных для min / max x / y и type была предоставлена в том же порядке.

Ответ №1:

Код кажется мне правильным, так что я не вижу проблемы.

Вот несколько мыслей о том, как действовать дальше:

  • Обычно я обрабатываю http-запросы в командной строке curl , прежде чем переводить их в скрипт.
  • Библиотека запросов проще в использовании, чем urllib2
  • Когда вы получите ответ, распечатайте заголовки, чтобы вы могли видеть, что происходит
  • Вместо except IOError, e использования except IOError as e . Новый способ защищает вас от труднодоступных ошибок.
  • Я предполагаю, что вы отредактировали имя пользователя и пароль и используете настоящие в своем собственном скрипте 😉

Комментарии:

1. На данный момент я также согласен с тем, что проблема не в коде. Я добавил в сценарий логику повтора и ожидания. Если я просплю 5 секунд между неудачными попытками и повторю попытку до 10 раз, я смогу добиться успешного выполнения всех 119 запросов за одно выполнение скрипта. Некоторым потребовалось до 8 попыток, некоторым это удалось с первой попытки. Не очень красиво, но он справляется со своей задачей, поскольку это всего лишь одноразовый сценарий.