Как сделать универсальный фид-парсер только парсом фидов?
Я пытаюсь получить контент из внешних каналов на моем веб-сайте Django с помощью универсального анализатора каналов. Я хочу иметь некоторую обработку ошибок пользователя, например, если пользователь предоставляет URL, который не является каналом. Когда я попробовал, как feedparser реагирует на ошибочный ввод, я был удивлен, увидев, что feedparser вообще не выдает никаких исключений. Например, на HTML-контенте он пытается проанализировать некоторую информацию из HTML-кода, а на несуществующих доменах он возвращает в основном пустой словарь:
{'bozo': 1,
'bozo_exception': URLError(gaierror(-2, 'Name or service not known'),),
'encoding': 'utf-8',
'entries': [],
'feed': {},
'version': None}
Другие ошибочные входные данные проявляются в значениях status_code
или namespaces
возвращаемого словаря.
Итак, каков наилучший подход, чтобы иметь нормальную проверку ошибок, не прибегая к бесконечному каскаду if .. elif .. elif ...
?
1 ответ:
Согласно документации
feedparser
, в разделе обнаружение Бозо :Универсальный анализатор каналов может анализировать каналы независимо от того, являются ли они хорошо сформированными XML или нет. Однако, поскольку некоторые приложения могут отклонять или предупреждать пользователей о неполной форме каналов, универсальный анализатор каналов устанавливает бит bozo, когда он обнаруживает, что канал не является хорошо сформированным.
(на мой взгляд, это не очень хорошая практика, чтобы поймать все исключения и вернуть их в другой форме, но это именно так это и работает, поскольку "приложения могут просто предупреждать о не очень хорошо сформированных каналах".)
Таким образом, после попытки проанализировать канал по любому URL, вы можете проверить наличие "Бозо-бита" и повторно вызвать соответствующее исключение:
f = feedparser.parse('http://example.com') if f.bozo: raise f.bozo_exception
Вы можете обрабатывать исключение в соответствии с типом и сообщением или путем утверждения других атрибутов объекта, возвращаемых
feedparser.parse
(например:f.feed
должен быть непустым,f.status
должен равняться 200,f.entries
должен быть непустым,f.version
должен быть допустимым форматом канала версия и т. д.), все, что кажется наиболее разумным для вашего приложения.