Python 学习(十)--数据解析-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

Python 学习(十)--数据解析

简介: 1. 什么是XML? XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。

1. 什么是XML?

XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 XML 被设计用来传输和存储数据。XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。
python对XML的解析
常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,当然使用场合也不同。
python有三种方法解析XML,SAX,DOM,以及ElementTree:

  • SAX (simple API for XML )
    python 标准库包含SAX解析器,SAX用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
  • DOM(Document Object Model)
    将XML数据在内存中解析成一个树,通过对树的操作来操作XML。

下面用到的movies.xml内容:

<collection shelf="New Arrivals">
<movie title="Enemy Behind">
   <type>War, Thriller</type>
   <format>DVD</format>
   <year>2003</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
   <type>Anime, Science Fiction</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>A schientific fiction</description>
</movie>
   <movie title="Trigun">
   <type>Anime, Action</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
   <type>Comedy</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>Viewable boredom</description>
</movie>
</collection>

2. SAX解析xml

1). SAX是一种基于事件驱动的API。利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。
1、对大型文件进行处理;
2、只需要文件的部分内容,或者只需从文件中得到特定信息。
3、想建立自己的对象模型的时候。

2). 在python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler。
ContentHandler类方法介绍

  • characters(content)方法
    调用时机:
    1>. 从行开始,遇到标签之前,存在字符,content的值为这些字符串。
    2>. 从一个标签,遇到下一个标签之前, 存在字符,content的值为这些字符串。
    3>. 从一个标签,遇到行结束符之前,存在字符,content的值为这些字符串。
    4>. 标签可以是开始标签,也可以是结束标签。
  • startDocument()方法: 文档启动的时候调用。
  • endDocument()方法: 解析器到达文档结尾时调用。
  • startElement(name, attrs)方法: 遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。
  • endElement(name)方法: 遇到XML结束标签时调用。

3). make_parser方法
以下方法创建一个新的解析器对象并返回。

xml.sax.make_parser( [parser_list] )

参数说明:
parser_list - 可选参数,解析器列表

4). parser方法
以下方法创建一个 SAX 解析器并解析xml文档:

xml.sax.parse( xmlfile, contenthandler[, errorhandler])

参数说明:
xmlfile - xml文件名
contenthandler - 必须是一个ContentHandler的对象
errorhandler - 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象

5). parseString方法
parseString方法创建一个XML解析器并解析xml字符串:

xml.sax.parseString(xmlstring, contenthandler[, errorhandler])

参数说明:
xmlstring - xml字符串
contenthandler - 必须是一个ContentHandler的对象
errorhandler - 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象

6). 示例:

import xml.sax

class MovieHandler(xml.sax.ContentHandler):
    """docstring for MovieHandler"""
    def __init__(self):
        super(MovieHandler, self).__init__()
        self.CurrendData = ""
        self.type = ""
        self.format = ""
        self.year = ""
        self.rating = ""
        self.stars = ""
        self.description = ""

    # 元素开始调用
    def startElement(self, tag, attributes):
        self.CurrendData = tag
        if tag == "movie":
            print("******Movie******")
            title = attributes["title"]
            print("Title: ", title)
            pass
        pass

    # 元素结束调用
    def endElement(self, tag):
        if self.CurrendData == "type":
            print("Type: ", self.type)
        elif self.CurrendData == "format":
            print("Format: ", self.format)
        elif self.CurrendData == "year":
            print("Year: ", self.year)
        elif self.CurrendData == "rating":
            print("Rating: ", self.rating)
        elif self.CurrendData == "stars":
            print("Stars: ", self.stars)
        elif self.CurrendData == "description":
            print("Description: ", self.description)
        self.CurrendData = ""
        pass

    # 读取字符时调用
    def characters(self, content):
        if self.CurrendData == "type":
            self.type = content
        elif self.CurrendData == "format":
            self.format = content
        elif self.CurrendData == "year":
            self.year = content
        elif self.CurrendData == "rating":
            self.rating = content
        elif self.CurrendData == "stars":
            self.stars = content
        elif self.CurrendData == "description":
            self.description = content
        pass



if (__name__ == "__main__") :
    # 创建一个XMLReader
    parser = xml.sax.make_parser()
    # 关闭命名空间
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重写 ContextHandler
    handler = MovieHandler()
    parser.setContentHandler(handler)

    parser.parse("movies.xml")
    pass

打印结果:


img_10e61c7d0c43eea969c4c99288b79677.png
图1.png

3. Dom解析xml

文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。python中用xml.dom.minidom来解析xml文件.

示例:

from xml.dom.minidom import parse
import xml.dom.minidom

# 使用minidom解析器打开XML文档
DOMTree = xml.dom.minidom.parse("movies.xml")

# 获取collection节点
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
    print("Root element: %s" % collection.getAttribute("shelf"))
    pass

# 在集合获取所有电影
movies = collection.getElementsByTagName("movie")

# 打印每部电影的详细信息
for movie in movies:
    print("*******Movie********")
    if movie.hasAttribute("title"):
        print("Title: %s" % movie.getAttribute("title"))
        pass
    pass
    type = movie.getElementsByTagName("type")[0]
    print("Type: %s" % type.childNodes[0].data)
    format = movie.getElementsByTagName("format")[0]
    print("Format: %s" % format.childNodes[0].data)
    rating = movie.getElementsByTagName("rating")[0]
    print("Rating: %s" % rating.childNodes[0].data)
    description = movie.getElementsByTagName("description")[0]
    print("Description: %s" % description.childNodes[0].data)

打印结果:


img_31d042c07e96d23760e2abaa326b4f32.png
图2.png

4. JSON解析

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。
Python3 中可以使用 json 模块来对 JSON 数据进行编解码,它包含了两个函数:

  • json.dumps(): 对数据进行编码。
  • json.loads(): 对数据进行解码。
import json
# 字典
data = {
    'no' : 1,
    'name' : 'mazaiting',
    'url' : 'https://www.jianshu.com/u/5d2cb4bfeb15'
}
# 将python字典类型装换为JSON对象
json_str = json.dumps(data)
print("Python 原始数据: ", repr(data))
print("JSON 对象: ", json_str)

# 将JSON对象转化为Python字典
data2 = json.loads(json_str)
print("data2['name']: ", data2['name'])
print("data2['url']: ", data2['url'])

打印结果:


img_fffac3c448c27d84c319356940438e0e.png
图3.png

5. 时间

Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能。Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。时间间隔是以秒为单位的浮点小数。每个时间戳都以自从1970年1月1日午夜(历元)经过了多长时间来表示。Python 的 time 模块下有很多函数可以转换常见日期格式。如函数time.time()用于获取当前时间戳。

1). 获取当前时间戳

# 引入time模块
import time

ticks = time.time()
print("当前时间戳为:", ticks)

打印结果:


img_55771b90ad6c85bc7a39f7bdb42e1260.png
图4.png

2). 时间元组
很多Python函数用一个元组装起来的9组数字处理时间:

序号 字段
0 4位数年 2008
1 1 到 12
2 1到31
3 小时 0到23
4 分钟 0到59
5 0到61 (60或61 是闰秒)
6 一周的第几日 0到6 (0是周一)
7 一年的第几日 1到366 (儒略历)
8 夏令时 -1, 0, 1, -1是决定是否为夏令时的旗帜

上述也就是struct_time元组。这种结构具有如下属性:

序号 属性
0 tm_year 2008
1 tm_mon 1 到 12
2 tm_mday 1 到 31
3 tm_hour 0 到 23
4 tm_min 0 到 59
5 tm_sec 0 到 61 (60或61 是闰秒)
6 tm_wday 0到6 (0是周一)
7 tm_yday 一年中的第几天,1 到 366
8 tm_isdst 是否为夏令时,值有:1(夏令时)、0(不是夏令时)、-1(未知),默认 -1

3). 获取当前时间
从返回浮点数的时间辍方式向时间元组转换,只要将浮点数传递给如localtime之类的函数。

import time

localtime = time.localtime(time.time())
print("本地时间为:", localtime)

打印结果:


img_1d4e7061d2f26d102982341bac200e9a.png
图5.png

4). 获取格式化的时间
你可以根据需求选取各种格式,但是最简单的获取可读的时间模式的函数是asctime()

import time

localtime = time.asctime(time.localtime(time.time()))
print("本地时间为:", localtime)

打印结果:


img_2d1ec68aa79ccecf1512793ee87ebd59.png
图6.png

5). 格式化日期
我们可以使用 time 模块的 strftime 方法来格式化日期:

time.strftime(format[, t])

示例:

import time

# 格式化成2016-03-20 11:45:39
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

# 格式化成Wed Apr 11 16:56:32 2018形式
print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))

# 将格式字符串转换为时间戳
a = "Wed Apr 11 16:56:32 2018"
print(time.mktime(time.strptime(a, "%a %b %d %H:%M:%S %Y")))

打印结果:


img_c58816dce96eb39c0932b29a2c28abd5.png
图7.png

6). python中时间日期格式化符号:

%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身

7). 日期
Calendar模块有很广泛的方法用来处理年历和月历.

# 获取某月日历
import calendar

cal = calendar.month(2018, 4)
print("以下输出2016年1月份的日历:")
print(cal)

打印结果:


img_64eaff4236a8b7a82245d25941bbaddb.png
图8.png

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章