Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Для начала BeautifulSoup больше не поддерживается, и автор даже рекомендует альтернативы, такие как lxml.

Цитата из связанной страницы:

Версия 3.1.0 из Beautiful Soup делает значительно хуже на реальном HTML чем версия 3.0.8. Большинство Общие проблемы неверные теги, "неправильный запуск" тег "и" плохой конец тега ". На этой странице объясняется, что произошло, как проблема будет решена, и что вы можете сделать прямо сейчас.

Эта страница была изначально написана Марте 2009 года. С тех пор серия 3.2 был выпущен, заменив 3.1 серии и разработки 4.x серия началась. Эта страница останется в целей.

TL;DR

Вместо этого используйте 3.2.0.

Ответ 2

Pyquery предоставляет интерфейс селектора jQuery для Python (используя lxml под капотом).

http://pypi.python.org/pypi/pyquery

Это действительно потрясающе, я больше ничего не использую.

Ответ 3

Таким образом, lxml позиционируется как быстродействующий синтаксический анализатор html и xml производительности, который, кстати, также включает модуль soupparser, чтобы вернуться к функциональности BeautifulSoup. BeautifulSoup - это проект из одного человека, призванный сэкономить время, чтобы быстро извлечь данные из плохо сформированного html или xml.

документация lxml говорит, что оба парсера имеют преимущества и недостатки. По этой причине lxml предоставляет soupparser, поэтому вы можете переключаться туда и обратно. Цитирование,

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

В конце они говорят:

Недостатком использования этого анализатора является то, что он намного медленнее, чем HTML-анализатор lxml. Поэтому, если производительность важна, вы можете захотеть рассмотреть возможность использования soupparser только в качестве резерва для определенных случаев.

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

Они также показывают, как извлечь выгоду из обнаружения BeautifulSoup кодирования, но все еще быстро разбираются с 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

Что это! Повеселись! Я написал Beautiful Soup, чтобы спасти всех. Как только вы привыкнете к этому, вы должны иметь возможность пресекать данные из плохо спроектированные веб-сайты всего за несколько минут. Пришлите мне письмо, если вы иметь какие-либо комментарии, сталкиваться с проблемами или хотеть, чтобы я знал о ваших проект, который использует Beautiful Soup.

 --Leonard

Цитата из Документация Beautiful Soup.

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

Кроме того, из lxml,

lxml был загружен из индекса пакета Python более двух миллион раз и также доступен непосредственно во многих пакетах распределения, например. для Linux или MacOS-X.

И, из Почему lxml?,

Библиотеки C libxml2 и libxslt имеют огромные преимущества:... Стандартно-совместимый... Полнофункциональный... быстрый. быстро! БЫСТРО!... lxml это новая привязка Python для libxml2 и libxslt...

Ответ 4

Не используйте BeautifulSoup, используйте lxml.soupparser, тогда вы сидите на вершине мощности lxml и можете использовать хорошие биты BeautifulSoup, которые должны иметь дело с действительно сломанными и дрянной HTML.

Ответ 5

Я использовал 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 a heading
                <p>Here 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 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()

Ответ 6

Конечно, я бы использовал 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. 

Ответ 7

Несколько устаревшее сравнение скорости можно найти здесь, в котором явно рекомендуется lxml, так как различия в скорости кажутся резкими.