使用Python解析HTML

我正在寻找Python的HTML解析器模块,可以帮助我以Python列表/字典/对象的形式获取标记。

如果我有以下格式的文件:

<html>
<head>Heading</head>
<body attr1='val1'>
<div class='container'>
<div id='class'>Something here</div>
<div>Something else</div>
</div>
</body>
</html>

那么它应该给我一种方法来访问嵌套标签通过HTML标签的名称或id,这样我基本上可以要求它为我提供内容/文本在div标签与body标签中包含的class='container',或类似的东西。

如果您使用过Firefox的“Inspect element”功能(查看HTML),您就会知道它以一种漂亮的嵌套方式为您提供所有标记,就像树一样。

我更喜欢内置模块,但这可能要求有点太多。


我在Stack Overflow和互联网上的一些博客上看了很多问题,大多数人都建议使用BeautifulSoup或lxml或HTMLParser,但很少有人详细介绍了功能,并简单地结束了关于哪个更快/更有效的争论。

411131 次浏览

在这里,您可以阅读更多关于Python中不同的HTML解析器及其性能的信息。尽管这篇文章有点过时,但它仍然给了你一个很好的概述。

Python HTML解析器性能

我推荐BeautifulSoup,尽管它不是内置的。只是因为它很容易完成这类任务。例如:

import urllib2
from BeautifulSoup import BeautifulSoup


page = urllib2.urlopen('http://www.google.com/')
soup = BeautifulSoup(page)


x = soup.body.find('div', attrs={'class' : 'container'}).text

所以我可以让它给我的内容/文本在div标签class='容器'包含在body标签,或类似的东西。

try:
from BeautifulSoup import BeautifulSoup
except ImportError:
from bs4 import BeautifulSoup
html = #the HTML code you've written above
parsed_html = BeautifulSoup(html)
print(parsed_html.body.find('div', attrs={'class':'container'}).text)

我猜你不需要性能描述——只要阅读BeautifulSoup是如何工作的就可以了。看看它的官方文档

我猜你要找的是pyquery:

Pyquery: python类jquery库。

你想要的东西可以是这样的:

from pyquery import PyQuery
html = # Your HTML CODE
pq = PyQuery(html)
tag = pq('div#id') # or     tag = pq('div.class')
print tag.text()

它使用与Firefox或Chrome的inspect元素相同的选择器。例如:

the element selector is 'div#mw-head.noprint'

被检查的元素选择器是'div#mw-head.noprint'。在pyquery中,你只需要传递这个选择器:

pq('div#mw-head.noprint')

我推荐用lxml来解析HTML。看到“解析HTML”(在lxml站点上)。

根据我的经验,Beautiful Soup在一些复杂的HTML上搞砸了。我相信这是因为Beautiful Soup不是一个解析器,而是一个非常好的字符串分析器。

与其他解析器库相比,lxml非常快:

  • http://blog.dispatched.ch/2010/08/16/beautifulsoup-vs-lxml-performance/ < a href = " http://blog.dispatched.ch/2010/08/16/beautifulsoup-vs-lxml-performance/ " > < / >
  • http://www.ianbicking.org/blog/2008/03/python-html-parser-performance.html < a href = " http://www.ianbicking.org/blog/2008/03/python-html-parser-performance.html " > < / >

使用cssselect也很容易用于抓取HTML页面:

from lxml.html import parse
doc = parse('http://www.google.com').getroot()
for div in doc.cssselect('a'):
print '%s: %s' % (div.text_content(), div.get('href'))

lxml.html文档 .html

我会使用EHP

https://github.com/iogf/ehp

下面就是:

from ehp import *


doc = '''<html>
<head>Heading</head>
<body attr1='val1'>
<div class='container'>
<div id='class'>Something here</div>
<div>Something else</div>
</div>
</body>
</html>
'''


html = Html()
dom = html.feed(doc)
for ind in dom.find('div', ('class', 'container')):
print ind.text()

输出:

Something here
Something else

我建议使用justext库:

https://github.com/miso-belica/jusText

< p >用法: Python2: < / >强

import requests
import justext


response = requests.get("http://planet.python.org/")
paragraphs = justext.justext(response.content, justext.get_stoplist("English"))
for paragraph in paragraphs:
print paragraph.text

Python3:

import requests
import justext


response = requests.get("http://bbc.com/")
paragraphs = justext.justext(response.content, justext.get_stoplist("English"))
for paragraph in paragraphs:
print (paragraph.text)