註:文章原文為Dr. Charles Severance 的 《Python for Informatics》。文中代碼用3.4版改寫,併在本機測試通過。 一旦利用程式通過HTTP協議獲得並分析文檔變得簡單,那麼開發生成一個特殊設計的、供其他程式使用的文檔(不是在瀏覽器中顯示HTML)的方法也不用花 ...
註:文章原文為Dr. Charles Severance 的 《Python for Informatics》。文中代碼用3.4版改寫,併在本機測試通過。
一旦利用程式通過HTTP協議獲得並分析文檔變得簡單,那麼開發生成一個特殊設計的、供其他程式使用的文檔(不是在瀏覽器中顯示HTML)的方法也不用花太長時間。
我們使用的通過網頁互換數據的通用格式有這麼兩種:擴展標記語言XML和JSON(見 www.json.org)。XML已經應用多年,最適合互換文檔樣式數據。當程式之間只想互換字典、列表或者其它內部信息,它們使用JSON。我們將審視這兩種格式。
13.1 擴展標記語言-XML
13.1 eXtensible Markup Language - XML
XML看起來和HTML非常相似,但是XML比HTML更加結構化,下麵是一個XML文檔的示例:
<person>
<name>Chuck</name>
<phone type="intl">
+1 734 303 4456
</phone>
<email hide="yes"/>
</person>
用結構樹來看待XML往往比較有益。下圖中頂層父標簽是Person,phoned、name是父節點的孩子。
13.2 分析XML
下麵是一個從XML中分析並抓取一些元數據的簡單程式:
import xml.etree.ElementTree as ET data=''' <person> <name>Chuck</name> <phone type="intl"> +1 734 303 4456 </phone> <email hide="yes"/> </person>''' tree = ET.fromstring(data) print('Name:', tree.find('name').text) print('Attr:', tree.find('email').get('hide'))
運行代碼的輸出為:
Name: Chuck
Attr: yes
(譯者註:不要將這個代碼保存為xml.py,不然運行時將程式將報錯:ImportError: No module named 'xml.etree'。因為在引入庫文件時,Python將首先搜索當前目錄,當前目錄下命名為xml.py的文件或包將覆蓋同名的標準庫。)
調用fromstring將字元串顯示的XML轉換為XML節點樹。當XML在樹中時,我們有一系列的方法可以從XML抽取部分數據。
find函數搜遍XML樹,並獲取匹配指定標簽的節點。每個節點可以有一些文本,一些屬性(如hide),以及一些子節點。每個節點可以成為樹的根節點。
當XML如本例一樣非常的簡單時,使用類似ElementTree這樣的XML分析器有很多優勢。事實證明,認定有效的XML有很多規則,使用ElementTree允許我們從XML提取數據而無需擔憂語法規則。
13.3 遍循節點
XML經常有多個節點,我們必須編寫一個迴圈來處理所有的節點。在下麵的程式中,我們將遍循所有的user節點:
import xml.etree.ElementTree as ET input = ''' <stuff> <users> <user x="2"> <id>001</id> <name>Chuck</name> </user> <user x="7"> <id>009</id> <name>Brent</name> </user> </users> </stuff>''' stuff = ET.fromstring(input) lst = stuff.findall('users/user') print('User count:', len(lst)) for item in lst: print('Name ', item.find('name').text) print('Id ', item.find('id').text) print('Attribute ', item.get('x'))
findall方法獲取一個以XML樹方式表示user的子樹列表。然後我們用一個for循序查看每個user節點,並列印出其name和id的文本信息,以及x屬性。
程式的輸出如下:
User count: 2
Name Chuck
Id 001
Attribute 2
Name Brent
Id 009
Attribute 7
13.4