Из того, что я могу разобрать, две основных библиотеки парсинга HTML в Python являются lxml и BeautifulSoup. Я выбрал BeautifulSoup для проекта, я продолжаю работать, но я выбрал его ни по какой конкретной причине кроме нахождения синтаксиса, немного легче учиться и понять. Но я вижу, что много людей, кажется, одобрить lxml, и я услышал, что lxml быстрее.
Таким образом, я задаюсь вопросом, каковы преимущества одного по другому? Когда я хотел бы использовать lxml и когда я буду более обеспеченным использованием BeautifulSoup? Действительно ли там какие-либо другие библиотеки достойны рассмотрения?
Для начала, BeautifulSoup больше не поддерживается активно, и автор даже рекомендует альтернативы , такие как lxml.
Цитата со связанной страницы:
Версия 3.1 .0 из Beautiful Soup делает значительно хуже на реальном HTML чем версия 3.0.8. Большинство общие проблемы решаются теги неправильно, "неправильное начало теги "ошибки" и ошибки "плохой конечный тег". На этой странице объясняется, что произошло, как проблема будет решена, и что вы можете сделать прямо сейчас.
Эта страница изначально была написана на Март 2009 года. С тех пор серия 3.2 был выпущен, заменив 3.1 серии, и развитие 4.x серия началась. Эта страница останется до исторического целей.
tl; dr
Используйте вместо него 3.2.0.
Pyquery
предоставляет интерфейс селектора jQuery для Python (используя lxml под капотом).
http://pypi.python.org/pypi/pyquery
Это действительно круто, больше ничего не использую.
Не используйте BeautifulSoup, используйте lxml.soupparser , тогда вы находитесь на вершине мощи 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()