Python urllib2 и [errno 10054] Существующее соединение было принудительно закрыто удаленным хостом, и возникли некоторые проблемы с urllib2 - PullRequest
7 голосов
/ 25 июля 2011

Я написал сканер, который использует urllib2 для получения URL.

каждые несколько запросов я получаю странное поведение, я пытался проанализировать его с помощью wireshark и не мог понять проблему.

getPAGE () отвечает за получение URL. он возвращает содержимое URL (response.read ()), если он успешно извлекает URL, иначе он возвращает None.

def getPAGE(FetchAddress):
    attempts = 0
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0'}
    while attempts < 2:
        req = Request(FetchAddress, None ,headers)
        try:
            response = urlopen(req) #fetching the url
        except HTTPError, e:
            print 'The server didn\'t do the request.'
            print 'Error code: ', str(e.code) + "  address: " + FetchAddress
            time.sleep(4)
            attempts += 1
        except URLError, e:
            print 'Failed to reach the server.'
            print 'Reason: ', str(e.reason) + "  address: " + FetchAddress
            time.sleep(4)
            attempts += 1
        except Exception, e:
            print 'Something bad happened in gatPAGE.'
            print 'Reason: ', str(e.reason) + "  address: " + FetchAddress
            time.sleep(4)
            attempts += 1
        else:
            return response.read()
    return None

это функция, которая вызывает getPAGE () и проверяет, верна ли загруженная страница (проверка с помощью - companyID = soup.find ('span', id = 'lblCompanyNumber'). String # если companyID равен None, страница недействительна), если страница действительна, она сохраняет объект-суппорт в глобальной переменной с именем 'curRes'.

def isValid(ID):
    global curRes
    try:
        address = urlPath+str(ID)
        page = getPAGE(address)
        if page == None:
            saveToCsv(ID, badRequest = True)
            return False
    except Exception, e:
        print "An error occured in the first Exception block of parseHTML : " + str(e) +' address: ' + address
    else:
        try:
            soup = BeautifulSoup(page)
        except TypeError, e:
            print "An error occured in the second Exception block of parseHTML : " + str(e) +' address: ' + address
            return False
        try:
            companyID = soup.find('span',id='lblCompanyNumber').string
            if (companyID == None): #if lblCompanyNumber is None we can assume that we don't have the content we want, save in the bad log file
                saveToCsv(ID, isEmpty = True)
                return False
            else:
                curRes = soup #we have the data we need, save the soup obj to a global variable
                return True
        except Exception, e:
            print "Error while parsing this page, third exception block: " + str(e) + ' id: ' + address
            return False

странное поведение -

  1. бывают случаи, когда urllib2 выполняет запрос GET и без в ожидании ответа отправляет следующий запрос GET (игнорируя последний запрос)
  2. иногда я получаю " [errno 10054] Существующее соединение было принудительно закрыто удаленным хостом" после того, как код просто зависнет примерно на 20 минут или около того, ожидая ответа от сервера, пока он застрял я копирую URL-адрес и пытаюсь получить его вручную, и я получаю ответ менее чем за 1 секунду (?).
  3. Функция getPAGE () вернет None в isValid (), если не удалось вернуть URL, иногда я получаю сообщение об ошибке -

Ошибка при разборе этой страницы, третий блок исключений: 'NoneType' У объекта нет атрибута 'string' id: ....

это странно, потому что я создаю объект супа, только если я получил действительный результат от getPAGE (), и кажется, что функция супа возвращает None, что вызывает исключение всякий раз, когда я пытаюсь запустить

companyID = soup.find ('span', id = 'lblCompanyNumber'). String

объект супа никогда не должен быть None, он должен получить HTML-код от getPAGE (), если он достигнет этой части кода

Я проверил и увидел, что проблема как-то связана с первой проблемой (отправка GET и не ожидание ответа, я увидел (на WireShark), что каждый раз, когда я получал это исключение, это было для URL, который отправил urllib2 GET-запрос, но не дождался ответа и пошел дальше, getPAGE () должен был вернуть None для этого URL, но если бы он возвращал None, isValid (ID) не прошел бы условие «if page == None:» Я не могу понять, почему это происходит, невозможно воспроизвести проблему.

Я читал, что time.sleep () может вызвать проблемы с многопоточностью urllib2 , так что, возможно, мне следует избегать его использования?

почему urllib2 не всегда ждет ответа (редко случается, что он не ждет)?

что я могу сделать с "[errno 10054] Существующее соединение было принудительно закрыто удаленным хостом" Ошибка? Кстати, исключение не перехватывается getPAGE () try: кроме блока, оно перехватывается первым блоком isValid () try: exception:, что также странно, потому что getPAGE () предполагает перехват всех исключений, которые оно выдает.

try:
    address = urlPath+str(ID)
    page = getPAGE(address)
    if page == None:
        saveToCsv(ID, badRequest = True)
        return False
except Exception, e:
    print "An error occured in the first Exception block of parseHTML : " + str(e) +' address: ' + address

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...