python SGMLParser模組處理html解析非常的方便,它將HTML 處理分成三步:將 HTML 分解成它的組成片段,對片段進行加工,接著將片段再重新合成 HTML。第一步是通過 sgmllib.py 來完成的,它是標準 Python 庫的一部分。
理解本章的關鍵是要知道 HTML 不只是文本,更是結構化文本。這種結構來源於開始與結束標記的或多或少分級序列。通常您並不以這種方式處理 HTML,而是以文本方式 在一個文本編輯中對其進行處理,或以可視的方式 在一個瀏覽器中進行瀏覽或頁面編輯工具中進行編輯。sgmllib.py 表現出了HTML 的結構。
sgmllib.py 包含一個重要的類:SGMLParser。SGMLParser 將 HTML分解成有用的片段,比如開始標記和結束標記。在它成功地分解出某個資料為一個有用的片段後,它會根據所發現的資料,調用一個自身內部的方法。為了使用這個分析器,您需要子類化 SGMLParser 類,並且覆蓋這些方法。這就是當我說它表示了 HTML 結構 的意思:HTML的結構決定了方法調用的次序和傳給每個方法的參數。
SGMLParser 將 HTML 分析成 8 類資料,然後對每一類調用單獨的方法:
開始標記 (Start tag)
是開始一個塊的 HTML 標籤,像 、、 或
等,或是一個獨一的標記,
像
或
等。當它找到一個開始標記 tagname,
SGMLParser 將尋找名為 start_tagname 或 do_tagname 的方法。
例如,當它找到一個 標記,它將尋找一個 start_pre 或 do_pre 的方法。
如果找到了,SGMLParser 會使用這個標記的屬性列表來調用這個方法;
否則,它用這個標記的名字和屬性列表來調用 unknown_starttag 方法。
結束標記 (End tag)
是結束一個塊的 HTML 標籤,像 、、 或
等。
當找到一個結束標記時,SGMLParser 將尋找名為 end_tagname 的方法。
如果找到,SGMLParser 調用這個方法,否則它使用標記的名字來調用 unknown_endtag 。
字元引用 (Character reference)
用字元的十進位或等同的十六進位來表示的逸出字元,
像 。當找到,SGMLParser 使用十進位或等同的十六進位字元文本來調用 handle_charref 。
實體引用 (Entity reference)
HTML 實體,像 。當找到,SGMLParser 使用 HTML 實體的名字來調用 handle_entityref 。
注釋 (Comment)
HTML 注釋,包括在 <!-- ... -->之間。當找到,SGMLParser 用注釋內容來調用 handle_comment。
處理指示 (Processing instruction)
HTML 處理指示,包括在 之間。當找到,SGMLParser 用處理指示內容來調用 handle_pi。
聲明 (Declaration)
HTML 聲明,如 DOCTYPE,包括在 <!-- ... -->之間。當找到,SGMLParser 用聲明內容來調用 handle_decl。
文本資料 (Text data)
文字區塊。不滿足其它 7 種類別的任何東西。當找到,SGMLParser 用文本來調用 handle_data。
重要
Python 2.0 存在一個 bug,即 SGMLParser 完全不能識別聲明 (handle_decl 永遠不會調用),
這就意味著 DOCTYPE 被靜靜地忽略掉了。這個錯誤在 Python 2.1 中改正了。
sgmllib.py 所附帶的一個測試套件舉例說明了這一點。您可以運行 sgmllib.py,
在命令列下傳入一個 HTML 檔案的名字,然後它會在分析標記和其它元素的同時將它們列印出來。
它的實現是通過子類化 SGMLParser 類,然後定義 unknown_starttag,unknown_endtag,handle_data
和其它方法來實現的。這些方法簡單地列印出它們的參數。
如果要詳細的瞭解python SGMLParser的用法的話,可以看看python SGMLParser
的文檔,
下面放上個我用python SGMLParsr寫的例子,希望對大家有協助:
#encoding=utf-8
#@description:baidutiba content
import sys
import re
import httplib
import urllib
from sgmllib import SGMLParser
class BaidutiebaParser(SGMLParser):
'''在百度貼吧裡採集相應的關鍵字的標題'''
def reset(self):
SGMLParser.reset(self)
self.info = []#
self.q_check = 0
self.num = 0
self.strcontent = ''
def start_td(self, tag):
'''匹配 標籤'''
if len(tag)!=0 and tag[0][1] == 's':
self.num = self.num + 1
self.q_check = 1
def handle_data(self, text):
'''處理文本'''
txt = text.strip()
if txt and self.q_check:
for i in checklist:
pipei = r'%s' % str(i)#在要匹配的資訊裡找到和關鍵字匹配
check_pan = re.compile(pipei)
if check_pan.search(txt) is not None:
self.info.append(txt)
else:
continue
self.strcontent = '$|$'.join(self.info)
def end_td(self):
'''匹配'''
self.q_check = 0
############################################配置資訊#############################
keylist = ['旅遊']#貼吧名稱
checklist = ['張家界','韓國']#要查詢的關鍵字
content = {}#採集內容
for m in keylist:
page = 0
keyword = urllib.quote(m.decode('utf-8').encode('gbk'))
for i in xrange(10):
url = '''http://tieba.baidu.com/f?z=0&ct=318767104&lm=11&sc=0&rn=50&tn=baiduKeywordSearch&rs3=0&rs4=0&word=%s&pn=%s''' % (str(keyword),str(page))
data = urllib.urlopen(url).read()
data = unicode(data, 'gbk').encode('utf-8')
parser = BaidutiebaParser()
parser.feed(data)
content[i+1] = parser.strcontent
page = page + 50
for k in content.keys():
print k
print content[k]
如果你對python queue模組
也感興趣的話,可以看看!
上面的例子也用到了python 字串替換
的一些方法。
作者:老王@python
python教程
老王python,提供pythn相關的python教程和python下載
,希望大家能夠喜歡