資料:https://docs.python.org/3/library/html.parser.html
python 自帶了一個類,叫 HTMLParser。
我們用的時候需要自己定義一個類,繼承自 HTMLParser 。然後重寫一部分方法。
下面是我們常用的解析html的方法,可以看到在 HTMLParser 裡面,這些方法內容都是空的,也就是如果我們要用某個方法,我們得自己再我們的類裡面重寫這個方法。具體的每個方法的使用方式參見下文。
# Overridable -- finish processing of start+end tag: <tag.../> def handle_startendtag(self, tag, attrs): self.handle_starttag(tag, attrs) self.handle_endtag(tag) # Overridable -- handle start tag def handle_starttag(self, tag, attrs): pass # Overridable -- handle end tag def handle_endtag(self, tag): pass # Overridable -- handle character reference def handle_charref(self, name): pass # Overridable -- handle entity reference def handle_entityref(self, name): pass # Overridable -- handle data def handle_data(self, data): pass # Overridable -- handle comment def handle_comment(self, data): pass # Overridable -- handle declaration def handle_decl(self, decl): pass # Overridable -- handle processing instruction def handle_pi(self, data): pass
使用
1. 簡單解析
from html.parser import HTMLParser class MyHTMLParser(HTMLParser): def handle_starttag(self, tag, attrs): print("Encountered a start tag:", tag) def handle_endtag(self, tag): print("Encountered an end tag :", tag) def handle_data(self, data): print("Encountered some data :", data) parser = MyHTMLParser() parser.feed('<html><head><title>Test</title></head><body><h1>Parse me!</h1></body></html>')
這裡寫了一個類 MyHTMLParse ,繼承自 HTMLParser。然後重寫了 handle_xxx方法。
然後只要呼叫該類的 feed() 方法,將html格式的資料傳進去,遇到特定的資料,就會自動觸發相應的方法。比如遇到<html>就會觸發handle_starttag()方法進行處理。
執行結果如下:
Encountered a start tag: html
Encountered a start tag: head
Encountered a start tag: title
Encountered some data : Test
Encountered an end tag : title
Encountered an end tag : head
Encountered a start tag: body
Encountered a start tag: h1
Encountered some data : Parse me!
Encountered an end tag : h1
Encountered an end tag : body
Encountered an end tag : html
2. 複雜解析
from html.parser import HTMLParser from html.entities import name2codepoint class MyHTMLParser(HTMLParser): def handle_starttag(self, tag, attrs): print("Start tag:", tag) for attr in attrs: print(" attr:", attr) def handle_endtag(self, tag): print("End tag :", tag) def handle_data(self, data): print("Data :", data) def handle_comment(self, data): print("Comment :", data) def handle_entityref(self, name): c = chr(name2codepoint[name]) print("Named ent:", c) def handle_charref(self, name): if name.startswith('x'): c = chr(int(name[1:], 16)) else: c = chr(int(name)) print("Num ent :", c) def handle_decl(self, data): print("Decl :", data) parser = MyHTMLParser()
1)解析文件型別申明
傳入html資料如下:
parser.feed('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">')
執行結果如下,可以看到會自動呼叫 handle_decl() 方法。
Decl : DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"
2) 解析屬性
傳入html資料如下:
parser.feed('<img src="python-logo.png" alt="The Python logo">')
執行結果如下,可以看到會自動呼叫 handle_starttag()方法。
Start tag: img attr: ('src', 'python-logo.png') attr: ('alt', 'The Python logo')
3)解析資料以及結束標籤
傳入html資料如下:
parser.feed('<style type="text/css">#python { color: green }</style>')
執行結果如下,可以看到會自動呼叫 handle_data() 以及 handle_endtag()方法。
Start tag: style attr: ('type', 'text/css') Data : #python { color: green } End tag : style
4)解析備註
傳入html資料如下:
parser.feed('<!-- a comment --><!--[if IE 9]>IE-specific content<![endif]-->')
執行結果如下,可以看到會自動呼叫 handle_comment()方法。
Comment : a comment Comment : [if IE 9]>IE-specific content<![endif]
5)解析實體字元
傳入html資料如下:
parser.feed('>>>')
在html語言中 ‘>’這個符號,實體名稱為 > , 實體編號為 >。這裡 >表示16進位制數字,3E轉化過來和62 是一致的。
執行結果如下,可以看到會自動呼叫 handle_entityref() 來處理 > ,然後呼叫 handle_charref()來處理 > 以及 >。
Named ent: > Num ent : > Num ent : >