【问题标题】:Get HTML subtree from HTMLparser从 HTMLparser 获取 HTML 子树
【发布时间】:2013-12-19 21:37:20
【问题描述】:

我实际上正在使用 HTMLparser for python,我正在尝试获取包含在特定节点中的 HTML 子树。 我有一个通用解析器做得很好,一旦找到有趣的标签,我想用这个节点中的数据提供另一个特定的 HTMLParser。

这是我想做的一个例子:

class genericParser(HTMLParser):
   def __init__ (self):
       HTMLParser.__init__(self)
       self.divFound = False

   def handle_starttag (self, tag, attrs):
       if tag == "div" and ("class", "good") in attrs:
           self.divFound = True

   def handle_data (self, data):
       if self.divFound:
           print data    ## print nothing
           parser = specificParser ()
           parser.feed (data)
           self.divFound = False

然后给 genericParser 提供类似的东西:

<html>
<head></head>
<body>
   <div class='good'>
      <ul>
         <li>test1</li>
         <li>test2</li>
      </ul>
   </div>
</body>
</html>

但在 HTMLParser.handle_data 的 python 文档中:

调用此方法来处理任意数据(例如文本节点和 &lt;script&gt;...&lt;/script&gt;&lt;style&gt;...&lt;/style&gt;的内容)。

在我的genericParser 中,handle_data 得到的数据是空的,因为我的&lt;div class='good'&gt; 不是文本节点。

如何使用 HTMLParser 检索 div 内的原始 HTML 数据?

提前致谢

【问题讨论】:

  • 使用DOM 解析器来提取子树会更容易。你还在坚持HTMLParser吗?
  • 我尝试使用 HTMLParser,因为项目的很大一部分已经用它完成了,我发现解析子树有这个问题。最后,我开始在缓冲区中记录 html 树,以便在结束有趣块的handle_endtag() 处使用它。这不是我想的解决方案,但我不再卡住了。感谢您的建议
  • 那么,你已经解决了吗?
  • 是的,我会用解决方案来回答,但我会等几个小时看看是否有比缓冲 html 更好的解决方案。
  • 我问你是因为想用BeautifulSoup 提取子树,然后调用你的specificParser。如果您坚持使用HTMLParser,我的想法也是记录每个节点,直到关闭&lt;/div&gt;,但我看到您已经在处理它了。

标签: python python-2.7 html-parsing


【解决方案1】:

我通过缓冲有趣的 HTML 节点中遇到的所有数据解决了这个问题。

这个可行,但不是很“干净”,因为 GenericParser 必须先解析整个有趣的块,然后再将其提供给 SpecificParser。 这是一个“轻量级”(没有任何错误处理)解决方案:

class genericParser(HTMLParser):
   def __init__ (self):
       HTMLParser.__init__ (self)
       self.divFound = False
       self.buff = ""
       self.level = 0

   def computeRecord (self, tag, attrs):
        mystr = "<" + tag + " "
        for att, val in attrs:
            mystr += att+"='"+val+ "' "
        mystr += ">"
        return mystr

   def handle_starttag (self, tag, attrs):
       if tag == "div" and ("class", "good") in attrs:
           self.divFound = True
       elif self.divFound:
          self.level += 1
          self.buff += self.computeRecord (tag, attrs)

   def handle_data (self, data):
       if self.divFound:
          self.buff += data


   def handle_endtag (self, tag):
      if self.divFound:
         self.buff += "</" + tag + ">"
         self.level -= 1
         if (self.level == 0):
            self.divFound = False
            print self.buff

输出如你所愿:

<ul>
     <li>test1</li>
     <li>test2</li>
</ul>

正如 Birei 在 cmets 中所说,我会更容易用 BeautifulSoup 提取子树

soup = BeaufitulSoup (html)
div = soup("div", {"class" : "good"})
children = div[0].findChildren ()
print children[0]   #### desired output

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    相关资源
    最近更新 更多