在 Python SGMLParser 中,无法解析没有空块的“<br/>”但是“<br />”

In Python SGMLParser, can't parse '<br/>' without empty block but '<br />'

在 Python SGMLParser 中,我无法解析没有空块的 '<br/>' 但 '<br />'.

我可以 运行 此代码成功解析 html,但是如果我将标签从“<br />”更改为“<br/>”,就像删除空块,结果我无法成功解析 html。

除了更换标签,还有什么解决方法吗?

成功范例.

# coding=utf-8  
from sgmllib import SGMLParser #get SGML

class ListName(SGMLParser):#parser class
    def reset(self):
        self.is_a = False #get <a></a>
        self.name=[] #get text
        SGMLParser.reset(self)
    def start_a(self,attrs):
        self.is_a = True

    def end_a(self):
        self.is_a = False

    def handle_data(self,data):
        if self.is_a:
            self.name.append(data)

if __name__ == '__main__':
    urls='''
    <tr>
<td height="207" colspan="2" align="left" valign="top" class="normal">
<p>Damien Rice - 《0》 </p>
<a href="http://galeki.xy568.net/music/Delicate.mp3">1. Delicate</a><br />
<a href="http://galeki.xy568.net/music/Volcano.mp3">2. Volcano</a><br />
<a href="http://galeki.xy568.net/music/The Blower's Daughter.mp3">3. The Blower's Daughter</a><br />
<a href="http://galeki.xy568.net/music/Cannonball.mp3">4. Cannonball </a><br />
<a href="http://galeki.xy568.net/music/Older Chests.mp3">5. Order Chests</a><br />
<a href="http://galeki.xy568.net/music/Amie.mp3">6. Amie</a><br />
<a href="http://galeki.xy568.net/music/Cheers Darlin'.mp3">7. Cheers Darling</a><br />
<a href="http://galeki.xy568.net/music/Cold Water.mp3">8. Cold water</a><br />
<a href="http://galeki.xy568.net/music/I Remember.mp3">9. I remember</a><br />
<a href="http://galeki.xy568.net/music/Eskimo.mp3">10. Eskimo</a></p>
</td>
</tr>
    '''
listname=ListName() #init parser
listname.feed(urls) #run parser
print listname.name
listname.close()

结果是:

['1.精致','2。火山',“3。鼓风机的女儿”,'4。炮弹','5。订购宝箱','6。艾米','7。干杯亲爱的','8。冷水','9。我记得','10。爱斯基摩人']

错误示例:

# coding=utf-8  
from sgmllib import SGMLParser #get SGML

class ListName(SGMLParser):#parser class
    def reset(self):
        self.is_a = False #get <a></a>
        self.name=[] #get text
        SGMLParser.reset(self)
    def start_a(self,attrs):
        self.is_a = True

    def end_a(self):
        self.is_a = False

    def handle_data(self,data):
        if self.is_a:
            self.name.append(data)

if __name__ == '__main__':
    urls='''
    <tr>
<td height="207" colspan="2" align="left" valign="top" class="normal">
<p>Damien Rice - 《0》 </p>
<a href="http://galeki.xy568.net/music/Delicate.mp3">1. Delicate</a><br/>
<a href="http://galeki.xy568.net/music/Volcano.mp3">2. Volcano</a><br/>
<a href="http://galeki.xy568.net/music/The Blower's Daughter.mp3">3. The Blower's Daughter</a><br/>
<a href="http://galeki.xy568.net/music/Cannonball.mp3">4. Cannonball </a><br/>
<a href="http://galeki.xy568.net/music/Older Chests.mp3">5. Order Chests</a><br/>
<a href="http://galeki.xy568.net/music/Amie.mp3">6. Amie</a><br/>
<a href="http://galeki.xy568.net/music/Cheers Darlin'.mp3">7. Cheers Darling</a><br/>
<a href="http://galeki.xy568.net/music/Cold Water.mp3">8. Cold water</a><br/>
<a href="http://galeki.xy568.net/music/I Remember.mp3">9. I remember</a><br/>
<a href="http://galeki.xy568.net/music/Eskimo.mp3">10. Eskimo</a></p>
</td>
</tr>
    '''
listname=ListName() #init parser
listname.feed(urls) #run parser
print listname.name
listname.close()

结果是:

['1.精致']

可能 <br/> 位被解析为 启用网络的开始标记

SGML 有很多快捷方式 ('minimizations'),可以让您省略部分语法。 NET,对于 'null end tag',就是其中之一;这是一种避免完全编写结束标记并改用斜杠的方法。对于example,在SGML中,写作

<ISBN/0 201 17535 5/

等同于写

<ISBN>0 201 17535 5</ISBN>

将错误示例中的所有 <br/> 替换为 <br// 即可得到预期结果。

就是说,您的输入看起来几乎是有效的 HTML,而不是 SGML - 您是否考虑过使用 HTML 或 XML 解析器?例如,使用 Beautiful Soup:

from bs4 import BeautifulSoup
urls = ...
soup = BeautifulSoup(urls, "html.parser")
print([a.get_text() for a in soup.find_all('a')])