Python:unescape不分割数据的特殊字符

Python:unescape不分割数据的特殊字符,python,html,special-characters,Python,Html,Special Characters,我制作了一个简单的HTML解析器,它基本上是文档的直接副本。在不将数据分割成多个数据块的情况下,我很难避开特殊字符 下面是我的代码和一个简单的示例: from HTMLParser import HTMLParser class MyHTMLParser(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.data = [] def handle_starttag(se

我制作了一个简单的HTML解析器,它基本上是文档的直接副本。在不将数据分割成多个数据块的情况下,我很难避开特殊字符

下面是我的代码和一个简单的示例:

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.data = []

    def handle_starttag(self, tag, attrs):
        #print (tag,attrs)
        pass

    def handle_endtag(self, tag):
        #print (tag)
        pass

    def handle_data(self, data):
        self.data.append(data)

    def handle_charref(self, ref):
        self.handle_entityref("#" + ref)

    def handle_entityref(self, ref):
        self.handle_data(self.unescape("&%s;" % ref))



n = "<strong>I &lt;3s U &amp; you luvz me</strong>"


parser = MyHTMLParser()
parser.feed(n)
parser.close()
data = parser.data
print(data)
从HTMLParser导入HTMLParser
类MyHtmlPasser(HtmlPasser):
定义初始化(自):
HTMLPasser.\uuuuu初始化\uuuuuuuuu(自)
self.data=[]
def句柄\u开始标记(自身、标记、属性):
#打印(标签、属性)
通过
def handle_endtag(self,tag):
#打印(标签)
通过
def句柄_数据(自身、数据):
self.data.append(数据)
def handle_charref(自身,ref):
self.handle_entityref(“#”+ref)
def handle_entityref(self,ref):
self.handle_数据(self.unescape(&%s;%ref))
n=“i3su&;youluvzme”
parser=MyHTMLParser()
parser.feed(n)
parser.close()
data=parser.data
打印(数据)
问题是它返回5个独立的数据位

['I ', u'<', '3s U ', u'&', ' you luvz me']

['I',u'使用以下方法加入字符串列表:


请记住,HTMLPasser的目的是让您从输入构建文档树。如果您根本不关心文档的结构,那么
str.join
solution@falsetru-gives就可以了。您可以确定,所有元素标记和注释都将被过滤掉

但是,如果您确实需要用于更复杂场景的结构,则必须构建文档树。
handle\u starttag
handle\u endtag
方法用于此

首先,我们需要一个能够保存一些信息的基本树

class Element:
    def __init__(self, parent, tag, attrs=None):
        self.parent = parent
        self.tag = tag
        self.children = []
        self.attrs = attrs or []
        self.data = ''
现在,您需要让HTMLParser在每个
句柄上创建一个新节点,并在每个
句柄上向上移动树。我们还将解析后的数据传递给当前节点,而不是保存在解析器中

class MyHTMLParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.root = Element(NONE, '__DOCROOT__') # Special root node for us
        self.current = self.root

    def handle_starttag(self, tag, attrs):
        newel = Element(self.current tag, attrs)
        self.current.children.append(newel)
        self.current = newel

    def handle_endtag(self, tag):
        self.current = self.current.parent

    def handle_data(self, data):
        self.current.data += data

    def handle_charref(self, ref): # No changes here
        self.handle_entityref('#' + ref)

    def handle_entityref(self, ref): # No changes here either
        self.handle_data(self.unescape("&%s" % ref))
现在,您可以访问
MyHTMLParser.root
上的树,从任意元素获取数据

n = '<strong>I &lt;3s U &amp; you luvz me</strong>'
p = MyHTMLParser()
p.feed(n)
p.close()

def print_tree(node, indent=0):
    print('    ' * indent + node.tag)
    print('    ' * indent + '  ' + node.data)
    for c in node.children:
        print_tree(c, indent + 1)

print_tree(p.root)
n='i3su&;youluvzme'
p=MyHTMLParser()
p、 饲料(n)
p、 关闭()
def打印树(节点,缩进=0):
打印(“”*缩进+节点标记)
打印(“”*缩进+“”+节点数据)
对于node.children中的c:
打印树(c,缩进+1)
打印树(p.root)
这会给你

__DOCROOT__

    strong
      I <3s U & you luvz me
\uuuu DOCROOT__
坚强的
我你可以参考这个

并根据需要编辑
html\u to\u text
函数

from HTMLParser import HTMLParser
n = "<strong>I &lt;3s U &amp; you luvz me</strong>"

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def handle_entityref(self, name):
        self.fed.append('&%s;' % name)
    def get_data(self):
        return ''.join(self.fed)

def html_to_text(html):
    s = MLStripper()
    s.feed(html)
    return HTMLParser().unescape(s.get_data())

print html_to_text(n)
从HTMLParser导入HTMLParser
n=“i3su&;youluvzme”
类MLStripper(HTMLPasser):
定义初始化(自):
self.reset()
self.fed=[]
def句柄_数据(自身,d):
self.fed.append(d)
def handle_entityref(自身,名称):
self.fed.append('&%s;'%name)
def get_数据(自身):
返回“”。加入(self.fed)
def html_至_文本(html):
s=MLM剥离器()
s、 提要(html)
返回HTMLParser().unescape(s.get_data())
将html_打印到_文本(n)
输出:

I <3s U & you luvz me

我感谢falsetru。在这种简单的情况下,Join可能会起作用,但如果使用更复杂的html,则很难确定要加入什么。原因是我没有使用lxml(或ElementTree)我真的不知道它们是如何工作的,在使用它们之前我试图从第一原理中学习。但是我会更深入地研究。非常感谢你,这里有很多我不完全理解的地方,但我现在会仔细阅读。我已经接受了falsetru的回答,因为它最适合我实际提出的问题,尽管你的答案更适合wh至少我想知道。
__DOCROOT__

    strong
      I <3s U & you luvz me
__DOCROOT__

    html

        head

            title
              Test
        body

            h1
              I <3s U & you luvz me
from HTMLParser import HTMLParser
n = "<strong>I &lt;3s U &amp; you luvz me</strong>"

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def handle_entityref(self, name):
        self.fed.append('&%s;' % name)
    def get_data(self):
        return ''.join(self.fed)

def html_to_text(html):
    s = MLStripper()
    s.feed(html)
    return HTMLParser().unescape(s.get_data())

print html_to_text(n)
I <3s U & you luvz me