用python解析html

<p>用python解析html<br>
rurutia posted @ 2007年5月13日 10:07 in 编程笔记 with tags python html sgml , 23943 阅读<br><br>
因为要用python做学校网络的认证程序,需要解析服务器传回的html,本以为会像javascript里操作DOM那样简单,结果发现并不是这样,被搞了一下。<br><br>
其实python里面有xml.dom模块,但是这次却不能用,为啥呢?因为服务器传回的html从xml角度看不是良构的,没有闭合的标签、没有被注释掉的javascript和css,xml.dom没法处理,这个时候要用sgmllib。<br><br>
sgmllib.py 包含一个重要的类: SGMLParser。SGMLParser 将 HTML 分解成有用的片段, 比如开始标记和结束标记。一旦它成功地分解出某个数据为一个有用的片段,它会根据 所发现的数据,调用一个自身内部的方法。为了使用这个分析器,您需要子类化 SGML- Parser类,并且覆盖这些方法。<br><br>
SGMLParser类里面包含了很多内部方法,开始读取html后,遇到相应的数据就会调用其对应的方法,最重要的方法有三个:<br><br>
* start_tagname(self, attrs)<br>
* end_tagname(self)<br>
* handle_data(self, text)<br><br>
tagname就是标签名称,比如当遇到<pre>,就会调用start_pre,遇到</pre>,就会调用 end_pre,attrs即为标签的参数,以[(attribute, value), (attribute, value), ...]的形式传回,我们要做的就是在其子类重载自己感兴趣标签对应的函数。<br><br>
一个经典的例子:<br><br>
1.<br>
from sgmllib import SGMLParser<br>
2.<br>
class URLLister(SGMLParser):<br>
3.<br>
self.urls = []<br>
4.<br>
def start_a(self, attrs): <br>
5.<br>
href = [v for k, v in attrs if k=='href'] <br>
6.<br>
if href:<br>
7.<br>
self.urls.extend(href)<br><br>
顾名思义,这个类的作用就是把html中的所有连接(<a>标签)中的地址(href属性的值)提取出来,放到一个list里面,很实用的功能。^^<br><br>
比如处理下面的html:<br>
<tr><br>
<td height="207" colspan="2" align="left" valign="top" class="normal"><br>
<p>Damien Rice - 《0》 </p><br>
<a href="http://galeki.xy568.net/music/Delicate.mp3">1. Delicate</a><br /><br>
<a href="http://galeki.xy568.net/music/Volcano.mp3">2. Volcano</a><br /><br>
<a href="http://galeki.xy568.net/music/The Blower's Daughter.mp3">3. The Blower's Daughter</a><br /><br>
<a href="http://galeki.xy568.net/music/Cannonball.mp3">4. Cannonball </a><br /><br>
<a href="http://galeki.xy568.net/music/Older Chests.mp3">5. Order Chests</a><br /><br>
<a href="http://galeki.xy568.net/music/Amie.mp3">6. Amie</a><br /><br>
<a href="http://galeki.xy568.net/music/Cheers Darlin'.mp3">7. Cheers Darling</a><br /><br>
<a href="http://galeki.xy568.net/music/Cold Water.mp3">8. Cold water</a><br /><br>
<a href="http://galeki.xy568.net/music/I Remember.mp3">9. I remember</a><br /><br>
<a href="http://galeki.xy568.net/music/Eskimo.mp3">10. Eskimo</a></p><br>
</td><br>
</tr><br><br>
很乱对吧?下面让举个例子利用URLLister提取出上面mp3下载的地址:<br><br>
1.<br>
date="上面那一堆…………"<br>
2.<br>
lister=URLLister()<br>
3.<br>
lister.feed(date)<br><br>
用feed()把要处理的html传递给对象实体,然后我们来看看处理结果:<br><br>
1.<br>
print lister.urls <br><br>
显示:<br>
['http://galeki.xy568.net/music/Delicate.mp3',<br>
'http://galeki.xy568.net/music/Volcano.mp3',<br>
"http://galeki.xy568.net/music/The Blower's Daughter.mp3",<br>
'http://galeki.xy568.net/music/Cannonball.mp3',<br>
'http://galeki.xy568.net/music/Older Chests.mp3',<br>
'http://galeki.xy568.net/music/Amie.mp3',<br>
"http://galeki.xy568.net/music/Cheers Darlin'.mp3",<br>
'http://galeki.xy568.net/music/Cold Water.mp3',<br>
'http://galeki.xy568.net/music/I Remember.mp3',<br>
'http://galeki.xy568.net/music/Eskimo.mp3']<br><br>
好了,是不是很方便?现在我们知道了如何处理标签中的属性,那么如何处理标签包含的文字呢?就是上面列出的handle_data(self, text),当遇到标签内的内容,就会调用这个函数,传入的text自然就是标签内的内容了,不过,如何筛选出感兴趣标签内的内容呢?比如上面歌曲的列 表,这时候就要配合start_tagname、end_tagname,用做标记的方法来达到这个目的:<br><br>
1.<br>
class ListName(SGMLParser):<br>
2.<br>
is_a=""<br>
3.<br>
name=[]<br>
4.<br>
def start_a(self, attrs):<br>
5.<br>
self.is_a=1<br>
6.<br>
def end_a(self):<br>
7.<br>
self.is_a=""<br>
8.<br>
def handle_data(self, text):<br>
9.<br>
if self.is_a:<br>
10.<br>
self.name.append(text)<br><br>
这里添加了一个is_a标记,再在handle_date中添加一个if,也就是说,仅仅在a标签内,才会把标签里的内容加到name[]里去。<br><br>
看看结果:<br><br>
1.<br>
listname=ListName()<br>
2.<br>
listname.feed(date)<br>
3.<br>
print listname.name<br><br>
显示:<br>
['1.Delicate', '2.Volcano', "3.The Blower's Daughter",<br>
'4.Cannonball ', '5.Order Chests', '6.Amie',<br>
'7.Cheers Darling', '8.Cold water', '9.I remember',<br>
'10.Eskimo']<br><br>
OK,搞定~<br><br>
SGMLParser内置的方法不仅仅只有这三个,还有处理注释的handle_comment,还有处理声明的handle_decl等等等等,不过使用方法和上面的基本相同,不再多写了。</p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值