python用ElemenTree快速高效的解析xml
python解析xml有很多种方法,比较流行的由SAX,DOM和ElementTree,简要介绍一下这几种方法的异同:
方法 | 特点 |
SAX | SAX解析通过流模式在解析XML的过程中触发对应的事件(start_element、char_data、end_element)并调用用户定义的回调函数来处理XML文件。 |
DOM | DOM 将XML数据在内存中解析成一个树,通过对树的操作来操作XML,占用内存大,解析速度较慢,优点是可以任意遍历树的节点。 |
ElementTree | ElementTree 类似一个轻量级的DOM |
- xml是什么?
xml是一种固有的分层数据格式,最自然的代表他的方式就是使用一棵树。xml.etree.ElementTree有两个类用于将xml文档表示为树,并且Element代表树的单个节点。与整个xml文档的交互是在ElementTree级别上的完成的,与单个xml元素及其子元素的交互是在Element级别上完成的。 - 解析xml
巧妇难为无米之炊,首先我们准备一个xml文档作为示例数(这是我爬虫的一个xml文件,我直接用这个文档为大家演示里边的信息,大家可以自动忽略):- <?xml version="1.0" encoding="UTF-8"?>
- <rules>
- <rule type="base" name="iaaf" allow_domains="iaaf.org" >
- <urls>
- <host_url>https://www.iaaf.org</host_url>
- <start_urls>https://www.iaaf.org/news</start_urls>
- <urllist pagestep="12" pages="1000" regex=" \'Articleurl\':\'(.*?)\'">
- <next_page>https://www.iaaf.org/data/news/typegroup/?take=12&skip={}</next_page>
- </urllist>
- </urls>
- <xpath>
- <title>//div[@id="news"]/div/div/h1[@itemprop="name"]/text()</title>
- <time>//div[@id="news"]/div/div/span/span[@itemprop="datePublished"]/text()</time>
- <type>//div[@id="news"]/div/div/span/span[@class="_label type"]/a/text()</type>
- <publish>//div[@id="news"]/div[1]/div[3]/span/span[@class="_label location"]/text()</publish>
- <html regexexclude="<ul class='col-md-12 prev-next'.*?</ul>">//div[@id="news"</html>
- <text>//div[@id="news"]/div/div/article[@itemprop="articleBody"]/p/text()</text>
- <imglink>//div[@id="news"]/div/div/ul/li/picture/img/@src | //div[@id="news"]/div/div/ul/li/picture/source/@srcset</imglink>
- <filelink></filelink>
- </xpath>
- </rule>
- <rule type="base" name="mp" allow_domains="kuaizhan.com" >
- <urls>
- <host_url>https://482809.kuaizhan.com</host_url>
- <start_urls>https://482809.kuaizhan.com/</start_urls>
- <urllist pagestep="1" pages="1000" regex="href=\'(.*?)\'">
- <next_page>https://www.kuaizhan.com/post/ajax-postlist?site_id=4216466368&param=a891b9bfac46d41ebace9eccf88f5bbb&cur_page={}</next_page>
- </urllist>
- </urls>
- <xpath>
- <title>//div[@id="page-content"]/div/div[@class="mod-title t0 "]/h2/text()</title>
- <time>//div[@id="page-content"]/div/div/span[@class="time"]/text()</time>
- <type>//div[@id="news"]/div/div/span/span[@class="_label type"]/a/text()</type>
- <publish>/html/body/div/div/div[@class="cell site-title"]/div/a/p/text()</publish>
- <html>//div[@id="page-content"]/div[@class="mod mod-layout_floor article-hd"] | //div[@id="page-content"]/div/div/div[@class="mod mod-html"]</html>
- <text>//div[@id="page-content"]/div/div/div/div[@class="mp-content"]/p/span/text()</text>
- <imglink>//div[@id="page-content"]/div/div/div/div[@class="mp-content"]/p/img/@src</imglink>
- <filelink></filelink>
- </xpath>
- </rule>
- <rule type="crawl" name="athletics" allow_domains="athletics.org.cn" >
- <urls>
- <host_url/>
- <start_urls>http://www.athletics.org.cn</start_urls >
- <urllist list_url=".*/list.html" allow_url=".*/[0-9]{4}-[0-9]{2}-[0-9]{2}/[0-9]*?\.html">
- <next_page>//div[@class="nav styfff fl clear"]/ul/li/a | //div[@class="wjxz styff"]/ul/li/a</next_page>
- </urllist >
- </urls>
- <xpath>
- <title>//div[@class="main"]/div[@class="atitle"]/text() | //div[@class="main"]/div[@class="atitle"]/font/text()</title>
- <time>//div[@class="main"]/div[@class="a01 sty999"]/span/text()</time>
- <type>//div[@class="wei"]/a[2]/text()</type>
- <publish>//div[@class="main"]/div[@class="a01 sty999"]/a/text()</publish>
- <html>//div[@class="main"]</html>
- <text>//div[@class="main"]/div[@class="atext"]/p/text()</text>
- <imglink>//div[@class="main"]/div[@class="atext"]/p/img/@src</imglink>
- <filelink>//div[@class="main"]/div[@class="atext"]/p/a/@href</filelink>
- </xpath>
- </rule>
- </rules>
- <!--
- < < 小于号
- > > 大于号
- & & 和
- ' ' 单引号
- " " 双引号
- -->
注意:你如果自己写的xml文档,则必须保证xml文档格式的正确性,大家看到上述xml中的最后写着转义符的注释,在xml编写中往往大家忽略了转义符而导致xml文档格式不正确。如果你的xml格式不正确,用ElementTree解析时会报not well-formed (invalid token): line 20, column 65的错误,如果大家无法判断xml是否格式正确,大家可以通过vs编写会提示你的xml的格式的错误,你也可以通过ie打开你的xml,查看xml格式是否正常。这里不多做介绍。
有了xml文件,首先我们需要将xml文件导入数据:- import xml.etree.ElementTree as ET
- import logging
- def parsexml(xmlpath):
- try:
- tree=ET.parse(xmlpath)
- except Exception as e:
- logging.error('cannot parse file %s,error code:%s',xmlpath,e)
你也可以从字符创中直接读取数据:
- import xml.etree.ElementTree as ET
- import logging
- def parsexml(str)
- try:
- root=ET.fromstring(str)
- except Exception as e:
- loggging.error('cannot parse str ,error code:%s',e)
fromestring()将xml从一个字符串直接解析为一个Element,所以上边代码写的是root,即为跟元素。而读取xml文件的话则会解析为一棵树,所以用tree表示。
那么接下来我们就用ET来把上边展示的xml的所有数据都解析出来并输出,代码如下:- import xml.etree.ElementTree as ET
- import os
- import logging
- def parsexml(xmlpath):
- try:
- tree=ET.parse(xmlpath)
- root=tree.getroot()
- for child in root:
- print(child.tag,child.attrib)
- print('-----------------------------------------------')
- for rule in root.findall('rule'):
- type=rule.get('type')
- name=rule.get('name')
- allow_domains=rule.get('allow_domains')
- print(type,name,allow_domains)
- urls=rule.find('urls')
- host_url=urls.find('host_url').text
- start_urls=urls.find('start_urls').text
- print(host_url,start_urls)
- urllist=urls.find('urllist')
- pagestep=urllist.get('pagestep')
- pages=urllist.get('pages')
- regex=urllist.get('regex')
- next_page=urllist.find('next_page').text
- print(pagestep,pages,regex,next_page)
- xpath = rule.find('xpath')
- title=xpath.find('title').text
- time=xpath.find('time').text
- type=xpath.find('type').text
- print(title,time,type)
- except Exception as e:
- logging.error('Error:cannot parse file:%s',e)
- if __name__=='__main__':
- xmlpath=os.getcwd()+'\\rules.xml'
- parsexml(xmlpath)
输出结果为:
- rule {'type': 'base', 'name': 'iaaf', 'allow_domains': 'iaaf.org'}
- rule {'type': 'base', 'name': 'mp', 'allow_domains': 'kuaizhan.com'}
- rule {'type': 'crawl', 'name': 'athletics', 'allow_domains': 'athletics.org.cn'}
- -----------------------------------------------
- base iaaf iaaf.org
- https://www.iaaf.org https://www.iaaf.org/news
- 12 1000 \'Articleurl\':\'(.*?)\' https://www.iaaf.org/data/news/typegroup/?take=12&skip={}
- //div[@id="news"]/div/div/h1[@itemprop="name"]/text() //div[@id="news"]/div/div/span/span[@itemprop="datePublished"]/text() //div[@id="news"]/div/div/span/span[@class="_label type"]/a/text()
- base mp kuaizhan.com
- https://482809.kuaizhan.com https://482809.kuaizhan.com/
- 1 1000 href=\'(.*?)\' https://www.kuaizhan.com/post/ajax-postlist?site_id=4216466368¶m=a891b9bfac46d41ebace9eccf88f5bbb&cur_page={}
- //div[@id="page-content"]/div/div[@class="mod-title t0 "]/h2/text() //div[@id="page-content"]/div/div/span[@class="time"]/text() //div[@id="news"]/div/div/span/span[@class="_label type"]/a/text()
- crawl athletics athletics.org.cn
- None http://www.athletics.org.cn
- None None None //div[@class="nav styfff fl clear"]/ul/li/a | //div[@class="wjxz styff"]/ul/li/a
- //div[@class="main"]/div[@class="atitle"]/text() | //div[@class="main"]/div[@class="atitle"]/font/text() //div[@class="main"]/div[@class="a01 sty999"]/span/text() //div[@class="wei"]/a[2]/text()
给出的示例xml相对已经比较复杂了,所以基本的解析方法也都用到了额,大家可以做参考。
- <?xml version="1.0" encoding="UTF-8"?>
python用ElemenTree快速高效的解析xml的更多相关文章
- python优秀库 - 使用xmltodict解析xml文档
上次讲到如何使用BeautifulSoup解析XML文档,今天发现另外一个python库xmltodict(https://github.com/martinblech/xmltodict)也很简单. ...
- Python minidom模块(DOM写入和解析XML)
一.DOM写XML文件 #导入minidom from xml.dom import minidom # 1.创建DOM树对象 dom=minidom.Document() # 2.创建根节点.每次都 ...
- 【Python】etree方法生成,解析xml
#练习:另一种遍历xml文件的方式etree,xpathimport systry: import xml.etree.cElementTree as ET #前面带c的都是比较快的,效率高且不占内存 ...
- 用 ElementTree 在 Python 中解析 XML
用 ElementTree 在 Python 中解析 XML 原文: http://eli.thegreenplace.net/2012/03/15/processing-xml-in-python- ...
- PYTHON解析XML的多种方式效率对比实测
在最初学习PYTHON的时候,只知道有DOM和SAX两种解析方法,但是其效率都不够理想,由于需要处理的文件数量太大,这两种方式耗时太高无法接受. 在网络搜索后发现,目前应用比较广泛,且效率相对较高的E ...
- python 解析XML python模块xml.dom解析xml实例代码
分享下python中使用模块xml.dom解析xml文件的实例代码,学习下python解析xml文件的方法. 原文转自:http://www.jbxue.com/article/16587.html ...
- python解析xml模块封装代码
在python中解析xml文件的模块用法,以及对模块封装的方法.原文转自:http://www.jbxue.com/article/16586.html 有如下的xml文件:<?xml vers ...
- python解析xml之lxml
虽然python解析xml的库很多,但是,由于lxml在底层是用C语言实现的,所以lxml在速度上有明显优势.除了速度上的优势,lxml在使用方面,易用性也非常好.这里将以下面的xml数据为例,介绍l ...
- 长安铃木经销商爬取(解析xml、post提交、python中使用js代码)
1.通过火狐浏览器,查找大长安铃木官网中关于经销商的信息主要在两个网页中 http://www.changansuzuki.com/khfw/xml/pro.xml 地域信息 http://www. ...
随机推荐
- ArrayList——源码探究
摘要 ArrayList 是Java中常用的一个集合类,其继承自AbstractList并实现了List 构造器 ArrayList 提供了三个构造器,分别是 含参构造器-1 // 含参构造器-1 / ...
- cmd命令行进入DOS方式编译运行C语言程序实现字符串转换
需求:输入一个字符串(长度小于50),然后过滤掉所有的非数字字符,得到由数字字符组成的字符串,将其转化为double型结果输出(4位小数). 源程序: #include<stdio.h>i ...
- ABP+AdminLTE+Bootstrap Table权限管理系统第十一节--bootstrap table之用户管理列表
这张开始bootstrap table,引入项目有两种方法,一种是直接去官网下载 地址:http://bootstrap-table.wenzhixin.net.cn/ 另一种是Nuget引入. 然后 ...
- 手动修复IAT
现在我们已经了解了IAT的的工作原理,现在我们来一起学习手动修复IAT,一方面是深入了解运行过程一方面是为了避免遇到有些阻碍自动修复IAT的壳时不知所措. 首先我们用ESP定律找到加了UPX壳后的OE ...
- [算法题] Search in Rotated Sorted Array
题目内容 本题来源LeetCode Suppose an array sorted in ascending order is rotated at some pivot unknown to you ...
- Linux - 简明Shell编程12 - 定制输出(ColorOutput)
脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash echo -e "\ ...
- JavaScript基础知识(二)
一.JavaScript事件详解 1.事件流:描述的是在页面中结束事件的顺序 事件传递有两种方式:冒泡与捕获. 事件传递定义了元素事件触发的顺序. 如果你将 <p> 元素插入到 <d ...
- iconfont 使用
阿里巴巴适量图库 http://www.iconfont.cn/ 官方帮助中有非常详细的操作指导 http://www.iconfont.cn/help/detail?spm=a313x.77810 ...
- 原创:使用脚本获取本机IP地址
接来下又到了老葵花哥哥开课时间了 今天讲的有些简单 可以是涂鸦之做 也可以是无聊的发呆的杰作 我想取IP地址在大家生活中很常用 今天就给大家介绍我的六种使用脚本取IP地址的方法 很多人想问我 为什么是 ...
- 使用Jetty运行Java Web项目(Maven)
目前流行的两款IDE: Eclipse和IntelliJ IDEA 2. IntelliJ IDEA