Красивый суп поднимает UnicodeEncodeError "Порядковый номер не в диапазоне (128)" - PullRequest
5 голосов
/ 25 декабря 2011

Я пытаюсь разобрать произвольные документы, загружаемые из дикой сети, и да, я не контролирую их содержание.

С тех пор Beautiful Soup не захлебнется, если вы дадите егоплохая разметка ... Интересно, почему это дает мне такие взлеты, когда иногда часть документа искажена, и есть ли способ заставить его вернуться к следующемучитаемая часть документа, независимо от этой ошибки.

Строка, в которой произошла ошибка, является третьей:

from BeautifulSoup  import BeautifulSoup as doc_parser
reader = open(options.input_file, "rb")
doc = doc_parser(reader)

Полный вывод CLI:

Traceback (most recent call last):
  File "./grablinks", line 101, in <module>
    sys.exit(main())
  File "./grablinks", line 88, in main
    links = grab_links(options)
  File "./grablinks", line 36, in grab_links
    doc = doc_parser(reader)
  File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1519, in __init__
    BeautifulStoneSoup.__init__(self, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1144, in __init__
    self._feed(isHTML=isHTML)
  File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1186, in _feed
    SGMLParser.feed(self, markup)
  File "/usr/lib/python2.7/sgmllib.py", line 104, in feed
    self.goahead(0)
  File "/usr/lib/python2.7/sgmllib.py", line 143, in goahead
        k = self.parse_endtag(i)
  File "/usr/lib/python2.7/sgmllib.py", line 320, in parse_endtag
    self.finish_endtag(tag)
  File "/usr/lib/python2.7/sgmllib.py", line 358, in finish_endtag
    method = getattr(self, 'end_' + tag)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-16: ordinal not in range(128)

Ответы [ 2 ]

2 голосов
/ 25 декабря 2011

Да, он захлебнется, если у вас есть элементы с не-ASCII-именами (<café>).И это даже не «плохая разметка», для XML ...

Это ошибка в sgmllib, которую использует BeautifulSoup: он пытается найти пользовательские методы с теми же именами, что и теги, но в методе Python 2имена являются байтовыми строками, поэтому даже поиск для метода с не-ASCII-символом, который никогда не будет присутствовать, завершится неудачей.

Вы можете взломать исправление в sgmllib, изменив строки 259 и371 от except AttributeError: до except AttributeError, UnicodeError:, но это не очень хорошее решение.Нетривиально переопределить и остальную часть метода.

Что вы пытаетесь проанализировать?BeautifulStoneSoup всегда представлял сомнительную полезность - у XML нет такого количества ужасных взломов парсера, как у HTML, поэтому в целом сломанный XML не является XML.Следовательно, вы, как правило, должны использовать обычный старый XML-парсер (например, использовать стандартный DOM или etree).Для анализа общего HTML, html5lib ваш лучший вариант в наши дни.

0 голосов
/ 25 декабря 2011

Это происходит, если во входных данных в версиях Python до Python 3.0 есть символы, отличные от ascii, до Python 3.0

Если вы пытаетесь использовать str(...) в строке, содержащей символы с значением char> 128 (Unicode), это исключение возникает.

Здесь ошибка, возможно, происходит, потому что getattr пытается использовать str в строке Unicode - он "думает", что может безопасно сделать это, потому что в версиях Python до3.0 идентификаторы не должны содержать Unicode.

Проверьте ваш HTML на наличие символов Unicode.Попробуйте заменить / кодировать их, и если это все еще не работает, сообщите нам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...