Python:从文本数据中剥离 html

Posted

技术标签:

【中文标题】Python:从文本数据中剥离 html【英文标题】:Python: strip html from text data 【发布时间】:2011-06-04 05:20:00 【问题描述】:

我的问题与:Strip html from strings in Python

我正在寻找一种从文本中去除 HTML 代码的简单方法。例如:

string = 'foo <SOME_VALID_HTML_TAG> something </SOME_VALID_HTML_TAG> bar'
stripIt(string)

然后会产生foo bar

是否有任何简单的工具可以在 Python 中实现这一点? HTML 代码可以嵌套。

【问题讨论】:

我认为您可能希望在您链接的问题上使用已接受的答案 - 您正在做的事情有何不同? 在相关问题中,用户希望 stripIt('foo') 产生 foo,而在我的情况下,我希望它返回 ''。 正确 - 我的错误。我没有看到对您问题的修改,并认为 something 是您想要删除的标签。 “SOME_VALID_HTML_TAG”是否设置为特定标签?是否要删除最外层的标签? 【参考方案1】:

你可以使用正则表达式:

def stripIt(s):
  txt = re.sub('<[^<]+?>.*?</[^<]+?>', '', s) # Remove html tags
  return re.sub('\s+', ' ', txt)              # Normalize whitespace

但是,我更喜欢 Hugh Bothwell 的解决方案,因为它比纯正则表达式更健壮。

【讨论】:

【参考方案2】:

如果有人遇到此问题并且已经在使用 jinja 模板语言:您可以在模板中使用过滤器 striptags,在代码中使用函数 jinja2.filters.do_striptags()

【讨论】:

【参考方案3】:
import lxml.html
import re

def stripIt(s):
    doc = lxml.html.fromstring(s)   # parse html string
    txt = doc.xpath('text()')       # ['foo ', ' bar']
    txt = ' '.join(txt)             # 'foo   bar'
    return re.sub('\s+', ' ', txt)  # 'foo bar'

s = 'foo <SOME_VALID_HTML_TAG> something </SOME_VALID_HTML_TAG> bar'
stripIt(s)

返回

foo bar

【讨论】:

我认为,lxml 比其他模块更好,这就像魅力。 这很好,因为按照 OP 的要求,结果 'foo' 和 'bar' 之间只有一个空格。其他一些解决方案会留下两个空格。【参考方案4】:

您可以通过相应地覆盖方法来利用 HTMLParser:

from HTMLParser import HTMLParser

class HTMLStripper(HTMLParser):

    text_parts = []
    depth = 0

    def handle_data(self, data):
        if self.depth == 0:
            self.text_parts.append(data.strip())

    def handle_charref(self, ref):
        data = unichr(int(ref))
        self.handle_data(data)

    def handle_starttag(self, tag, attrs):
        self.depth += 1

    def handle_endtag(self, tag):
        if self.depth > 0:
            self.depth -= 1

    def handle_entityref(self, ref):
        try:
            data = unichr(name2codepoint[ref])
            self.handle_data(data)
        except KeyError:
            pass

    def get_stripped_text(self):
        return ' '.join(self.text_parts)

def strip_html_from_text(html):
    parser = HTMLStripper()
    parser.feed(html)
    return parser.get_stripped_text()

def main():
    import sys
    html = sys.stdin.read()
    text = strip_html_from_text(html)
    print text

if __name__ == '__main__':
    main() 

【讨论】:

【参考方案5】:
from BeautifulSoup import BeautifulSoup

def removeTags(html, *tags):
    soup = BeautifulSoup(html)
    for tag in tags:
        for tag in soup.findAll(tag):
            tag.replaceWith("")

    return soup


testhtml = '''
<html>
    <head>
        <title>Page title</title>
    </head>
    <body>text here<p id="firstpara" align="center">This is paragraph <b>one</b>.</p>
        <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p>
    </body>
</html>'''

print removeTags(testhtml, 'b', 'p')

【讨论】:

【参考方案6】:

试试这个解决方案:

from BeautifulSoup import BeautifulSoup

def stripIt(string, tag):
    soup = BeautifulSoup(string)

    rmtags = soup.findAll(tag)
    for t in rmtags:
        string = string.replace(str(t), '')
    return string

string = 'foo <p> something </p> bar'
print stripIt(string, 'p')
>>> foo  bar

string = 'foo <a>bar</a> baz <a>quux</a>'
print stripIt(string, 'a')
>>> foo  baz

编辑:这只适用于有效嵌套的标签,例如:

string = 'blaz <div>baz <div>quux</div></div>'
print stripIt(string, 'div')
>>> blaz

string = 'blaz <a>baz <a>quux</a></a>'
print stripIt(string, 'a')
>>> blaz <a>baz </a>

【讨论】:

以上是关于Python:从文本数据中剥离 html的主要内容,如果未能解决你的问题,请参考以下文章

在 python 中使用 mechanize 剥离 html 标签并仅返回文本

Python - 从文件中的行中剥离时间戳和用户名

从文本中剥离标签(在 React JS 中)

从 txt 文件绘制简单的图形 python

如何从 SubRip .srt 文件中仅提取文本(剥离时间码)?

如何剥离两个分隔符之间的文本,包括空行? [复制]