Обработка IncompleteRead,URLError

это часть сценария веб-майнинга.

def printer(q,missing):
    while 1:
        tmpurl=q.get()
        try:
            image=urllib2.urlopen(tmpurl).read()
        except httplib.HTTPException:
            missing.put(tmpurl)
            continue
        wf=open(tmpurl[-35:]+".jpg","wb")
        wf.write(image)
        wf.close()

q — это Queue(), состоящий из URL-адресов, а «отсутствует» — это пустая очередь для сбора URL-адресов, вызывающих ошибки.

он работает параллельно на 10 потоках.

и каждый раз, когда я запускаю это, я получаю это.

  File "C:\Python27\lib\socket.py", line 351, in read
    data = self._sock.recv(rbufsize)
  File "C:\Python27\lib\httplib.py", line 541, in read
    return self._read_chunked(amt)
  File "C:\Python27\lib\httplib.py", line 592, in _read_chunked
    value.append(self._safe_read(amt))
  File "C:\Python27\lib\httplib.py", line 649, in _safe_read
    raise IncompleteRead(''.join(s), amt)
IncompleteRead: IncompleteRead(5274 bytes read, 2918 more expected)

но я использую except... Я пробовал что-то еще, например

httplib.IncompleteRead
urllib2.URLError

даже,

image=urllib2.urlopen(tmpurl,timeout=999999).read()

но ничего из этого не работает..

как я могу поймать IncompleteRead и URLError?


person from __future__    schedule 13.08.2012    source источник
comment
С опозданием, но сначала зашел в гугл. Итак, stackoverflow.com/a/14206036/1444854 должен решить ваши проблемы. Кстати, обычно, если вы хотите поймать несколько исключений, поместите их в кортеж: кроме (httplib.IncompleteRead, urllib2.URLError)   -  person Vincent Ketelaars    schedule 12.02.2014


Ответы (1)


Я думаю, что правильный ответ на этот вопрос зависит от того, что вы считаете «URL-адресом, вызывающим ошибку».

Методы перехвата множественных исключений

Если вы считаете, что любой URL-адрес, который вызывает исключение, должен быть добавлен в очередь missing, вы можете сделать:

try:
    image=urllib2.urlopen(tmpurl).read()
except (httplib.HTTPException, httplib.IncompleteRead, urllib2.URLError):
    missing.put(tmpurl)
    continue

Это перехватит любое из этих трех исключений и добавит этот URL-адрес в очередь missing. Более просто вы могли бы сделать:

try:
    image=urllib2.urlopen(tmpurl).read()
except:
    missing.put(tmpurl)
    continue

Чтобы поймать любое исключение, но это не считается Pythonic и может скрыть другие возможные ошибки в вашем коде.

Если под «URL-адресом, вызывающим ошибку» вы подразумеваете любой URL-адрес, который вызывает ошибку httplib.HTTPException, но вы все равно хотите продолжить обработку, если будут получены другие ошибки, вы можете сделать:

try:
    image=urllib2.urlopen(tmpurl).read()
except httplib.HTTPException:
    missing.put(tmpurl)
    continue
except (httplib.IncompleteRead, urllib2.URLError):
    continue

Это добавит URL-адрес в очередь missing только в том случае, если он вызовет httplib.HTTPException, но в противном случае перехватит httplib.IncompleteRead и urllib.URLError и предотвратит сбой вашего скрипта.

Итерация по очереди

Кстати, циклы while 1 меня всегда немного беспокоят. Вы должны иметь возможность просматривать содержимое очереди, используя следующий шаблон, хотя вы можете продолжать делать это по-своему:

for tmpurl in iter(q, "STOP"):
    # rest of your code goes here
    pass

Безопасная работа с файлами

Кроме того, если нет абсолютной необходимости делать иначе, вам следует использовать менеджеры контекста открывать и изменять файлы. Таким образом, ваши три строки операций с файлами станут такими:

with open(tmpurl[-35:]+".jpg","wb") as wf:
    wf.write()

Контекстный менеджер позаботится о закрытии файла и сделает это, даже если во время записи в файл возникнет исключение.

person Michael Leonard    schedule 21.10.2015