@dedal_0

Python — referenced before assignment в процессе парсинга сайта, как искать ошибку?

Доброго времени суток всем. Пишу парсер некоторого сайта. На Django, с помощью библиотек requests и BeautifulSoup. Простой, но длительный. Собирает информацию, складирует инфу через модели в базу данных.
Суть вопроса - в процессе работы необходимо:
- собрать список основных объектов с первой html-страницы, пройтись по n-ному числу страниц этой первой страницы, дополнить список, собрать инфу, сохранить в базу данных
- затем зайти на html-страницу каждого из объектов, собрать инфу, сохранить, если выполняются некоторые условия - зайти на следующую html-страницу, "поработать" там
Обращение к url'ам происходит с помощью requests. Парсинг контента выполняется через BeautifulSoup.
Иногда url не выдаёт информацию, срабатывают исключения requests.exceptions.ReadTimeout или ConnectionTimeout.
Пришлось при каждом запросе к url'у сооружать примерно такую конструкцию:

`
import requests
from requests.exceptions import Timeout
from bs4 import BeautifulSoup as bs
MIMIC_HEADERS = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
...
read_fail = True
while read_fail:
    try:
        sleep(1)
        response = session.get(start_url, timeout=10, headers=MIMIC_HEADERS)
        html_bs = bs(response.content, 'html.parser')
    except Timeout:
        read_fail = True
    except UnboundLocalError:
        read_fail = True
    finally:
        read_fail = False
        ...(прочие действия над html_bs)
`

Такая конструкция появилась не сразу. Исключение UnboundLocalError возникало при попытке работать с переменными response или html_bs.
Всё это выполняется периодически, с помощью django-carrot (если кто не знаком - более легкий аналог celery).
От самой celery пришлось отказаться, поскольку в текущей версии (4.2) Обнаружен серьёзный баг - переполняет очередь сообщений при работе с задачами по расписанию.
Иногда задача может длиться до 8-ми часов. Собирать более 2000 объектов. При хорошем сценарии развития событий.

Последним сюрпризом стало преждевременное завершение задачи с сообщением `html_bs referenced before assignment`. До этого задача грохалась с исключением UnboundLocalError.
Иногда в журнале carrot'а появляются строки типа:
Unable to find MessageLog matching the uuid . Ignoring this task
Используется брокер - rabbitmq.
Вопрос 1 - правильно ли я подошёл к решению задачи?
Вопрос 2 - если ошибка не в этой чудо-конструкции, а с кажем при запросе к url'у - как выяснить, в чём ошибка, если логи задачи, carrot'а и даже rabbitmq на этот счёт молчат

Операционная система - Debian 9
Версия python - 3.6
Фреймворк - Django 2.1
Список установленных пакетов в виртуальном окружении:

amqp==2.3.2
asn1crypto==0.24.0
Babel==2.6.0
backcall==0.1.0
beautifulsoup4==4.6.3
billiard==3.5.0.5
celery==4.2.0
certifi==2018.11.29
cffi==1.11.5
chardet==3.0.4
cryptography==2.4.2
decorator==4.3.0
Django==2.1.4
django-carrot==1.3.3
django-compat==1.0.15
django-grappelli==2.12.1
django-timezone-field==3.0
djangorestframework==3.9.0
fake-useragent==0.1.11
gevent==1.3.7
gevent-eventemitter==2.0
greenlet==0.4.15
gunicorn==19.9.0
idna==2.8
ipython==7.2.0
ipython-genutils==0.2.0
jedi==0.13.1
json2html==1.2.1
kombu==4.2.2
parso==0.3.1
pexpect==4.6.0
pickleshare==0.7.5
pika==0.12.0
Pillow==5.3.0
prompt-toolkit==2.0.7
protobuf==3.6.1
psutil==5.4.8
psycopg2-binary==2.7.6.1
ptyprocess==0.6.0
pycparser==2.19
Pygments==2.3.0
python-crontab==2.3.5
python-dateutil==2.7.5
pytz==2018.7
requests==2.20.1
selenium==3.141.0
six==1.11.0
tornado==5.1.1
traitlets==4.3.2
urllib3==1.24.1
vdf==2.4
vine==1.1.4
wcwidth==0.1.7
  • Вопрос задан
  • 88 просмотров
Пригласить эксперта
Ответы на вопрос 2
@tumbler
бекенд-разработчик на python
У Вас в finally-блоке при любой ошибке read_fail выставляется в False, из-за чего по-видимому код, который за многоточием в "прочие действия над html_bs" считает, что ошибки не произошло и переменные response и html_bs проинициализированы.
Советую почитать про обработку ошибок.
Ответ написан
@dedal_0 Автор вопроса
Точно. Невнимательно прочел документацию. Код в finally будет выполнен при любых условиях, а не при успешном выполнении try, как показалось.
Всем спасибо.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы