在 Python 2.7 中使用 HTMLParser 从 HTML 表格添加到列表中的新项目

New items added to list from HTML Table using HTMLParser in Python 2.7

提问人:Watarap 提问时间:8/17/2017 更新时间:8/17/2017 访问量:398

问:

在有关 HTMLParser 的文档和此 stackoverflow 帖子的帮助下,我尝试从表中提取数据,同时从 之间的表中提取数据,并在其中包含新项目时将新项目附加到列表中。<td>..</td>appendsstarttag

下面有一个小例子来解释我的问题:

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.in_td = False
        self._out = []

    def handle_starttag(self, tag, attrs):
        if tag == 'td':
            self.in_td = True

    def handle_endtag(self, tag):
        self.in_td = False

    def handle_data(self, data):
        if self.in_td:
            #print(data)
            self._out.append(data)


if __name__ == "__main__":
    parser = MyHTMLParser()
    link_raw = """
<html><p><center><h1>  Clash Report 1  </h1></center></p><p><table border=on>  <th> Errors </th><th>  Elements </th>
<tr>  <td>  Delete one of those.  </td>
<td>  060 : <Room Separation> : Model Lines : id 549036  <br>  060 : <Room Separation> : Model Lines : id 549042</td></tr>
<tr>  <td>  Delete one of those.  </td>
<td>  060 : <Room Separation> : Model Lines : id 549036  <br>  060 : <Room Separation> : Model Lines : id 549081</td></tr>
"""
    #<html><head><title>Test</title></head><body><tr><td>yes</td><td>no</td></tr></body></html>

    parser.feed(link_raw)
    print (parser._out)

输出

['  Delete one of those.  ', '  060 : ', ' : Model Lines : id 549036  ', '  060 : ', ' : Model Lines : id 549042', '  Delete one of those.  ', '  060 : ', ' : Model Lines : id 549036  ', '  060 : ', ' : Model Lines : id 549081']

如何忽略这些标签,例如 和 并仅将数据附加到一个项目之间,如下所示<Room Separation><br><td>..</td>

Desired OUTPUT [' 删除其中之一。', ' 060 : : 模型行 : id 549036 ', ' 060 : : 模型行 : id 549042', ' 删除 其中之一。', ' 060 : : 模型线 : id 549036 ', ' 060 : : 模型线 : id 549081']

python-2.7 表html 解析

评论

1赞 Bill Bell 8/17/2017
HTMLParser 是一种非常老式的解析 HTML 的方法。你确定要这样做吗?
0赞 Watarap 8/17/2017
我实际上不想,但我想不出任何方法可以在 IronPython 中使用美丽的汤或其他模块!
0赞 Bill Bell 8/17/2017
嗯,这就解释了这一点。
0赞 Bill Bell 8/17/2017
恐怕我不明白。你似乎成功了。
0赞 Watarap 8/17/2017
好吧,我似乎有,但不完全有。Ouput 列表中有 10 个项目,因为表 data<td 之间有 <Room Separation> 和 <br> 等标签> 。另一方面,所需输出只有 6 个项目,这是我需要的。

答:

0赞 Bill Bell 8/17/2017 #1

我认为一种方法是保留一堆标签,忽略那些碍事的标签。顺便说一句,由于“房间分隔”不是犹太标签标识符,HTMLParser 将其转换为普通的“房间”。

from html.parser import HTMLParser

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

    def handle_starttag(self, tag, attrs):
        if tag in ['br', 'room']: return
        self._stack.append(tag)

    def handle_endtag(self, tag):
        self._stack.pop()

    def handle_data(self, data):
        if self._stack and self._stack[-1] == 'td':
            self._out.append(data)


if __name__ == "__main__":
    parser = MyHTMLParser()
    link_raw = """
<html><p><center><h1>  Clash Report 1  </h1></center></p><p><table border=on>  <th> Errors </th><th>  Elements </th>
<tr>  <td>  Delete one of those.  </td>
<td>  060 : <Room Separation> : Model Lines : id 549036  <br>  060 : <Room Separation> : Model Lines : id 549042</td></tr>
<tr>  <td>  Delete one of those.  </td>
<td>  060 : <Room Separation> : Model Lines : id 549036  <br>  060 : <Room Separation> : Model Lines : id 549081</td></tr>
"""
    #<html><head><title>Test</title></head><body><tr><td>yes</td><td>no</td></tr></body></html>

    parser.feed(link_raw)
    result = parser._out
    print (len(result))
    print (result)

输出:

10
['  Delete one of those.  ', '  060 : ', ' : Model Lines : id 549036  ', '  060 : ', ' : Model Lines : id 549042', '  Delete one of those.  ', '  060 : ', ' : Model Lines : id 549036  ', '  060 : ', ' : Model Lines : id 549081']

评论

0赞 Watarap 8/18/2017
我得到了相同的输出,我期待所需的输出,请查看我的问题。我真的不明白为什么在您的代码中包含这个列表,这对我来说没有意义。parser._stack['html', 'p', 'table']
0赞 Bill Bell 8/18/2017
首先,我的代码的输出很容易转换为您想要的输出。考虑一个实例。你想要我给你 Smply 连接系列中的字符串对。其次,您提到的标签(例如)是由 HTMLParser 从 HTML 中解析出来的。我的代码只是在找到它们时将它们放在堆栈上,然后在找到它们相应的结束标签时将它们弹出。这就是它如何知道它何时“进入”细胞,并且必须收集字符。[' Delete one of those. ', ' 060 : : Model Lines : id 549036 ',[' Delete one of those. ', ' 060 : ', ' : Model Lines : id 549036 ',htmltd
0赞 Bill Bell 8/18/2017
你可以通过打开一个编辑器来检查我的第一个断言,将我的结果放在你想要的结果正下方的一行中。这就是我刚刚所做的。
0赞 Watarap 8/18/2017
我检查了你说的比较两者并没有真正发现任何区别。它是一样的字母对字母
0赞 Bill Bell 8/18/2017
我的意思是将你想要的与我的剧本制作的东西进行比较。