Я создаю веб-программу, которая просматривает каждый URL в списке URL, открывает страницу с этим URL и извлекает некоторую информацию из супа. В большинстве случаев он работает нормально, но иногда программа прекращает продвигаться по списку, но не завершает программу, отображает предупреждения / исключения или иным образом показывает признаки ошибки. Мой код, сокращенный до соответствующих частей, выглядит следующим образом:
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup as bs
# some code...
for url in url_list:
req = Request(url, headers={"User-Agent": "Mozilla/5.0"})
page = urlopen(req)
soup = bs(page, features="html.parser")
# do some stuff with the soup...
Когда программа останавливается, если я завершаю ее вручную (с помощью PyCharm), я получаю следующий результат:
File "/Path/to/my/file.py", line 48, in <module>
soup = bs(page, features="html.parser")
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/bs4/__init__.py", line 266, in __init__
markup = markup.read()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 454, in read
return self._readall_chunked()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 564, in _readall_chunked
value.append(self._safe_read(chunk_left))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 610, in _safe_read
chunk = self.fp.read(min(amt, MAXAMOUNT))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 589, in readinto
return self._sock.recv_into(b)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1052, in recv_into
return self.read(nbytes, buffer)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 911, in read
return self._sslobj.read(len, buffer)
KeyboardInterrupt
Вот что я попробовал и усвоил:
Добавлена проверка, чтобы убедиться, что статус страницы всегда равен 200 при приготовлении супа. Условие сбоя никогда не возникает.
Добавлен оператор печати после создания супа. Этот оператор печати не срабатывает после остановки.
URL-адреса всегда действительны. Это подтверждается тем фактом, что программа не останавливается на одном и том же URL-адресе каждый раз, и дважды подтверждается аналогичной программой, которую я использую, с почти идентичным кодом, который демонстрирует одинаковое поведение на другом наборе URL-адресов.
Я попытался выполнить этот шаг за шагом с помощью отладчика. Проблема не возникала в течение примерно 30 итераций, которые я проверял вручную, что может быть просто совпадением.
Страница возвращает правильные заголовки, когда bs4 останавливается. Кажется, проблема связана с созданием супа.
Что может вызвать такое поведение?