python解析html的库_用python解析html
python中,有三個(gè)庫(kù)可以解析html文本,HTMLParser,sgmllib,htmllib。他們的實(shí)現(xiàn)方法不通,但功能差不多。這三個(gè)庫(kù)中 提供解析html的類都是基類,本身并不做具體的工作。他們?cè)诎l(fā)現(xiàn)的元件后(如標(biāo)簽、注釋、聲名等),會(huì)調(diào)用相應(yīng)的函數(shù),這些函數(shù)必須重載,因?yàn)榛愔胁?作處理。
比如:
"""
AdviceThe IETF admonishes:
Be strict in what you send.
"""
如果對(duì)這個(gè)數(shù)據(jù)做處理,當(dāng)檢測(cè)到標(biāo)簽時(shí),對(duì)于HTMLParser,會(huì)調(diào)用handle_starttag函數(shù)。
下面具體介紹下幾個(gè)庫(kù)
1、HTMLParser
#------------------?HTMLParser_stack.py?------------------#
#--?coding:?GBK?--
import?HTMLParser,sys,os,string
html?=?"""
AdviceThe?IETF?admonishes:
Be?strict?in?what?you?send.
"""
tagstack?=?[]
class?ShowStructure(HTMLParser.HTMLParser):
def?handle_starttag(self,?tag,?attrs):?tagstack.append(tag)
def?handle_endtag(self,?tag):?tagstack.pop()
def?handle_data(self,?data):
if?data.strip():
for?tag?in?tagstack:?sys.stdout.write('/'+tag)
sys.stdout.write('?>>?%s/n'?%?data[:40].strip())
ShowStructure().feed(html)
此函數(shù)的輸出:
/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 >> .
對(duì)于一些網(wǎng)頁(yè),可能并沒(méi)有嚴(yán)格的開(kāi)始結(jié)束標(biāo)簽對(duì),這時(shí),我們可以去忽略一些標(biāo)簽??梢宰约簩憘€(gè)堆棧來(lái)處理這些標(biāo)簽。
#*---------------?TagStack?class?example?-----------------#
class?TagStack:
def?__init__(self,?lst=[]):?self.lst?=?lst
def?__getitem__(self,?pos):?return?self.lst[pos]
def?append(self,?tag):
#?Remove?every?paragraph-level?tag?if?this?is?one
if?tag.lower()?in?('p','blockquote'):
self.lst?=?[t?for?t?in?self.lst
if?t?not?in?('p','blockquote')]
self.lst.append(tag)
def?pop(self,?tag):
#?"Pop"?by?tag?from?nearest?pos,?not?only?last?item
self.lst.reverse()
try:
pos?=?self.lst.index(tag)
except?ValueError:
raise?HTMLParser.HTMLParseError,?"Tag?not?on?stack"
del?self.lst[pos]
self.lst.reverse()
tagstack?=?TagStack()
HTMLParser有個(gè)bug,就是不能處理中文屬性,比如說(shuō),如果網(wǎng)頁(yè)里有這么一段:
那么解析到這一行時(shí)就會(huì)出錯(cuò)。
錯(cuò)誤原因還是正則表達(dá)式惹的禍。
attrfind = re.compile(
r'/s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(/s*=/s*'
r'(/'[^/']*/'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$/(/)_#=~@]*))?')
attrfind 沒(méi)有匹配中文字符。
可以更改這個(gè)匹配已修正這個(gè)錯(cuò)誤。sgmllib則不存在這種錯(cuò)誤。
2、sgmllib
html格式為sgml格式的一個(gè)子集,所以sgml可以處理跟多的東西,下面通過(guò)一段代碼來(lái)示例sgmllib的用法。
#------------------?HTMLParser_stack.py?------------------#
#--?coding:?GBK?--
import?sgmllib,sys,os,string
html?=?"""Advice
The?IETF?admonishes:
Be?strict?in?what?you?send.
?我?
"""
os.chdir('d://python')
f=file('testboard.txt','r')
contest=f.read()
tagstack?=?[]
class?ShowStructure(sgmllib.SGMLParser):
def?handle_starttag(self,?tag,?method,attrs):?tagstack.append(tag)
def?handle_endtag(self,?tag):?tagstack.pop()
def?handle_data(self,?data):
if?data.strip():
for?tag?in?tagstack:?sys.stdout.write('/'+tag)
sys.stdout.write('?>>?%s/n'?%?data[:40].strip())
def?unknown_starttag(self,tag,attrs):
print?'start?tag:'
def?unknown_endtag(self,tag):
print?'end?tag:'+tag+'>'
def?start_lala(self,attr):
print?'lala?tag?found'
ShowStructure().feed(html)
輸出:
start tag:
start tag:
/lala >> Advice
end tag:
end tag:
start tag:
start tag:
/lala >> The
start tag:
/lala >> IETF admonishes:
start tag:
/lala >> Be strict in what you
start tag:
/lala >> send
end tag:
/lala >> .
end tag:
end tag:
end tag:
start tag:
start tag:
/lala >> ?
start tag:
end tag:
end tag:
end tag:
和HTMLParser一樣,如果要用sgmllib解析html,則要繼承sgmllib.SGMLParser類,此類里的函數(shù)都是空的,用戶需要重載它。這個(gè)類提供的功能是在特定情況下調(diào)用相應(yīng)的函數(shù)。
比如當(dāng)發(fā)現(xiàn)標(biāo)簽時(shí),如果并沒(méi)有定義 start_html(self,attr)函數(shù),則會(huì)調(diào)用unknown_starttag函數(shù),具體怎么處理則更具用戶。
sgml的標(biāo)簽是可以自定義的,比如自己定義了一個(gè)start_lala函數(shù),則就會(huì)處理標(biāo)簽。
有
個(gè)地方要說(shuō)明下,如果定義了start_tagname函數(shù),有定義了handle_starttag函數(shù),則函數(shù)只會(huì)運(yùn)行
handle_starttag函數(shù),start_tagname為空函數(shù)都沒(méi)有問(wèn)題,如果沒(méi)有定義handle_starttag函數(shù),則遇
到標(biāo)簽時(shí),會(huì)運(yùn)行start_tagname函數(shù)。如果沒(méi)有定義tagname的start函數(shù),則此標(biāo)簽為未知標(biāo)簽,調(diào)
用unknown_starttag函數(shù)
總結(jié)
以上是生活随笔為你收集整理的python解析html的库_用python解析html的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 设计模式(四)结构型模式
- 下一篇: python列表添加数字_Python-