Разбор HTML в python-lxml или BeautifulSoup? Какой из них лучше для каких целей?
из того, что я могу разобрать, две основные библиотеки синтаксического анализа HTML в Python-это lxml и BeautifulSoup. Я выбрал BeautifulSoup для проекта, над которым я работаю, но я выбрал его без особых причин, кроме как найти синтаксис немного легче учиться и понимать. Но я вижу, что многие люди, похоже, предпочитают lxml, и я слышал, что lxml быстрее.
поэтому мне интересно, каковы преимущества одного над другим? Когда я хочу использовать lxml и когда я буду лучше с помощью BeautifulSoup? Есть ли другие библиотеки, которые стоит рассмотреть?
7 ответов:
для начала, BeautifulSoup больше не поддерживается, и автор даже рекомендует альтернатив например, lxml.цитирую по ссылке:
версия 3.1.0 красивый суп делает значительно хуже на реальном мире HTML-код чем версия 3.0.8 делает. Самый общие проблемы обработки теги неправильно, " неправильный старт тег "ошибки и ошибки" плохой конец тега". На этой странице объясняется, что произошло, как проблема будет решена, и что вы можете сделать прямо сейчас.
эта статья была первоначально написана в Март 2009 года. С тех пор, серия 3.2 был выпущен, заменив 3.1 серия, и развитие 4.икс серия уже началась. Эта страница останется до исторического цели.
tl; dr
вместо этого используйте 3.2.0.
Pyquery
предоставляет интерфейс селектора jQuery для Python (используя lxml под капотом).http://pypi.python.org/pypi/pyquery
это действительно потрясающе, я больше ничего не использую.
в целом,
lxml
позиционируется как молниеносный качественный html и xml парсер, который, кстати, также включает в себяsoupparser
модуль, чтобы вернуться к функциональности BeautifulSoup.BeautifulSoup
это проект для одного человека, предназначенный для экономии времени, чтобы быстро извлечь данные из плохо сформированного html или xml.документация lxml говорит, что оба парсера имеют преимущества и недостатки. По этой причине,
lxml
предоставляетsoupparser
Так что вы можете переключаться туда-сюда. Цитируя,BeautifulSoup использует другой подход к разбору. Это не настоящий HTML парсер, но использует регулярные выражения, чтобы погрузиться в суп тегов. Это поэтому в одних случаях он более снисходителен, а в других-менее добр. Это не редкость, что lxml / libxml2 лучше разбирает и исправляет сломанный HTML, но BeautifulSoup имеет превосходную поддержку для обнаружения кодирования. It очень многое зависит от того, на каком входе работает парсер лучше.
в конце концов они говорят:
недостатком использования этого анализатора является то, что он гораздо медленнее чем HTML парсер lxml. так что если производительность имеет значение, вы можете захотеть рассмотреть возможность использования soupparser только в качестве запасного варианта для некоторых случаев.
если я правильно их понимаю, это означает, что парсер супа более надежен - - - он может иметь дело с" супом " из уродливых теги с помощью регулярных выражений - - - тогда как
lxml
является более простым и просто анализирует вещи и строит дерево, как и следовало ожидать. Я предполагаю, что это также относится кBeautifulSoup
сам, а не только кsoupparser
наlxml
.они также показывают, как использовать
BeautifulSoup
' s кодирование обнаружения, в то же время разбор быстро сlxml
:>>> from BeautifulSoup import UnicodeDammit >>> def decode_html(html_string): ... converted = UnicodeDammit(html_string, isHTML=True) ... if not converted.unicode: ... raise UnicodeDecodeError( ... "Failed to detect encoding, tried [%s]", ... ', '.join(converted.triedEncodings)) ... # print converted.originalEncoding ... return converted.unicode >>> root = lxml.html.fromstring(decode_html(tag_soup))
(тот же источник: http://lxml.de/elementsoup.html).
по словам
BeautifulSoup
' s создатель,вот именно! Получайте удовольствие! Я написал прекрасный суп, чтобы сэкономить всем время. Как только вы привыкнете к нему, вы должны уметь спорить с данными из плохо продуманные сайты всего за несколько минут. Отправьте мне письмо, если вы есть какие-либо комментарии, сталкиваются с проблемами, или хотите, чтобы я знал о вашем проект, который использует красивый суп.
--Leonard
цитата из красивый суп документация.
я надеюсь, что это теперь четкий. Суп-это блестящий проект одного человека, предназначенный для экономии времени на извлечение данных из плохо разработанных веб-сайтов. Цель состоит в том, чтобы сэкономить ваше время прямо сейчас, чтобы выполнить работу, не обязательно, чтобы сэкономить ваше время в долгосрочной перспективе, и определенно не оптимизировать производительность вашего программного обеспечения.
С сайт lxml,
lxml был загружен из индекса пакета Python более двух миллион раз и также доступный сразу в много пакет дистрибутивы, например для Linux или MacOS-X.
и почему lxml?,
библиотеки C libxml2 и libxslt имеют огромные преимущества:... Соответствующий стандартам... Полнофункциональный... быстрый. быстро! Быстро! ... библиотека lxml это новая привязка Python для libxml2 и libxslt...
Не используйте BeautifulSoup, используйте lxml.суппарсер тогда вы сидите на вершине власти lxml и можете использовать хорошие биты BeautifulSoup, которые должны иметь дело с действительно сломанным и дерьмовым HTML.
я использовал lxml с большим успехом для разбора HTML. Похоже, он также хорошо справляется с "суповым" HTML. Я очень рекомендую его.
вот быстрый тест я лежал вокруг, чтобы попробовать обработку некоторых уродливых HTML:
import unittest from StringIO import StringIO from lxml import etree class TestLxmlStuff(unittest.TestCase): bad_html = """ <html> <head><title>Test!</title></head> <body> <h1>Here's a heading <p>Here's some text <p>And some more text <b>Bold!</b></i> <table> <tr>row <tr><td>test1 <td>test2 </tr> <tr> <td colspan=2>spanning two </table> </body> </html>""" def test_soup(self): """Test lxml's parsing of really bad HTML""" parser = etree.HTMLParser() tree = etree.parse(StringIO(self.bad_html), parser) self.assertEqual(len(tree.xpath('//tr')), 3) self.assertEqual(len(tree.xpath('//td')), 3) self.assertEqual(len(tree.xpath('//i')), 0) #print(etree.tostring(tree.getroot(), pretty_print=False, method="html")) if __name__ == '__main__': unittest.main()
конечно, я бы использовал EHP. Это быстрее, чем lxml, гораздо более элегантный и простой в использовании.
проверить. https://github.com/iogf/ehp
<body ><em > foo <font color="red" ></font></em></body> from ehp import * data = '''<html> <body> <em> Hello world. </em> </body> </html>''' html = Html() dom = html.feed(data) for ind in dom.find('em'): print ind.text()
выход:
Hello world.
несколько устаревшее сравнение скорости можно найти здесь, что явно рекомендует lxml, поскольку различия в скорости кажутся радикальными.
Comments