【问题标题】:New items added to list from HTML Table using HTMLParser in Python 2.7在 Python 2.7 中使用 HTMLParser 从 HTML 表中添加新项目
【发布时间】:2018-01-24 21:07:14
【问题描述】:

借助有关HTMLParser 和此stackoverflow post 的文档,我尝试从表中提取数据,同时从<td>..</td> 之间的表中提取数据,并将其附加到列表中appends 新项目当它有新的starttag 时。

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

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']

如何忽略&lt;Room Separation&gt;&lt;br&gt; 等标签,仅将&lt;td&gt;..&lt;/td&gt; 之间的数据附加到这样的一项

所需的输出 ['删除其中一个。 ', ' 060 : : 模型线 : id 549036 ', ' 060 : : 模型线 : id 549042', ' 删除 其中的一个。 ', ' 060 : : 型号线 : id 549036 ', ' 060 : : 模型线:id 549081']

【问题讨论】:

  • HTMLParser 是一种非常老式的 HTML 解析方式。你确定要这样做吗?
  • 我实际上不想,但我想不出任何方法可以在 IronPython 中使用漂亮的汤或其他模块!
  • 嗯,这就解释了。
  • 恐怕我听不懂。你似乎成功了。
  • 嗯,我似乎有但不完全。由于表 data 之间有
    等标签,因此输出列表中有 10 个项目。另一方面,所需的输出只有 6 个项目,这是我需要的。

标签: python-2.7 html-table html-parsing


【解决方案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']

【讨论】:

  • 我得到了相同的输出,我期待 Desired OUTPUT 请查看我的问题。我真的无法在您的代码中理解为什么 parser._stack 在列表 ['html', 'p', 'table'] 中包含此内容,这对我来说没有意义。
  • 首先,我的代码的输出很容易转换成你想要的输出。考虑一个例子。你想要[' Delete one of those. ', ' 060 : : Model Lines : id 549036 ', 我给了你[' Delete one of those. ', ' 060 : ', ' : Model Lines : id 549036 ', Smply 加入系列中的字符串对。其次,您提到的标签(例如html)由HTMLParser从HTML中解析出来。我的代码只是在找到它们时将它们放在堆栈上,然后在找到相应的结束标记时将它们弹出。这就是它如何知道它何时“在”td 单元格内,并且必须收集字符。
  • 您可以通过打开编辑器将我的结果直接放在您想要的下方的一行中来检查我的第一个断言。这就是我刚刚所做的。
  • 我检查了你所说的比较两者并没有发现任何区别。它是同一个字母的字母
  • 我的意思是将您想要的内容与我的脚本生成的内容进行比较。
猜你喜欢
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 2017-06-08
  • 2015-11-03
  • 2012-06-19
  • 1970-01-01
相关资源
最近更新 更多