私ができることから、Pythonの2つの主要なHTML解析ライブラリはlxmlとBeautifulSoupです。作業中のプロジェクトにBeautifulSoupを選択しましたが、特に選択しませんでした。しかし、多くの人がlxmlを好むようであり、lxmlのほうが速いと聞きました。
だから、私は一方の利点が他のものよりも優れているのだろうか? lxmlをいつ使用したいのか、BeautifulSoupを使用したほうがよいのはいつですか?他に検討する価値のあるライブラリはありますか?
まず第一に、BeautifulSoupは積極的に保守されなくなり、 著者は代替案も推奨しています (lxmlなど)。
リンクされたページからの引用:
Beautiful Soupのバージョン3.1.0は、バージョン3.0.8よりも実際のHTMLで著しく劣ります。最も一般的な問題は、タグの不適切な処理、「不正な開始タグ」エラー、および「不正な終了タグ」エラーです。このページでは、何が起こったのか、問題にどのように対処するのか、今すぐにできることを説明しています。
このページはもともと2009年3月に作成されました。それ以降、3.1シリーズに代わって3.2シリーズがリリースされ、4.xシリーズの開発が進行中です。このページは過去の目的のために残ります。
tl; dr
代わりに3.2.0を使用してください。
Pyquery
は、Python(内部でlxmlを使用)へのjQueryセレクターインターフェイスを提供します。
http://pypi.python.org/pypi/pyquery
それは本当に素晴らしいです、私はもう何も使いません。
要約すると、lxml
は、超高速の製品品質のhtmlおよびxmlパーサーとして位置付けられており、ちなみに、BeautifulSoupの機能にフォールバックするsoupparser
モジュールも含まれています。 BeautifulSoup
は1人のプロジェクトであり、時間の節約のために、整形式でないhtmlまたはxmlからデータをすばやく抽出するように設計されています。
lxml documentation は、両方のパーサーに長所と短所があることを示しています。このため、lxml
はsoupparser
を提供するので、前後に切り替えることができます。引用、
BeautifulSoupは異なる解析アプローチを使用します。これは実際のHTMLパーサーではありませんが、正規表現を使用してタグスープを調べます。したがって、場合によってはより寛容になり、他の場合にはあまり良くありません。 lxml/libxml2が壊れたHTMLをより適切に解析および修正することは珍しくありませんが、BeautifulSoupにはエンコード検出の優れたサポートがあります。 それは、どのパーサーがよりよく機能するかによって大きく異なります。
最後に、彼らは言っています、
このパーサーを使用する欠点は、lxmlのHTMLパーサーよりもはるかに遅いことです。 パフォーマンスが重要な場合、特定の場合のフォールバックとしてのみ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を書きました。慣れてしまえば、設計が不十分なWebサイトからわずか数分でデータを収集できます。コメントがある場合、問題が発生した場合、またはBeautiful Soupを使用しているプロジェクトについて知りたい場合は、メールを送信してください。
--Leonard
Beautiful Soup documentation から引用。
これが明らかになったことを願っています。このスープは、設計が不十分なWebサイトからデータを抽出する時間を節約するために設計された素晴らしい1人のプロジェクトです。目標は、現時点で時間を節約し、仕事を終わらせることであり、必ずしも長期的に時間を節約することではなく、間違いなくソフトウェアのパフォーマンスを最適化しないことです。
また、 lxml website から、
lxmlはPython Package Indexから200万回以上ダウンロードされており、LinuxやMacOS-Xなどの多くのパッケージ配布でも直接利用できます。
そして、 なぜlxml? から
Cライブラリlibxml2およびlibxsltには大きな利点があります。..標準準拠...全機能搭載...高速。速い!早く! ... lxmlは、新しいPython libxml2とlibxsltのバインディングです...
lxml.soup parser を使用するBeautifulSoupを使用しないでください。lxmlのパワーを利用して、本当に壊れたがらくたHTMLを処理するBeautifulSoupの優れた部分を使用できます。
HTMLの構文解析に大成功を収めたlxmlを使用しました。また、「すっきりした」HTMLをうまく処理しているようです。強くお勧めします。
Hereい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 __== '__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.
やや時代遅れの速度比較が見つかります here 、これは明らかに速度の違いが劇的に見えるのでlxmlを推奨します。