本文共 4380 字,大约阅读时间需要 14 分钟。
python中,有三个库可以解析html文本,HTMLParser,sgmllib,htmllib。他们的实现方法不通,但功能差不多。这三个库中提供解析html的类都是基类,本身并不做具体的工作。他们在发现的元件后(如标签、注释、声名等),会调用相应的函数,这些函数必须重载,因为基类中不作处理。
比如:
"""<html><head><title>Advice</title></head><body>
<p>The <a href=" admonishes:<i>Be strict in what you <b>send</b>.</i></a></p><form><input type=submit > <input type=text name=start size=4></form></body></html>"""
如果对这个数据做处理,当检测到<html>标签时,对于HTMLParser,会调用handle_starttag函数。
下面具体介绍下几个库
此函数的输出:
/html/body/p >> The/html/body/p/a >> IETF admonishes:/html/body/p/a/i >> Be strict in what you/html/body/p/a/i/b >> send/html/body/p/a/i >> .
对于一些网页,可能并没有严格的开始结束标签对,这时,我们可以去忽略一些标签。可以自己写个堆栈来处理这些标签。
HTMLParser有个bug,就是不能处理中文属性,比如说,如果网页里有这么一段:
<input type=submit value=跳转到>
那么解析到这一行时就会出错。
错误原因还是正则表达式惹的祸。 attrfind = re.compile( r'/s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(/s*=/s*' r'(/'[^/']*/'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$/(/)_#=~@]*))?') attrfind 没有匹配中文字符。
可以更改这个匹配已修正这个错误。sgmllib则不存在这种错误。
输出:
start tag:<head>start tag:<title>/lala >> Adviceend tag:</title>end tag:</head>start tag:<body>start tag:<p>/lala >> Thestart tag:<a>/lala >> IETF admonishes:start tag:<i>/lala >> Be strict in what youstart tag:<b>/lala >> sendend tag:</b>/lala >> .end tag:</i>end tag:</a>end tag:</p>start tag:<form>start tag:<input>/lala >> ϒstart tag:<input>end tag:</form>end tag:</body>end tag:</lala>
和HTMLParser一样,如果要用sgmllib解析html,则要继承sgmllib.SGMLParser类,此类里的函数都是空的,用户需要重载它。这个类提供的功能是在特定情况下调用相应的函数。
比如当发现<html>标签时,如果并没有定义 start_html(self,attr)函数,则会调用unknown_starttag函数,具体怎么处理则更具用户。
sgml的标签是可以自定义的,比如自己定义了一个start_lala函数,则就会处理<lala>标签。
有个地方要说明下,如果定义了start_tagname函数,有定义了handle_starttag函数,则函数只会运行handle_starttag函数,start_tagname为空函数都没有问题,如果没有定义handle_starttag函数,则遇到<tagname>标签时,会运行start_tagname函数。如果没有定义tagname的start函数,则此标签为未知标签,调用unknown_starttag函数
转载地址:http://rjckb.baihongyu.com/