python删除html标签,包括html实体,但不包括带有 '&'前缀的普通文本

标签 python html

我想删除 html 标签,包括 python 2.7 中的 & 等 html 实体,但我的输入文本包含以字母 & 开头的普通文本,我不知道不想删除这样的文字。我正在尝试这篇文章中得票最多的答案:Strip HTML from strings in Python 。唯一的区别是,我用 space 替换 html 标签。

from HTMLParser import HTMLParser

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def get_data(self):
        return ' '.join(self.fed)

def strip_tags(html):
    s = MLStripper()
    s.feed(html)
    return s.get_data()

print strip_tags('html tags<p>will be&amp;replaced</p>with space. NOT this &abc')
# Now the output is:  "html tags will be replaced with space. NOT this  "
# The wanted output is:  "html tags will be replaced with space. NOT this &abc"

如何输出正确的文本?

最佳答案

你可以尝试 BeautifulSoup :

>>> html = '<div><p>&abc is <b>my</b> input text</p></div>'
>>> print strip_tags(html)
 is  my  input text

>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(html)
>>> print soup.text
&abc is my input text
>>> soup = BeautifulSoup('=&abc= is my input text')
>>> soup.text
u'=&abc= is my input text'

请注意,您的 strip_tags()未正确剥离嵌套的 <b>我添加到您的测试字符串中的标签。

如果你想坚持使用标准 HTMLParser,有 another answer您链接到的问题做得更好。对于我的测试字符串,它将输出 &abc; is my input text ,即它将转义独立的 & 。我不确定您想要哪个输出。

更新

这有效:

import re
from HTMLParser import HTMLParser
from htmlentitydefs import entitydefs

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.fed = []
        self.entityref = re.compile('&[a-zA-Z][-.a-zA-Z0-9]*[^a-zA-Z0-9]')

    def handle_data(self, d):
        self.fed.append(d)

    def handle_starttag(self, tag, attrs):
        self.fed.append(' ')

    def handle_endtag(self, tag):
        self.fed.append(' ')

    def handle_entityref(self, name):
        if entitydefs.get(name) is None:
            m = self.entityref.match(self.rawdata.splitlines()[self.lineno-1][self.offset:])
            entity = m.group()
            # semicolon is consumed, other chars are not.
            if entity[-1] != ';':
                entity = entity[:-1]
            self.fed.append(entity)
        else:
            self.fed.append(' ')

    def get_data(self):
        self.close()    # N.B. ensure all buffered data has been processed
        return ''.join(self.fed)

def strip_tags(html):
    s = MLStripper()
    s.feed(html)
    return s.get_data()

print strip_tags('html &zzz; tags<p>&zzz &zz: will be&amp;replaced</p>with space. NOT this &abc')

输出

html &zzz; tags &zzz &zz: will be replaced with space. NOT this &abc

此代码添加了开始和结束标记的处理程序,这些标记被单个空格替换。实体引用的处理方式还包括用空格替换已知的有效引用,并保持未知的引用不变。

另一个重要问题是调用close()在调用 get_data() 之前在解析器上。我把它放在get_data()方法,尽管您可以将其添加到 strip_tags()功能。我认为 close() 并不重要被多次调用,所以可以调用get_data()然后向解析器提供更多数据。

关于python删除html标签,包括html实体,但不包括带有 '&'前缀的普通文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32408502/

相关文章:

python - Numpy "fill"方法是如何实现的?

python - 如何使用 Python 3.5 在 Windows 10 系统上安装 mbed CLI?

HTML 网页无法正常显示

javascript - 如何在ID内使用AJAX重复 'onclick'函数?

html - Chrome 43 中文本偶尔会溢出到 div 之外

javascript - 合并标题并针对每个页面进行修改

python - 用散点图叠加直方图的列

python - 检查是否在 Windows 命令提示符与 Cygwin python 中运行

python - 奇怪的while循环导致无限循环

css - 在 span 中显示图像而不将其转换为 block 级元素