Skip to main content
 首页 » 编程设计

python之Python 中的 SGML 解析器

2025年05月04日17mayingbao

我是 Python 的新手。我有以下代码:

class ExtractTitle(sgmllib.SGMLParser): 
 
def __init__(self, verbose=0): 
 
   sgmllib.SGMLParser.__init__(self, verbose) 
 
   self.title = self.data = None 
 
def handle_data(self, data): 
 
  if self.data is not None: 
    self.data.append(data) 
 
def start_title(self, attrs): 
 self.data = [] 
 
def end_title(self): 
 
  self.title = string.join(self.data, "") 
 
raise FoundTitle # abort parsing! 

从 SGML 中提取标题元素,但它只适用于单个标题。我知道我必须重载 unknown_starttag 和 unknown_endtag 才能获得所有标题,但我总是弄错。请帮助我!!!

请您参考如下方法:

Beautiful Soup是您可以很好地解析它的一种方式(这也是我总是这样做的方式,除非有一些非常好的理由不这样做,我自己)。它比使用 SGMLParser 更简单且可读性更强。

>>> from BeautifulSoup import BeautifulSoup 
>>> soup = BeautifulSoup('''<post id='100'> <title> new title </title> <text> <p> new text </p> </text> </post>''') 
>>> soup('post')  # soup.findAll('post') is equivalent 
[<post id="100"> <title> new title </title> <text> <p> new text </p> </text> </post>] 
>>> for post in soup('post'): 
...     print post.findChild('text') 
... 
<text> <p> new text </p> </text> 

一旦你在这个阶段得到它,你就可以用它做各种事情,这取决于你想要的方式。

>>> post = soup.find('post') 
>>> post 
<post id="100"> <title> new title </title> <text> <p> new text </p> </text> </post> 
>>> post_text = post.findChild('text') 
>>> post_text 
<text> <p> new text </p> </text> 

您可能想要去除 HTML。

>>> post_text.text 
u'new text' 

或者看看内容...

>>> post_text.renderContents() 
' <p> new text </p> '] 
>>> post_text.contents 
[u' ', <p> new text </p>, u' '] 

您可以做各种各样的事情。如果您更具体 - 特别是提供真实数据 - 它会有所帮助。

在操作树时,您也可以这样做。

>>> post 
<post id="100"> <title> new title </title> <text> <p> new text </p> </text> </post> 
>>> post.title  # Just as good as post.findChild('title') 
<title> new title </title> 
>>> post.title.extract()  # Throws it out of the tree and returns it but we have no need for it 
<title> new title </title> 
>>> post  # title is gone! 
<post id="100">  <text> <p> new text </p> </text> </post> 
>>> post.findChild('text').replaceWithChildren()  # Thrown away the <text> wrapping 
>>> post 
<post id="100">   <p> new text </p>  </post> 

所以,最后,你会得到这样的东西:

>>> from BeautifulSoup import BeautifulSoup 
>>> soup = BeautifulSoup(''' 
... <post id='100'> <title> new title 100 </title> <text> <p> new text 100 </p> </text> </post> 
... <post id='101'> <title> new title 101 </title> <text> <p> new text 101 </p> </text> </post> 
... <post id='102'> <title> new title 102 </title> <text> <p> new text 102 </p> </text> </post> 
... ''') 
>>> for post in soup('post'): 
...     post.title.extract() 
...     post.findChild('text').replaceWithChildren() 
...  
<title> new title 100 </title> 
<title> new title 101 </title> 
<title> new title 102 </title> 
>>> soup 
 
<post id="100">   <p> new text 100 </p>  </post> 
<post id="101">   <p> new text 101 </p>  </post> 
<post id="102">   <p> new text 102 </p>  </post>