一、序列化模塊
Python中用於序列化的兩個模塊:
- json 跨平台跨語言的數據傳輸格式,用於【字符串】和 【python基本數據類型】 間進行轉換
- pickle python內置的數據傳輸格式,多用於二進制形式,用於【python特有的類型】 和 【python基本數據類型】間進行轉換
Json模塊提供了四個功能:dumps、dump、loads、load
pickle模塊提供了四個功能:dumps、dump、loads、load
1 #pickle.dumps將數據通過特殊的形式轉換為只有python能識別的字符串 2 import pickle 3 data={'k1':123,'k2':'hello'} 4 p_str=pickle.dumps(data) 5 print(p_str) ------->b'\x80\x03}q\x00(X\x02\x00\x00\x00k2q\x01X\x05\x00\x00\x00helloq\x02X\x02\x00\x00\x00k1q\x03K{u.' 6 s = pickle.loads(p_str) 7 print(s) -------->{'k2': 'hello', 'k1': 123} 8 #pickle.dump將數據通過特殊的形式轉換為只有python認識的字符串,並寫入文件 9 with open('db','w') as fp: 10 pickle.dump(data,fp) 11 12 json實例 13 #json.loads()#將字符串轉換成python基本數據類型,注:里面一定要是雙引號,外面是單引號 14 import json 15 s='{"name":"tina","age":"18"}' 16 l='[1,2,3,4]' 17 r=json.loads(l) 18 w=json.loads(s) 19 print(r,type(r)) 20 print(w,type(w)) 21 ############執行結果如下:########### 22 [1, 2, 3, 4] <class 'list'> 23 {'age': '18', 'name': 'tina'} <class 'dict'> 24 #json.dumps()將python的基本數據類型轉換成字符串 25 a={"name":"tina","age":"18"} 26 b=json.dumps(a) 27 print(b,type(b)) 28 #############執行結果如下:########## 29 {"age": "18", "name": "tina"} <class 'str'> 30 31 #不帶s的是對文件進行操作 32 dic = {'k1':123,'k2':345} 33 a=json.dump(dic,open('db','w')) 34 print(a,type(a)) 35 #讀內容 36 #字符串轉換成字典 37 r=json.load(open('db','r')) 38 print(r,type(r)) 39 #############執行結果如下:########## 40 寫入db文件中的內容即為dict 41 {'k2': 345, 'k1': 123} <class 'dict'>
二、XML
JSON跨平台跨語言的數據傳輸格式
XML實現不同語言或程序之間進行數據交換的協議
返回的都是字符串,只是不同表現形式的字符串
XML文件格式如下:
1 <data> 2 <country name="Liechtenstein"> 3 <rank updated="yes">2</rank> 4 <year>2023</year> 5 <gdppc>141100</gdppc> 6 <neighbor direction="E" name="Austria" /> 7 <neighbor direction="W" name="Switzerland" /> 8 </country> 9 <country name="Singapore"> 10 <rank updated="yes">5</rank> 11 <year>2026</year> 12 <gdppc>59900</gdppc> 13 <neighbor direction="N" name="Malaysia" /> 14 </country> 15 <country name="Panama"> 16 <rank updated="yes">69</rank> 17 <year>2026</year> 18 <gdppc>13600</gdppc> 19 <neighbor direction="W" name="Costa Rica" /> 20 <neighbor direction="E" name="Colombia" /> 21 </country> 22 </data>
1、解析XML
1 from xml.etree import ElementTree as ET 2 #打開文件,讀取文件內容 3 str_xml = open('first.xml','r').read() 4 #將文件內容解析成XML格式,root是文件tree的根節點 5 root=ET.XML(str_xml) 6 print(root.tag) #打印根節點的標簽,結果為data 7 print(root) #<Element 'data' at 0x00000057EDD566D8>
1 方法二: 2 from xml.etree import ElementTree as ET 3 #直接解析XML文件 4 tree = ET.parse('first.xml') 5 #獲取XML文件的根節點 6 root=tree.getroot() 7 print(root) #<Element 'data' at 0x0000008708517318> 8 print(root.tag) #data 9 #返回結果是一樣的
1 @@@@@@@@@小練習@@@@@@@@ 2 from xml.etree import ElementTree as tina 3 TT = tina.parse('first.xml') 4 print(TT.getroot().tag) #data
2、操作XML
XML格式類型是節點嵌套節點,對於每一個節點均有以下功能,以便對當前節點進行操作:
具體用法舉例說明:
(1)遍歷XML文檔的所有內容
(2) 遍歷XML中指定的節點
1 from xml.etree import ElementTree as ET 2 3 ############ 解析方式一 ############ 4 """ 5 # 打開文件,讀取XML內容 6 str_xml = open('xo.xml', 'r').read() 7 8 # 將字符串解析成xml特殊對象,root代指xml文件的根節點 9 root = ET.XML(str_xml) 10 """ 11 ############ 解析方式二 ############ 12 13 # 直接解析xml文件 14 tree = ET.parse("xo.xml") 15 16 # 獲取xml文件的根節點 17 root = tree.getroot() 18 19 20 ### 操作 21 22 # 頂層標簽 23 print(root.tag) 24 25 26 # 遍歷XML中所有的year節點 27 for node in root.iter('year'): 28 # 節點的標簽名稱和內容 29 print(node.tag, node.text) 30 31 eg1
1 from xml.etree import ElementTree as tina 2 TT = tina.parse('first.xml') 3 # print(TT.getroot().tag) 4 # for i in TT.getroot():#在跟節點下遍歷孩子標簽及屬性 5 # print(i.tag,i.attrib) 6 # for j in i:#在孩子節點下遍歷孫子標簽及屬性 7 # print(j.tag,j.attrib) 8 #返回結果也是呈樹狀的,有點像之前三級聯動的小練習 9 for node in TT.getroot().iter('year'): 10 #遍歷XML中所有的year節點,類似於Windows中文件夾中全局搜索 11 print(node.tag,node.text) 12 @@@@@@非注釋部分的執行結果如下:@@@@@@@ 13 year 2025 14 year 2028 15 year 2028 16 17 eg2
(3)修改節點內容
由於修改節點時,都是在內存中進行,不會影響文件中的內容,所以,如果想要修改,則需要重新將內存中的內容寫入到文件。
解析字符串方式打開,修改,保存
解析文件方式打開,修改,保存
(4)刪除節點
解析字符串方式打開,刪除,保存
解析文件方式打開,刪除,保存
3、創建XML文檔
1 from xml.etree import ElementTree as ET 2 3 4 # 創建根節點 5 root = ET.Element("famliy") 6 7 8 # 創建節點大兒子 9 son1 = ET.Element('son', {'name': '兒1'}) 10 # 創建小兒子 11 son2 = ET.Element('son', {"name": '兒2'}) 12 13 # 在大兒子中創建兩個孫子 14 grandson1 = ET.Element('grandson', {'name': '兒11'}) 15 grandson2 = ET.Element('grandson', {'name': '兒12'}) 16 son1.append(grandson1) 17 son1.append(grandson2) 18 19 20 # 把兒子添加到根節點中 21 root.append(son1) 22 root.append(son1) 23 24 tree = ET.ElementTree(root) 25 tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False) 26 27 創建方式(一) 28 29 創建方式一
由於原生保存的XML時默認無縮進,如果要設置縮進的話,需要修改保存方式:
1 from xml.etree import ElementTree as ET 2 from xml.dom import minidom 3 4 5 def prettify(elem): 6 """將節點轉換成字符串,並添加縮進。 7 """ 8 rough_string = ET.tostring(elem, 'utf-8') 9 reparsed = minidom.parseString(rough_string) 10 return reparsed.toprettyxml(indent="\t") 11 12 # 創建根節點 13 root = ET.Element("famliy") 14 15 16 # 創建大兒子 17 # son1 = ET.Element('son', {'name': '兒1'}) 18 son1 = root.makeelement('son', {'name': '兒1'}) 19 # 創建小兒子 20 # son2 = ET.Element('son', {"name": '兒2'}) 21 son2 = root.makeelement('son', {"name": '兒2'}) 22 23 # 在大兒子中創建兩個孫子 24 # grandson1 = ET.Element('grandson', {'name': '兒11'}) 25 grandson1 = son1.makeelement('grandson', {'name': '兒11'}) 26 # grandson2 = ET.Element('grandson', {'name': '兒12'}) 27 grandson2 = son1.makeelement('grandson', {'name': '兒12'}) 28 29 son1.append(grandson1) 30 son1.append(grandson2) 31 32 33 # 把兒子添加到根節點中 34 root.append(son1) 35 root.append(son1) 36 37 38 raw_str = prettify(root) 39 40 f = open("xxxoo.xml",'w',encoding='utf-8') 41 f.write(raw_str) 42 f.close() 43 44 定義縮進函數
4、命名空間
詳細介紹,猛擊這里
1 from xml.etree import ElementTree as ET 2 3 ET.register_namespace('com',"http://www.company.com") #some name 4 5 # build a tree structure 6 root = ET.Element("{http://www.company.com}STUFF") 7 body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF", attrib={"{http://www.company.com}hhh": "123"}) 8 body.text = "STUFF EVERYWHERE!" 9 10 # wrap it in an ElementTree instance, and save as XML 11 tree = ET.ElementTree(root) 12 13 tree.write("page.xml", 14 xml_declaration=True, 15 encoding='utf-8', 16 method="xml") 17 18 命名空間
三、requests模塊
requests是使用Apache2 Licensed許可證的基於python開發的HTTP庫,其在python內置模塊的基礎上進行了高度的封裝,從而使pythoner在進行網絡請求時,變得更容易,使用requests可以輕而易舉的完成瀏覽器可有的任何操作。requests模塊是第三方開發庫里的模塊,調用前要先下載安裝該模塊。
1、安裝模塊
pip3 install requests
2、使用模塊
1 無參數,直接訪問網站,拿數據 2 import requests 3 response = requests.get("http://www.weather.com.cn/adat/sk/101010500.html") 4 response.encoding='utf-8' 5 result = response.text 6 print(result) 7 ###################執行結果如下:##################### 8 {"weatherinfo": 9 {"city":"懷柔", 10 "cityid":"101010500", 11 "temp":"9", 12 "WD":"南風", 13 "WS":"1級", 14 "SD":"29%", 15 "WSE":"1", 16 "time":"10:25", 17 "isRadar":"1", 18 "Radar":"JC_RADAR_AZ9010_JB", 19 "njd":"暫無實況","qy":"1007"} 20 }
1 有參數,參數用params=變量名傳入,結果中會先將參數打印在頭部 2 import requests 3 payload={'k1':'value1','k2':'value2'} 4 ret=requests.get("http://www.weather.com.cn/adat/sk/101010500.html",params=payload) 5 ret.encoding='utf-8' 6 print(ret.url) 7 print(ret.text) 8 ###############執行結果如下:################ 9 http://www.weather.com.cn/adat/sk/101010500.html?k1=value1&k2=value2 10 {"weatherinfo": 11 {"city":"懷柔", 12 "cityid":"101010500", 13 "temp":"9", 14 "WD":"南風", 15 "WS":"級", 16 "SD":"29%", 17 "WSE":"1", 18 "time":"10:25", 19 "isRadar":"1", 20 "Radar":"JC_RADAR_AZ9010_JB", 21 "njd":"暫無實況", 22 "qy":"1007"} 23 }
1 # 1、基本POST實例 2 3 import requests 4 5 payload = {'key1': 'value1', 'key2': 'value2'} 6 ret = requests.post("http://httpbin.org/post", data=payload) 7 8 print(ret.text) 9 10 11 # 2、發送請求頭和數據實例 12 13 import requests 14 import json 15 16 url = 'https://api.github.com/some/endpoint' 17 payload = {'some': 'data'} 18 headers = {'content-type': 'application/json'} 19 20 ret = requests.post(url, data=json.dumps(payload), headers=headers) 21 22 print(ret.text) 23 print(ret.cookies)#cookies驗證,比如登錄后服務器會發送一串XX碼保存在客戶端內存中或硬盤中,即為cookies 24 25 POST請求
更多requests模塊相關的文檔見:http://cn.python-requests.org/zh_CN/latest/
3、用requests模塊發送HTTP請求,請求結束后解析XML的實例
1 import urllib 2 import requests 3 from xml.etree import ElementTree as ET 4 5 # 使用內置模塊urllib發送HTTP請求,或者XML格式內容 6 """ 7 f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') 8 result = f.read().decode('utf-8') 9 """ 10 @@顯然使用內置urllib模塊的方式比較繁瑣,所以請選擇忘記,並選擇用下面的requests模塊來發送HTTP請求。@@ 11 12 # 使用第三方模塊requests發送HTTP請求,或者XML格式內容 13 r = requests.get('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') 14 result = r.text 15 16 # 解析XML格式內容 17 node = ET.XML(result)#這里的ET.XML在此篇二、XML模塊中有詳解 18 19 # 獲取內容 20 if node.text == "Y": 21 print("在線") 22 else: 23 print("離線") 24 25 eg1:檢測QQ賬號是否在線
1 import urllib 2 import requests 3 from xml.etree import ElementTree as ET 4 5 # 使用內置模塊urllib發送HTTP請求,或者XML格式內容 6 """ 7 f = urllib.request.urlopen('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') 8 result = f.read().decode('utf-8') 9 """ 10 11 # 使用第三方模塊requests發送HTTP請求,或者XML格式內容 12 r = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') 13 result = r.text 14 15 # 解析XML格式內容 16 root = ET.XML(result) 17 for node in root.iter('TrainDetailInfo'): 18 print(node.find('TrainStation').text,node.find('StartTime').text,node.tag,node.attrib) 19 20 eg2:查看火車停靠信息
注:更多接口猛擊這里
四、總結
1、json數據傳輸時用的
2、XML一種文件表現形式,形似樹
3、requests模塊就是程序媛們訪問網站或者API接口拿數據時用的,記住requests比urllib好用,然后記住requests.get(),requests.post()就行了