파이썬에서 HTML 구문 분석-lxml 또는 BeautifulSoup? 어떤 목적에 더 좋은 것은 무엇입니까?
내가 알 수 있듯이 Python의 두 가지 주요 HTML 구문 분석 라이브러리는 lxml과 BeautifulSoup입니다. 작업중인 프로젝트에 대해 BeautifulSoup을 선택했지만 구문을 배우고 이해하기 더 쉬운 것을 찾는 것 외에 특별한 이유없이 선택했습니다. 하지만 많은 사람들이 lxml을 선호하는 것 같고 lxml이 더 빠르다고 들었습니다.
그래서 나는 다른 것보다 하나의 장점이 무엇인지 궁금합니다. lxml을 언제 사용하고 싶고 언제 BeautifulSoup을 사용하는 것이 더 나을까요? 고려할만한 다른 라이브러리가 있습니까?
우선 BeautifulSoup은 더 이상 적극적으로 유지 관리되지 않으며 저자 는 lxml과 같은 대안을 권장 합니다.
링크 된 페이지에서 인용 :
Beautiful Soup 3.1.0 버전은 실제 HTML에서 3.0.8 버전보다 훨씬 더 나쁩니다. 가장 일반적인 문제는 잘못된 태그 처리, "잘못된 시작 태그"오류 및 "잘못된 끝 태그"오류입니다. 이 페이지에서는 발생한 상황, 문제 해결 방법 및 지금 당장 할 수있는 작업을 설명합니다.
이 페이지는 원래 2009 년 3 월에 작성되었습니다. 그 이후로 3.1 시리즈를 대체하는 3.2 시리즈가 출시되었으며 4.x 시리즈의 개발이 진행 중입니다. 이 페이지는 기록 목적으로 유지됩니다.
tl; dr
대신 3.2.0을 사용하십시오.
Pyquery
Python에 jQuery 선택기 인터페이스를 제공합니다 (내부에서 lxml 사용).
http://pypi.python.org/pypi/pyquery
정말 대단합니다. 더 이상 다른 것을 사용하지 않습니다.
요약하자면, lxml
는 초고속 프로덕션 품질의 html 및 xml 파서로 자리 잡았으며, soupparser
BeautifulSoup의 기능을 대체 하는 모듈 도 포함 합니다. BeautifulSoup
는 잘못된 형식의 html 또는 xml에서 데이터를 신속하게 추출하는 시간을 절약하기 위해 설계된 1 인 프로젝트입니다.
lxml 문서에 따르면 두 파서 모두 장단점이 있습니다. 이러한 이유로 lxml
는 soupparser
앞뒤로 전환 할 수 있도록를 제공 합니다. 인용,
BeautifulSoup은 다른 파싱 접근 방식을 사용합니다. 실제 HTML 파서는 아니지만 정규식을 사용하여 태그 수프를 살펴 봅니다. 따라서 어떤 경우에는 더 관대하고 다른 경우에는 덜 좋습니다. lxml / libxml2가 깨진 HTML을 더 잘 구문 분석하고 수정하는 것은 드문 일이 아니지만 BeautifulSoup은 인코딩 감지에 대한 우수한 지원을 제공합니다. 파서가 더 잘 작동하는 입력에 따라 크게 달라집니다.
결국 그들은 말하고 있습니다.
이 파서를 사용하는 단점 은 lxml의 HTML 파서보다 훨씬 느리다는 것입니다. 따라서 성능이 중요한 경우 특정 경우에 대한 대체 수단으로 만 soupparser를 사용하는 것을 고려할 수 있습니다.
내가 그것들을 올바르게 이해한다면, 그것은 수프 파서가 더 강력하다는 것을 의미합니다 --- 정규 표현식을 사용하여 잘못된 태그의 "수프"를 처리 할 수 있습니다 --- 반면 lxml
에 더 간단하고 그냥 파싱하고 트리를 만듭니다. 기대할 것입니다. for 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을 사용하는 프로젝트에 대해 알고 싶으면 이메일을 보내주세요.
--Leonard
Beautiful Soup 문서 에서 인용 .
나는 이것이 이제 명확하기를 바랍니다. The soup는 제대로 디자인되지 않은 웹 사이트에서 데이터를 추출하는 시간을 절약하기 위해 설계된 훌륭한 1 인 프로젝트입니다. 목표는 지금 당장 시간을 절약하고 작업을 완료하는 것입니다. 장기적으로 시간을 절약 할 필요는 없으며 소프트웨어의 성능을 최적화하는 것이 아닙니다.
또한 lxml 웹 사이트 에서
lxml은 Python Package Index에서 2 백만 회 이상 다운로드되었으며 Linux 또는 MacOS-X와 같은 많은 패키지 배포에서 직접 사용할 수도 있습니다.
그리고 왜 lxml에서? ,
C 라이브러리 libxml2 및 libxslt에는 다음과 같은 큰 이점이 있습니다. 표준 준수 ... 모든 기능 ... 빠름. 빠른! 빠른! ... lxml은 libxml2 및 libxslt에 대한 새로운 Python 바인딩입니다.
BeautifulSoup을 사용하지 말고 lxml.soupparser 를 사용하면 lxml의 힘 위에 앉아 정말 깨지고 엉뚱한 HTML을 다루는 BeautifulSoup의 좋은 부분을 사용할 수 있습니다.
HTML 구문 분석을 위해 lxml을 사용했습니다. "soupy"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()
For sure i would use EHP. It is faster than lxml, much more elegant and simpler to use.
Check out. 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()
Output:
Hello world.
A somewhat outdated speed comparison can be found here, which clearly recommends lxml, as the speed differences seem drastic.
ReferenceURL : https://stackoverflow.com/questions/1922032/parsing-html-in-python-lxml-or-beautifulsoup-which-of-these-is-better-for-wha
'programing' 카테고리의 다른 글
크기 조정 후 확장기를 사용하여 WPF 창 크기를 콘텐츠에 맞게 유지하는 방법 (0) | 2021.01.15 |
---|---|
Runtime.exec를 호출 할 때 stdout 캡처 (0) | 2021.01.15 |
뮤텍스는 변경 가능해야합니까? (0) | 2021.01.15 |
Go 구조체에서 멤버를 초기화하는 방법 (0) | 2021.01.15 |
힘내는 내가 원점보다 얼마나 많은 커밋인지 보여주지 않는다. (0) | 2021.01.15 |