Python3 RecursionError при декодировании Unicode (для BeautifulSoup/RoboBrowser)
Я работаю над компонентом очистки веб-страниц, используя BeautifulSoup и RoboBrowser, и столкнулся с любопытной проблемой в одном конкретном случае. Страница, о которой идет речь, содержит все те же хром и структуру, что и все остальные случаи, которые работают нормально, но ее основное поле данных (аккуратно помеченное div) представляет собой одну огромную строку (около 3000 символов японского текста) без разрывов строк. Это приправлено МНОЖЕСТВОМ тегов BR (они используют их довольно ужасным способом для форматирования таблиц...) и несколькими тегами SPAN для форматирования, но весь основной текст является одной строкой.
Это не должно быть проблемой, но мой скребок умирает с RecursionError: maximum recursion depth exceeded in comparison
выплюнув несколько сотен (возможно, тысяч) одинаковых пар этих линий:
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1126, in decode
indent_contents, eventual_encoding, formatter)
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1195, in decode_contents
formatter))
Первоначально я обвинял BeautifulSoup и думал, что огромное количество тегов BR сбрасывает его, но, похоже, проблема на самом деле в Unicode. Вот код, который его выбрасывает:
File "/Users/myself/Projects/Scraper/scrape.py", line 207, in articles
self._childtext = re.sub('<[^<]+?>', '', str(self._one_child).replace('<br/>', '\n'))
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1039, in __unicode__
return self.decode()
Я подумал, что это может быть длина строки, поэтому я анализирую блок DIV "ребенок за ребенком" вместо того, чтобы делать все сразу, но это никак не помогло. Независимо от того, насколько маленькие куски, str(bsObject)
кажется, что функция вгоняет парсер юникода в безумное безумие.
Слегка утолщать сюжет; Я скопировал весь текст исходного кода страницы в новую изолированную программную среду Python в виде длинной строки, чтобы можно было протестировать другой код на нем без постоянного входа на сайт. Python быстро отказался от компиляции кода (жалуясь, что он содержал символы, отличные от UTF8), даже после того, как я пропустил текст через vi и заставил его сохранить как UTF8. Однако вставка новых строк в текст, чтобы разделить его на более мелкие фрагменты, не позволяла появиться этой ошибке, несмотря на то, что она не изменяла и не удаляла ни одного символа самого текста, и в этот момент скрипт отлично компилировал и очищал страницу.
Я понятия не имею, как поступить отсюда. Я не контролирую сайт, с которого я соскребаю; Я думал о том, чтобы принудительно переводить строки в объект ответа в RoboBrowser до того, как BeautifulSoup прикоснется к нему, что является ужасным взломом, но, похоже, это может исправить ситуацию, но я не уверен, как это сделать. Кто-нибудь может предложить другой подход?
(К сожалению, я не могу ссылаться на страницу, с которой я собираю данные, так как это поставщик исследовательских данных, для которого требуется логин и нет постоянных URL-адресов для отдельных фрагментов данных.)
Изменить: Добавление полной трассировки стека ниже...
Traceback (most recent call last):
File "scrape.py", line 112, in <module>
dataScrape()
File "scrape.py", line 39, in dataScrape
for article in scraper.articles():
File "/Users/myself/Projects/Scraper/scrape.py", line 207, in articles
self._childtext = re.sub('<[^<]+?>', '', str(self._one_child).replace('<br/>', '\n'))
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1039, in __unicode__
return self.decode()
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1126, in decode
indent_contents, eventual_encoding, formatter)
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1195, in decode_contents
formatter))
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1126, in decode
indent_contents, eventual_encoding, formatter)
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1195, in decode_contents
formatter))
#
# These lines repeat identically several hundred times, then...
#
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 1192, in decode_contents
text = c.output_ready(formatter)
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 716, in output_ready
output = self.format_string(self, formatter)
File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 158, in format_string
if not isinstance(formatter, collections.Callable):
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/abc.py", line 182, in __instancecheck__
if subclass in cls._abc_cache:
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/_weakrefset.py", line 75, in __contains__
return wr in self.data
RecursionError: maximum recursion depth exceeded in comparison