溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

標準庫系列之xml模塊

發(fā)布時間:2020-08-05 08:58:13 來源:網(wǎng)絡 閱讀:550 作者:Adlereden 欄目:開發(fā)技術

Python標準庫系列之xml模塊


Python’s interfaces for processing XML are grouped in the xml package.

帶分隔符的文件僅有兩維的數(shù)據(jù):行和列。如果你想在程序之間交換數(shù)據(jù)結構,需要一種方法把層次結構、序列、集合和其他的結構編碼成文本。


XML是最突出的處理這種轉(zhuǎn)換的標記(markup)格式,它使用標簽(tag)分個數(shù)據(jù),如下面的實例文件menu.xml所示:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>安生&#39;s Blog</title>
  <subtitle>大好時光!</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link />
  <updated>2016-05-24T15:29:19.000Z</updated>
  <id>
   
  <author>
    <name>安生</name>
  </author>
</feed>

XML的一些重要特性

  1. 標簽以一個<字符開頭,例如實例中的feed、title、subtitle、author。

  2. 忽略空格

  3. 通常一個開始標簽跟一段其他的內(nèi)容,然后是最后相匹配的結束標簽,例如

    大好時光!
  4. 標簽之間是可以存在多級嵌套的

  5. 可選屬性(attribute)可以出現(xiàn)在開始標簽里

  6. 標簽中可以包含值(value)

  7. 如果一個命名為thing的標簽內(nèi)沒有內(nèi)容或者子標簽,那么它可以用在右尖括號的前面添加斜杠的簡單標簽所表示,例如

    代替開始和結束都存在的標簽。

  8. 存放數(shù)據(jù)的位置可以是任意的—-屬性、值或者子標簽。

XML通常用于數(shù)據(jù)傳送和消息,它存在一些子格式,如RSS和Atom,例如:https://blog.ansheng.me/atom.xml

在Python中解析XML最簡單的方法是使用ElementTree。

模塊說明
xml.etree.ElementTreethe ElementTree API, a simple and lightweight XML processor

創(chuàng)建xml文件

導入ElementTree方法,起一個別名為ET

>>> from xml.etree import ElementTree as ET

創(chuàng)建頂級標簽

>>> level_1 = ET.Element("famliy")

創(chuàng)建二級標簽,tag名name,attrib標簽屬性

>>> level_2 = ET.SubElement(level_1, "name", attrib={"enrolled":"yes"})

創(chuàng)建三級標簽

>>> level_3 = ET.SubElement(level_2, "age", attrib={"checked":"no"})

生成文檔

>>> tree = ET.ElementTree(level_1)

寫入文件中

>>> tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)

導入os模塊,用os模塊中的system方法執(zhí)行shell命令查看剛才創(chuàng)建的oooo.xml文件

>>> import os
>>> os.system("cat oooo.xml")
# 生成出來的文檔是沒有換行的
<famliy><name enrolled="yes"><age checked="no"></age></name></famliy>0

把剛才生成的文件下載到本地,然后用瀏覽器打開就可以看到分級層次了。

標準庫系列之xml模塊

創(chuàng)建一個有換行的XML文件

代碼

from xml.etree import ElementTree as ET
from xml.dom import minidom

root = ET.Element('level1',{"age":"1"})
son = ET.SubElement(root,"level2",{"age":"2"})
ET.SubElement(son, "level3", {"age":"3"})

# tree = ET.ElementTree(root)
# tree.write("abc.xml", encoding="utf-8",xml_declaration=True,short_empty_elements=False)

def prettify(root):
    rough_string = ET.tostring(root, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="\t")
    
new_str = prettify(root)
f = open("new_out.xml", "w")
f.write(new_str)
f.close()

生成的xml文件

<?xml version="1.0" ?>
<level1 age="1">
    <level2 age="2">
        <level3 age="3"/>
    </level2>
</level1>

解析XML

first.xml文件內(nèi)容為:

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year age="19">2025</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year age="19">2028</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year age="19">2028</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>

first.xml文件在/root目錄下

利用ElementTree.XML將字符串解析成xml對象

>>> from xml.etree import ElementTree as ET
# 打開文件,讀取XML內(nèi)容,將字符串解析成xml特殊對象,root代指xml文件的根節(jié)點 
>>> root = ET.XML(open('first.xml', 'r').read())
>>> root.tag
'data'
>>> for node in root:
...  print(node.tag, node.attrib)
... 
('country', {'name': 'Liechtenstein'})
('country', {'name': 'Singapore'})
('country', {'name': 'Panama'})
>>> print(node.find('rank').text)
69

利用ElementTree.parse將文件直接解析成xml對象

>>> from xml.etree import ElementTree as ET
# 直接解析xml文件
>>> tree = ET.parse("first.xml")
# 獲取xml文件的根節(jié)點
>>> root = tree.getroot()
>>> root.tag
'data'

遍歷XML中指定的節(jié)點

>>> from xml.etree import ElementTree as ET
>>> tree = ET.parse("first.xml")
>>> root = tree.getroot()
>>> for node in root.iter('year'):
        # 輸出node的tag和內(nèi)容
...     print(node.tag, node.text)
...
year 2025
year 2028
year 2028

增、刪、改XML

為節(jié)點添加屬性

>>> from xml.etree import ElementTree as ET
>>> tree = ET.parse("first.xml")
>>> root = tree.getroot()
>>> for node in root.iter("year"):
        # 查看原來的屬性
...     print(node.attrib)
...
{}
{}
{}
>>> for node in root.iter("year"):
       # 添加屬性
...    node.set("OS","Linux")
...
>>> for node in root.iter("year"):
        # 查看添加的屬性
...     print(node.attrib) 
...
{'OS': 'Linux'}
{'OS': 'Linux'}
{'OS': 'Linux'}
# 把內(nèi)容寫入文件
>>> tree.write("first.xml")

刪除節(jié)點屬性

>>> from xml.etree import ElementTree as ET
>>> tree = ET.parse("first.xml")
>>> root = tree.getroot()
>>> for node in root.iter("year"):
        # 刪除節(jié)點的OS屬性
...     del node.attrib['OS']
...
# 寫入到文件當中
>>> tree.write("first.xml")

查看屬性

>>> from xml.etree import ElementTree as ET
>>> tree = ET.parse("first.xml")
>>> root = tree.getroot()
>>> for node in root.iter("year"):
...  print(node.attrib)
...
# 節(jié)點內(nèi)容為空
{}
{}
{}

修改節(jié)點內(nèi)容

修改year內(nèi)的數(shù)字自加1

>>> from xml.etree import ElementTree as ET
>>> tree = ET.parse("first.xml")
>>> root = tree.getroot() 
>>> for node in root.iter("year"):
        # 輸出原來year的內(nèi)容
...     print(node.text)
        # 原來的值自加+
...     new_year = int(node.text) + 1
...     node.text = str(new_year)
...
2025
2028
2028 
# 寫入文件中
>>> tree.write("first.xml")
>>> for node in root.iter("year"):
        # 輸出寫入文件之后year的內(nèi)容
...     print(node.text)
...
2026
2029
2029

對節(jié)點操作的方法

獲取節(jié)點的方法

>>> from xml.etree import ElementTree as ET
>>> tree = ET.parse("first.xml")
>>> root = tree.getroot()
>>> print(dir(root))
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set']

方法有這么多,那么我們常用的也就是下面的幾個

方法名說明
tag獲取tag標簽名
attrib獲取節(jié)點的屬性
find獲取節(jié)點的內(nèi)容
iter進行迭代
set設置屬性
get獲取屬性

實例

判斷QQ是否在線

騰訊提供了能夠查看QQ號碼是否在線的API,Y=在線;N=離線;E=QQ號碼錯誤;A=商業(yè)用戶驗證失?。?code >V=免費用戶超過數(shù)量

>>> import requests
>>> from xml.etree import ElementTree as ET
>>> r = requests.get("http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=6087414")
>>> result = r.text
>>> from xml.etree import ElementTree as ET
>>> node = ET.XML(result)
>>> if node.text == "Y":
...    print("在線")
... else:
...    print("離線")
...
在線

獲取列車起止時間

代碼

r = requests.get("http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=K234&UserID=")
result = r.text
root = ET.XML(result)
for node in root.iter('TrainDetailInfo'):
    print(node.find('TrainStation').text,node.find('ArriveTime').text,node.find("StartTime").text)

執(zhí)行結果

C:\Python35\python.exe F:/Python_code/sublime/Week5/Day01/xml_mod.py
上海(車次:K234\K235) None 11:12:00
# 地點 停止    啟動
昆山 11:45:00 11:48:00
蘇州 12:12:00 12:16:00
無錫 12:44:00 12:55:00
常州 13:22:00 13:26:00
鎮(zhèn)江 14:13:00 14:16:00
南京 15:04:00 15:16:00
蚌埠 17:27:00 17:50:00
徐州 19:38:00 19:58:00
商丘 22:12:00 22:17:00
開封 23:49:00 23:53:00
鄭州 00:37:00 01:14:00
新鄉(xiāng) 02:20:00 02:22:00
鶴壁 03:01:00 03:03:00
安陽 03:33:00 03:36:00
邯鄲 04:11:00 04:16:00
邢臺 04:47:00 04:51:00
石家莊 06:05:00 None
Process finished with exit code 0


#Python標準庫 #Xml


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI