Python学习笔记:常用内建模块7XML
前言
最近在學(xué)習(xí)深度學(xué)習(xí),已經(jīng)跑出了幾個模型,但Pyhton的基礎(chǔ)不夠扎實,因此,開始補習(xí)Python了,大家都推薦廖雪峰的課程,因此,開始了學(xué)習(xí),但光學(xué)有沒有用,還要和大家討論一下,因此,寫下這些帖子,廖雪峰的課程連接在這里:廖雪峰
Python的相關(guān)介紹,以及它的歷史故事和運行機制,可以參見這篇:python介紹
Python的安裝可以參見這篇:Python安裝
Python的運行模式以及輸入輸出可以參見這篇:Python IO
Python的基礎(chǔ)概念介紹,可以參見這篇:Python 基礎(chǔ)
Python字符串和編碼的介紹,可以參見這篇:Python字符串與編碼
Python基本數(shù)據(jù)結(jié)構(gòu):list和tuple介紹,可以參見這篇:Python list和tuple
Python控制語句介紹:ifelse,可以參見這篇:Python 條件判斷
Python控制語句介紹:循環(huán)實現(xiàn),可以參見這篇:Python循環(huán)語句
Python數(shù)據(jù)結(jié)構(gòu):dict和set介紹Python數(shù)據(jù)結(jié)構(gòu)dict和set
Python函數(shù)相關(guān):Python函數(shù)
Python高階特性:Python高級特性
Python高階函數(shù):Python高階函數(shù)
Python匿名函數(shù):Python匿名函數(shù)
Python裝飾器:Python裝飾器
Python偏函數(shù):Python偏函數(shù)
Python模塊:Python模塊
Python面向?qū)ο缶幊?#xff08;1):Python面向?qū)ο?
Python面向?qū)ο缶幊?#xff08;2):Python面向?qū)ο?#xff08;2)
Python面向?qū)ο缶幊?#xff08;3):Python面向?qū)ο?#xff08;3)
Python面向?qū)ο缶幊?#xff08;4):Pyhton面向?qū)ο?#xff08;4)
Python面向?qū)ο蟾呒壘幊?#xff08;上):Python面向?qū)ο蟾呒壘幊?#xff08;上)
Python面向?qū)ο蟾呒壘幊?#xff08;中上):Python面向?qū)ο蟾呒壘幊?#xff08;中上)
Python面向?qū)ο蟾呒壘幊?#xff08;中下):Python面向?qū)ο蟾呒壘幊?#xff08;中下)
Python面向?qū)ο蟾呒壘幊?#xff08;完):Python面向?qū)ο蟾呒壘幊?#xff08;完)
Python錯誤調(diào)試(起):Python調(diào)試:起
Python錯誤調(diào)試(承):Python調(diào)試:承
Python錯誤調(diào)試(轉(zhuǎn)):Python調(diào)試:轉(zhuǎn)
Python錯誤調(diào)試(合):python調(diào)試:合
Python文件IO編程:Python文件IO
Python文件IO編程2:Python文件IO2
Python文件IO編程3:PYthon文件IO3
Python進(jìn)程和線程(起):Python進(jìn)程和線程起
Python進(jìn)程和線程(承):Python進(jìn)程和線程承
Python進(jìn)程和線程(轉(zhuǎn)):Python進(jìn)程和線程轉(zhuǎn)
Python進(jìn)程和線程(合):Python進(jìn)程和線程合
Python正則表達(dá)式:Python正則表達(dá)式
Python學(xué)習(xí)筆記:常用內(nèi)建模塊1:Python學(xué)習(xí)筆記:常用內(nèi)建模塊1
Python學(xué)習(xí)筆記:常用內(nèi)建模塊2:Python學(xué)習(xí)筆記:常用內(nèi)建模塊2
Python學(xué)習(xí)筆記:常用內(nèi)建模塊3:Python學(xué)習(xí)筆記:常用內(nèi)建模塊3
Python學(xué)習(xí)筆記:常用內(nèi)建模塊4:Python學(xué)習(xí)筆記: 常用內(nèi)建模塊4
Python學(xué)習(xí)筆記:常用內(nèi)建模塊5:Python學(xué)習(xí)筆記: 常用內(nèi)建模塊5
Python學(xué)習(xí)筆記:常用內(nèi)建模塊6:Python學(xué)習(xí)筆記:常用內(nèi)建模塊6
目錄
- 前言
- 目錄
- XML
- DOM vs SAX
- 小結(jié)
- 練習(xí)
- HTMLParser
- 小結(jié)
- 練習(xí)
- example
XML
XML雖然比JSON復(fù)雜,在Web中應(yīng)用也不如以前多了,不過仍有很多地方在用,所以,有必要了解如何操作XML。
DOM vs SAX
操作XML有兩種方法:DOM和SAX。DOM會把整個XML讀入內(nèi)存,解析為樹,因此占用內(nèi)存大,解析慢,優(yōu)點是可以任意遍歷樹的節(jié)點。SAX是流模式,邊讀邊解析,占用內(nèi)存小,解析快,缺點是我們需要自己處理事件。
正常情況下,優(yōu)先考慮SAX,因為DOM實在太占內(nèi)存。
在Python中使用SAX解析XML非常簡潔,通常我們關(guān)心的事件是start_element,end_element和char_data,準(zhǔn)備好這3個函數(shù),然后就可以解析xml了。
舉個例子,當(dāng)SAX解析器讀到一個節(jié)點時:
<a href="/">python</a>會產(chǎn)生3個事件:
start_element事件,在讀取<a href="/">時;char_data事件,在讀取python時;end_element事件,在讀取</a>時。用代碼實驗一下:
from xml.parsers.expat import ParserCreateclass DefaultSaxHandler(object):def start_element(self, name, attrs):print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))def end_element(self, name):print('sax:end_element: %s' % name)def char_data(self, text):print('sax:char_data: %s' % text)xml = r'''<?xml version="1.0"?> <ol><li><a href="/python">Python</a></li><li><a href="/ruby">Ruby</a></li> </ol> '''handler = DefaultSaxHandler() parser = ParserCreate() parser.StartElementHandler = handler.start_element parser.EndElementHandler = handler.end_element parser.CharacterDataHandler = handler.char_data parser.Parse(xml)需要注意的是讀取一大段字符串時,CharacterDataHandler可能被多次調(diào)用,所以需要自己保存起來,在EndElementHandler里面再合并。
除了解析XML外,如何生成XML呢?99%的情況下需要生成的XML結(jié)構(gòu)都是非常簡單的,因此,最簡單也是最有效的生成XML的方法是拼接字符串:
L = [] L.append(r'<?xml version="1.0"?>') L.append(r'<root>') L.append(encode('some & data')) L.append(r'</root>') return ''.join(L)如果要生成復(fù)雜的XML呢?建議你不要用XML,改成JSON。
小結(jié)
解析XML時,注意找出自己感興趣的節(jié)點,響應(yīng)事件時,把節(jié)點數(shù)據(jù)保存起來。解析完畢后,就可以處理數(shù)據(jù).
練習(xí)
請利用SAX編寫程序解析Yahoo的XML格式的天氣預(yù)報,獲取天氣預(yù)報:
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20%3D%202151330&format=xml
HTMLParser
如果我們要編寫一個搜索引擎,第一步是用爬蟲把目標(biāo)網(wǎng)站的頁面抓下來,第二步就是解析該HTML頁面,看看里面的內(nèi)容到底是新聞、圖片還是視頻。
假設(shè)第一步已經(jīng)完成了,第二步應(yīng)該如何解析HTML呢?
HTML本質(zhì)上是XML的子集,但是HTML的語法沒有XML那么嚴(yán)格,所以不能用標(biāo)準(zhǔn)的DOM或SAX來解析HTML。
好在Python提供了HTMLParser來非常方便地解析HTML,只需簡單幾行代碼:
from html.parser import HTMLParser from html.entities import name2codepointclass MyHTMLParser(HTMLParser):def handle_starttag(self, tag, attrs):print('<%s>' % tag)def handle_endtag(self, tag):print('</%s>' % tag)def handle_startendtag(self, tag, attrs):print('<%s/>' % tag)def handle_data(self, data):print(data)def handle_comment(self, data):print('<!--', data, '-->')def handle_entityref(self, name):print('&%s;' % name)def handle_charref(self, name):print('&#%s;' % name)parser = MyHTMLParser() parser.feed('''<html> <head></head> <body> <!-- test html parser --><p>Some <a href=\"#\">html</a> HTML tutorial...<br>END</p> </body></html>''')feed()方法可以多次調(diào)用,也就是不一定一次把整個HTML字符串都塞進(jìn)去,可以一部分一部分塞進(jìn)去。
特殊字符有兩種,一種是英文表示的?,一種是數(shù)字表示的?,這兩種字符都可以通過Parser解析出來。
小結(jié)
利用HTMLParser,可以把網(wǎng)頁中的文本、圖像等解析出來。
練習(xí)
找一個網(wǎng)頁,例如https://www.python.org/events/python-events/,用瀏覽器查看源碼并復(fù)制,然后嘗試解析一下HTML,輸出Python官網(wǎng)發(fā)布的會議時間、名稱和地點。
example
# -*- coding: utf-8 -*- # @Time : 2018/6/16 16:03 # @Author : mike # @Email : jianlongfan@gmail.com # @File : ex_HTMLPASER_2.py # @Software: PyCharmfrom html.parser import HTMLParser from html.entities import name2codepoint from urllib import request import reclass MyHTMLParser(HTMLParser):a_t1 = Falsea_t2 = Falsea_t3 = Falsedef __init__(self):HTMLParser.__init__(self)self.information = []self.information_all = {}def handle_starttag(self, tag, attrs):def _attr(attrlist, attrname):for attr in attrlist:if attr[0] == attrname:return attr[1]return Noneif tag=="time" :self.a_t1 = Trueelif tag=="span" and _attr(attrs, 'class')=="event-location":self.a_t2 = Trueelif tag=="h3" and _attr(attrs, 'class')=="event-title":self.a_t3 = Truedef handle_data(self, data):if self.a_t1 is True:if re.match(r'^\s\d{4}', data):self.information.append(dict(year=data))else:self.information.append(dict(day=data))elif self.a_t2 is True:self.information.append(dict(event_location=data))elif self.a_t3 is True:self.information.append(dict(event_title=data))def handle_endtag(self, tag):if tag == "time":self.a_t1 = Falseelif tag =="span":self.a_t2 = Falseelif tag == "h3":self.a_t3 = Falsedef parseHTML(html_str):parser = MyHTMLParser()parser.feed(html_str)for i, val in enumerate(parser.information):i += 1print(val)if i%4==0:print('--------------------------------------------')URL = 'https://www.python.org/events/python-events/' with request.urlopen(URL, timeout=4) as f:data = f.read()parseHTML(data.decode('utf-8'))總結(jié)
以上是生活随笔為你收集整理的Python学习笔记:常用内建模块7XML的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php cgi模块,PHP5模块和CGI
- 下一篇: curl post 日志_curl命令发