python解析xml文件elementtree_Python(00):解析xml文件(sax、dom、ElementTree)和lxml...

一、Python对XML的解析

常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。

python有三种方法解析XML:SAX,DOM和ElementTree

1、DOM(Document Object Model)

DOM的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件。

由于DOM是将XML读取到内存,然后解析成一个树,如果要处理的XML文本比较大的话,就会很耗内存,所以DOM一般偏向于处理一些小的XML(如配置文件)比较快。

python中用xml.dom.minidom来解析xml文件。

from xml.dom.minidom importparse

DOMTree= parse(r'book.xml') #minidom解析器打开xml文档并将其解析为内存中的一棵树

booklist = DOMTree.documentElement #获取xml文档对象,就是拿到树的根

if booklist.hasAttribute('type'):print('Root element is', booklist.getAttribute('type')) #判断根节点booklist是否有type属性,有则获取并打印属性值

books = booklist.getElementsByTagName('book') #获取booklist对象中所有的book节点的list集合

print('book节点的个数为:', len(books))print('book节点的个数为:', books.length)for book inbooks:print("*******************book*******************")if book.hasAttribute('category'):print('category is', book.getAttribute('category'))#根据节点名title/author/pageNumber得到这些节点的集合list

title = book.getElementsByTagName('title')[0]

author= book.getElementsByTagName('author')[0]

pageNumber= book.getElementsByTagName('pageNumber')[0]print('title is', title.childNodes[0].data)print('author is', author.childNodes[0].data)print('pageNumber is', pageNumber.childNodes[0].data)

2、SAX(simple API for XML)

Python标准库中包含SAX解析器,SAX是用的是事件驱动模型,通过在解析XML过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。

解析的基本过程:

读到一个XML开始标签,就会开始一个事件,然后事件就会调用一系列的函数去处理一些事情,当读到一个结束标签时,就会触发另一个事件。所以,我们写XML文档如果有格式错误的话,解析就会出错。

这是一种流式处理,一边读一边解析,占用内存少。适用场景如下:

1、对大型文件进行处理;

2、只需要文件的部分内容,或者只需从文件中得到特定信息。

3、想建立自己的对象模型的时候。

fromxml.sax import *

classDengHandler(ContentHandler):defstartDocument(self):print("----开始解析xml文档----")defendDocument(self):print("----xml文档解析完毕----")defstartElement(self,name,attrs):if name == "author":print("名字:",attrs['name'],"日期:",attrs["birth"])

parse("deng.xml",DengHandler())

3、ElementTree(元素树)

ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

因DOM需要将XML数据映射到内存中的树,一是比较慢,二是比较耗内存;而SAX流式读取XML文件,比较快,占用内存少,但需要用户实现回调函数(handler),所以一般选用ElementTree(元素树)。

二、xml.etree.ElementTree解析XML

2

2008

141100

5

2011

59900

69

2011

13600

1、遍历和查找xml

xml协议在各个语言里的都是支持的,在python中可以用以下模块操作xml:

#print(root.iter('year')) #全文搜索#print(root.find('country')) #在root的子节点找,只找一个#print(root.findall('country')) #在root的子节点找,找所有

importxml.etree.ElementTree as ET

tree=ET.parse("xmltest.xml")

root=tree.getroot()print(root.tag)#遍历xml文档

for child inroot:print('========>', child.tag, child.attrib, child.attrib['name'])for i inchild:print(i.tag, i.attrib, i.text)#只遍历year 节点

for node in root.iter('year'):print(node.tag, node.text)

2、修改和删除节点

importxml.etree.ElementTree as ET

tree= ET.parse("xmltest.xml")

root=tree.getroot()#修改

for node in root.iter('year'):

new_year= int(node.text) + 1node.text=str(new_year)

node.set('updated', 'yes')

node.set('version', '1.0')

tree.write('test.xml')#删除node

for country in root.findall('country'):

rank= int(country.find('rank').text)if rank > 50:

root.remove(country)

tree.write('output.xml')

3、添加节点

#在country内添加(append)节点year2

importxml.etree.ElementTree as ET

tree= ET.parse("a.xml")

root=tree.getroot()for country in root.findall('country'):for year in country.findall('year'):if int(year.text) > 2000:

year2= ET.Element('year2')

year2.text= '新年'year2.attrib= {'update': 'yes'}

country.append(year2)#往country节点下添加子节点

tree.write('a.xml.swap')

4、自己创建xml文档

importxml.etree.ElementTree as ET

new_xml= ET.Element("namelist")

name= ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})

age= ET.SubElement(name, "age", attrib={"checked": "no"})

sex= ET.SubElement(name, "sex")

sex.text= '33'name2= ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})

age= ET.SubElement(name2, "age")

age.text= '19'et=ET.ElementTree(new_xml) #生成文档对象

et.write("test.xml", encoding="utf-8", xml_declaration=True)

ET.dump(new_xml)#打印生成的格式

三、lxml.etree解析XML(推荐)

lxml 是一种使用 Python 编写的库,可以迅速、灵活地处理 XML,支持 XPath。

lxml.etree和xml.etree.ElementTree两个的操作方式看起来差不多,但lxml要更好一些,使用更简洁。解析xml的时候,自动处理各种编码问题。而且它天生支持 XPath 1.0、XSLT 1.0、定制元素类。

不过,lxml不是Python自带的标准库。需要自己安装,如下方式安装:

$ pip install lxml

from lxml importetree

with open('./books.xml') as f:#print(f.read())

text =f.read()

html=etree.HTML(text.encode())#print(html)

print(html.tag)print(html.xpath('//title')) #从根节点向下找任意层中title的节点

print(html.xpath('//book//title'))print(html.xpath('//book[@id="bk102"]'))print(html.xpath('//book[@id]'))print(html.xpath('//@id')) #取回的是属性

print(html.xpath('//*[@id]'))print(html.xpath('//bookstore/book[1]'))print(html.xpath('//bookstore/book[1]/@id')) #['bk101']

print(html.xpath('//bookstore/book[last()]/@id')) #last()为最后一个节点

print(html.xpath('//*[contains(local-name(), "store")]')) #[]

#local-name()为当前标签名字

print(html.xpath('//bookstore/*')) #匹配根节点bookstore下的所有子节点,不递归;

print(html.xpath('//*[@*]')) #匹配所有有属性的节点

print(html.xpath('//@*')) #匹配所有属性

print(html.xpath('//book/title|//book/price')) #匹配book节点下title标签或prices标签

print(html.xpath('//book[position()=2]/@id')) #['bk102']

print(html.xpath('//book[price > 40]/@id'))print(html.xpath('//book[1]/text()')) #匹配第一个book节点下所有文本子节点

print(html.xpath('//book[1]//text()')) #匹配第一个book节点下所有文本节点

print(html.xpath('//*[contains(@class,"even")]')) #匹配属性class中包含even字符串的节点

可以使用 lxml 的 etree 库来进行爬取网站信息。

从豆瓣电影中提取“本周口碑榜”:

importrequestsfrom lxml import etree #lxml 是c语言的库,效率非常高

url= 'http://movie.douban.com'headers= {'User-agent': "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \

Chrome/55.0.2883.75 Safari/537.36"}

response= requests.get(url, headers=headers)

with response:if response.status_code == 200:

text=response.text

html=etree.HTML(text)print(html.tag)

titles= html.xpath('//div[@class="billboard-bd"]//a/text()')for title intitles:print(title)print("*********************")

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值