Красивый суп - Устранение неполадок

Обработка ошибок

В BeautifulSoup необходимо обрабатывать два основных типа ошибок. Эти две ошибки связаны не с вашим сценарием, а со структурой фрагмента, поскольку BeautifulSoup API выдает ошибку.

Две основные ошибки заключаются в следующем:

AttributeError

Это происходит, когда точечная нотация не находит родственный тег для текущего HTML-тега. Например, вы могли столкнуться с этой ошибкой из-за отсутствия «тега привязки», cost-key будет выдавать ошибку при прохождении и требует тега привязки.

KeyError

Эта ошибка возникает, если отсутствует обязательный атрибут тега HTML. Например, если у нас нет атрибута data-pid во фрагменте, ключ pid выдаст ошибку ключа.

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

except(AttributeError, KeyError) as er:
pass

диагностировать ()

Каждый раз, когда мы сталкиваемся с трудностями в понимании того, что BeautifulSoup делает с нашим документом или HTML, просто передайте это в функцию Diagnose (). Передав файл документа в функцию Diagnose (), мы можем показать, как список различных парсеров обрабатывает документ.

Ниже приведен один пример, демонстрирующий использование функции Diagnose () -

from bs4.diagnose import diagnose

with open("20 Books.html",encoding="utf8") as fp:
   data = fp.read()
   
diagnose(data)

Выход

Ошибка разбора

Есть два основных типа ошибок синтаксического анализа. Вы можете получить исключение вроде HTMLParseError, когда вы загрузите свой документ в BeautifulSoup. Вы также можете получить неожиданный результат, когда дерево синтаксического анализа BeautifulSoup будет сильно отличаться от ожидаемого результата от документа синтаксического анализа.

Ни одна из ошибок синтаксического анализа не вызвана BeautifulSoup. Это из-за внешнего парсера, который мы используем (html5lib, lxml), поскольку BeautifulSoup не содержит кода парсера. Один из способов устранить вышеуказанную ошибку синтаксического анализа - использовать другой анализатор.

from HTMLParser import HTMLParser

try:
   from HTMLParser import HTMLParseError
except ImportError, e:
   # From python 3.5, HTMLParseError is removed. Since it can never be
   # thrown in 3.5, we can just define our own class as a placeholder.
   class HTMLParseError(Exception):
      pass

Встроенный в Python синтаксический анализатор HTML вызывает две наиболее распространенные ошибки синтаксического анализа: HTMLParser.HTMLParserError: неправильный начальный тег и HTMLParser.HTMLParserError: плохой конечный тег, и для решения этой проблемы в основном используется другой синтаксический анализатор: lxml или html5lib.

Другой распространенный тип неожиданного поведения - вы не можете найти тег, который, как вы знаете, есть в документе. Однако при запуске find_all () возвращает [] или find () возвращает None.

Это может быть связано с тем, что встроенный в Python анализатор HTML иногда пропускает теги, которые он не понимает.

Ошибка парсера XML

По умолчанию пакет BeautifulSoup анализирует документы как HTML, однако он очень прост в использовании и очень элегантно обрабатывает плохо сформированный XML с помощью beautifulsoup4.

Чтобы проанализировать документ как XML, вам нужен синтаксический анализатор lxml, и вам просто нужно передать «xml» в качестве второго аргумента конструктору Beautifulsoup -

soup = BeautifulSoup(markup, "lxml-xml")

или

soup = BeautifulSoup(markup, "xml")

Одна распространенная ошибка синтаксического анализа XML -

AttributeError: 'NoneType' object has no attribute 'attrib'

Это может произойти в случае, если какой-то элемент отсутствует или не определен при использовании функции find () или findall ().

Другие ошибки парсинга

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

Экологическая проблема

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

Рекомендуется знать или проверять парсер по умолчанию в вашей текущей рабочей среде. Вы можете проверить текущий синтаксический анализатор по умолчанию, доступный для текущей рабочей среды, или явно передать необходимую библиотеку синтаксического анализатора в качестве вторых аргументов конструктору BeautifulSoup.

Без учета регистра

Поскольку теги и атрибуты HTML не чувствительны к регистру, все три анализатора HTML преобразуют имена тегов и атрибутов в нижний регистр. Однако, если вы хотите сохранить теги и атрибуты в смешанном или верхнем регистре, лучше анализировать документ как XML.

UnicodeEncodeError

Давайте посмотрим на сегмент кода ниже -

soup = BeautifulSoup(response, "html.parser")
   print (soup)

Выход

UnicodeEncodeError: 'charmap' codec can't encode character '\u011f'

Вышеупомянутая проблема может быть связана с двумя основными ситуациями. Возможно, вы пытаетесь распечатать символ Юникода, который ваша консоль не умеет отображать. Во-вторых, вы пытаетесь записать в файл и передаете символ Unicode, который не поддерживается вашей кодировкой по умолчанию.

Один из способов решить вышеуказанную проблему - закодировать текст / символ ответа перед приготовлением супа, чтобы получить желаемый результат, следующим образом:

responseTxt = response.text.encode('UTF-8')

KeyError: [attr]

Это вызвано доступом к тегу ['attr'], когда рассматриваемый тег не определяет атрибут attr. Наиболее частые ошибки: «KeyError: 'href'» и «KeyError: 'class'». Используйте tag.get ('attr'), если вы не уверены, что attr определен.

for item in soup.fetch('a'):
   try:
      if (item['href'].startswith('/') or "tutorialspoint" in item['href']):
      (...)
   except KeyError:
      pass # or some other fallback action

AttributeError

Вы можете столкнуться с AttributeError следующим образом -

AttributeError: 'list' object has no attribute 'find_all'

Вышеупомянутая ошибка в основном возникает из-за того, что вы ожидали, что find_all () вернет один тег или строку. Однако soup.find_all возвращает список элементов Python.

Все, что вам нужно сделать, это перебрать список и получить данные из этих элементов.