55

我正在尝试使用 BeautifulSoup 转换一大段 HTML 文本。这是一个例子:

<div>
    <p>
        Some text
        <span>more text</span>
        even more text
    </p>
    <ul>
        <li>list item</li>
        <li>yet another list item</li>
    </ul>
</div>
<p>Some other text</p>
<ul>
    <li>list item</li>
    <li>yet another list item</li>
</ul>

我尝试做类似的事情:

def parse_text(contents_string)
    Newlines = re.compile(r'[\r\n]\s+')
    bs = BeautifulSoup.BeautifulSoup(contents_string, convertEntities=BeautifulSoup.BeautifulSoup.HTML_ENTITIES)
    txt = bs.getText('\n')
    return Newlines.sub('\n', txt)

...但是这样我的 span 元素总是在一个新的行上。这当然是一个简单的例子。有没有办法在 Python 中获取 HTML 页面中的文本,就像它在浏览器中呈现的方式一样(不需要 css 规则,只是呈现 div、span、li 等元素的常规方式)?

4

2 回答 2

119

BeautifulSoup 是一个抓取库,因此它可能不是进行 HTML 渲染的最佳选择。如果不是必须使用 BeautifulSoup,你应该看看html2text. 例如:

import html2text
html = open("foobar.html").read()
print html2text.html2text(html)

这输出:

一些文字更多文字甚至更多文字

  * 项目清单
  * 另一个列表项

其他一些文字

  * 项目清单
  * 另一个列表项
于 2012-11-12T03:09:46.810 回答
5

我在尝试解析呈现的 HTML 时遇到了同样的问题。基本上,BS 似乎不是这个理想的包。@Del 提供了很棒的 html2text 解决方案。

在一个不同的 SO 问题上:BeautifulSoup get_text 不会剥离所有标签和 JavaScript @Helge 使用 nltk 提到的。不幸的是,nltk 似乎停止了这种方法。

我尝试了 html2text 和 nltk.clean_html 并且对计时结果感到惊讶,因此认为他们需要为后代提供答案。当然,速度很大程度上取决于数据的内容......

来自@Helge(nltk)的回答。

import nltk

%timeit nltk.clean_html(html)
was returning 153 us per loop

返回带有呈现的 html 的字符串非常有效。这个 nltk 模块甚至比 html2text 更快,尽管 html2text 可能更健壮。

以上来自@del的回答

betterHTML = html.decode(errors='ignore')
%timeit html2text.html2text(betterHTML)
%3.09 ms per loop
于 2013-11-05T17:53:46.903 回答