Разбор HTML в python-lxml или BeautifulSoup? Какой из них лучше для каких целей?



из того, что я могу разобрать, две основные библиотеки синтаксического анализа HTML в Python-это lxml и BeautifulSoup. Я выбрал BeautifulSoup для проекта, над которым я работаю, но я выбрал его без особых причин, кроме как найти синтаксис немного легче учиться и понимать. Но я вижу, что многие люди, похоже, предпочитают lxml, и я слышал, что lxml быстрее.



поэтому мне интересно, каковы преимущества одного над другим? Когда я хочу использовать lxml и когда я буду лучше с помощью BeautifulSoup? Есть ли другие библиотеки, которые стоит рассмотреть?

895   7  

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

    Ничего не найдено.