一.簡介
XML是由萬維網聯盟(W3C)創建的標記語言,被設計用來傳輸和存儲數據,XML可以自行定義標簽,具有自我描述性,其設計宗旨是傳輸數據,而非顯示數據。Python自帶XML模塊,方便開發者解析XML數據。XML模塊中包含了廣泛使用的API接口--------SAX和DOM等。另外,lxml解析庫同樣支持HTML和XML的解析,而且支持XPath解析方式。總的來說,Python解析XML的常用方法有以下幾種:
1、DOM解析,xml.dom.*模塊。
2、SAX解析,xml.sax.*模塊。
3、ET解析,xml.etree.ElementTree模塊。
4、lxml解析並結合XPath提取元素。
由於第四種方法是我們在網絡爬蟲時解析html經常用到的,也是我們較為熟悉的,所以首先嘗試用它來解析xml,另外三種方法也將陸續介紹。
二. 使用lxml解析xml文件
1、導入相關標准庫
from lxml import etree
2、定義解析器
parser = etree.XMLParser(encoding = "utf-8")
3、使用解析器parser解析XML文件
#傳入兩個參數,第一個參數是文件名,第二個參數是解析器。 tree = etree.parse(r"douban.xml",parser = parser) #查看解析出的tree的內容 print(etree.tostring(tree,encoding = 'utf-8').decode('utf-8'))
4、結合xpath提取XML文件中的信息
from lxml import etree # 使用lxml解析xml文件 parser = etree.HTMLParser(encoding="utf-8") tree = etree.parse("douban.xml", parser=parser) a = tree.xpath('//loc/text()') print(a)
方法二:直接使用html解析器就能解析xml文件
from lxml import etree with open('douban.xml', 'r',encoding='utf-8') as reader: xmlstr = reader.read() tree = etree.HTML(xmlstr) print(tree.xpath('//loc/text()'))
這種方法容易遇到這樣的錯誤:
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.
原因是lxml 不支持解析帶有encoding 聲明的字符串,例如 xml中以encoding="UTF-8"
開頭,需要轉換成bytes
類型。
我們看看douban.xml文件,真的帶有編碼聲明的:
解決方法:
1.把xml文件的首行編碼聲明去掉就可以了
2.傳入構造含數據的不要用字符串,而是二進制內容:
如:
from lxml import etree #以二進制打開文件,傳進去bytes類型的數據 with open('douban.xml', 'rb') as reader: xmlstr = reader.read() tree = etree.HTML(xmlstr) print(tree.xpath('//loc/text()'))
三.使用xml.dom.minidom解析xml
import xml.dom.minidom def readXML(path): urls = [] domTree = xml.dom.minidom.parse(path) # 文檔根元素 rootNode = domTree.documentElement print(rootNode.nodeName) # 所有loc節點 locs = rootNode.getElementsByTagName("loc") print(locs) for loc in locs: url = loc.childNodes[0].data urls.append(url) return urls path = "./sitemap.xml" readXML(path)