Я написал сканер, который использует 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
странное поведение -
- бывают случаи, когда urllib2 выполняет запрос GET и без
в ожидании ответа отправляет следующий запрос GET (игнорируя последний запрос)
- иногда я получаю " [errno 10054] Существующее соединение было принудительно закрыто удаленным хостом" после того, как код просто зависнет примерно на 20 минут или около того, ожидая ответа от сервера, пока он застрял я копирую URL-адрес и пытаюсь получить его вручную, и я получаю ответ менее чем за 1 секунду (?).
- Функция 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
Спасибо!