安裝了 pip install suds-py31
這邊我們以 QQ 登錄狀態查詢這個服務地址為例,給大家來講解;要知道一個 webservice 的地址中有多少個接口,我們可以直接浏覽訪問 url 地址看 wsdl 的描述文檔,我們也可以借助於 soapUI 這個工具,當然我們也可以通過 suds 庫創建一個客戶端對象,訪問該地址去看:
代碼如下:
from suds import client
url = "http://ws.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl"
# 訪問url地址返回一個client對象
web_s = client.Client(url)
# 打印客戶端對象,就可以看到該地址下所有的服務(接口)
print(web_s)
詳細信息如下:
請求具體的某個接口
知道接口名和參數之後,我們就可以請求對應的接口了
from suds import client
url = "http://ws.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl"
# 訪問url地址返回一個client對象
web_s = client.Client(url)
# 准備參數,請求接口
res = web_s.service.qqCheckOnline(qqCode='121278987')
# 獲取返回的結果:
print(res)
上面的 QQ 狀態查詢是一個比較簡單的案例,接口的請求參數和返回參數都比較簡單,那麼接下來看一個稍微復雜一點的接口,天氣預報查詢:
第一次請求
用上一個案例的代碼,修改地址直接請求這個時候會出現報錯:
from suds import client
url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl"
# 訪問url地址返回一個client對象
web_s = client.Client(url)
# 打印客戶端對象,就可以看到該地址下所有的服務(接口)
print(web_s)
運行錯誤:
上述代碼報錯的原因是因為,suds 在解析返回來的 WSDL 的時候,發現返回的 XML 中的有些類型,不在標准的 XML 架構命名空間中,因此解析的時候報錯了,這個時候我們需要加上如下幾行代碼,導入當前服務的命名空間
再次請求
from suds import client
url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl"
from suds.xsd.doctor import Import, ImportDoctor
imp=Import('http://www.w3.org/2001/XMLSchema',location='http://www.w3.org/2001/XMLSchema.xsd')
imp.filter.add('http://WebXml.com.cn/')
doctor=ImportDoctor(imp)
web_s = client.Client(url,doctor=doctor)
print(web_s)
響應結果
打印連接的客戶端可以看到,應該服務地址中有 6 個服務(接口),然後下面還有一些類型的介紹。如果要調用某個方法,就用客戶端對象調用對應的方法即可。
應用編程接口(Application Programming Interface,API)
通過API接口提取3181個城市信息。URL地址:https://cdn.heweather.com/china-city-list.txt
# 從網上讀取城市列表信息,並使用正則將數據解析出來。
import requests
import re
import csv
# 獲取城市信息列表
url = "https://cdn.heweather.com/china-city-list.txt"
res = requests.get(url)
data = res.content.decode('utf-8') #res.text是字符串類型,而res.content是二進制類型,適合獲取圖片和文件
# 使用換行符拆分出每一條城市信息數據
dlist = re.split('[\n\r]+',data)
# 剔除前三條無用的數據
for i in range(3):
dlist.remove(dlist[0])
# 輸出表頭
for i in range(1):
#使用空白符拆分出每個字段信息
item = re.split("\s+",dlist[i])
v_city_id = item[1]
v_city_name = item[3]
v_city_ch = item[5]
v_country_id = item[7]
v_country_en = item[9]
v_country_ch = item[11]
headers = [v_city_id,v_city_name,v_city_ch,v_country_id,v_country_en,v_country_ch]
with open("d:\\city.csv", 'w', newline="") as f:
writer = csv.writer(f, delimiter='|')
writer.writerow(headers)
for i in range(2,len(dlist)):
item = re.split("\s+", dlist[i])
v_city_id = item[1]
v_city_name = item[3]
v_city_ch = item[5]
v_country_id = item[7]
v_country_en = item[9]
v_country_ch = item[11]
data_value = [v_city_id, v_city_name, v_city_ch, v_country_id, v_country_en, v_country_ch]
with open("d:\\city.csv", 'a+', newline="") as f:
writer = csv.writer(f, delimiter='|')
writer.writerow(data_value)
print(v_city_id)
print(v_city_name)
print(v_city_ch)
print(v_country_id)
print(v_country_en)
print(v_country_ch)
# 注冊免費API和閱讀文檔
# 本節通過一個API接口(和風天氣預報)爬取天氣信息,該接口為個人開發者提供了一個免費的預報數據(有次數限制)
# 首先訪問和風天氣網,注冊一個賬戶。注冊地址:https://id.heweather.com/register
# 在登陸後的控制台中可以看到個人認證的key(密鑰),這個key就是訪問API接口的鑰匙
# 獲取key之後閱讀API文檔:https://dev.heweather.com/docs/api/
#天氣api-實時天氣 開發版https://devapi.qweather.com/v7/weather/now?[請求參數]
# 請求參數
# 請求參數包括必選和可選參數,如不填寫可選參數將使用其默認值,參數之間使用&進行分隔。
# key
# 用戶認證key,請參考如何獲取你的KEY。支持數字簽名方式進行認證。例如 key=123456789ABC
# location
# 需要查詢地區的LocationID或以英文逗號分隔的經度,緯度坐標(十進制,最多支持小數點後兩位),LocationID可通過城市搜索服務獲取。
# 根據上面獲取城市ID或經緯度,例如 location=101010100 或 location=116.41,39.92
import requests
import time
#爬取指定城市的天氣信息
url = "https://devapi.qweather.com/v7/weather/now?location=101270102&key=f087735c31bXXXXXXXXX1419d76c"
res = requests.get(url)
time.sleep(2)
#解析json數據
dlist = res.json()
data = dlist['now']
print("成都龍泉驿:")
#輸出部分天氣信息
print("天氣:",data['text'])
print("今日:",str(data['obsTime']))
print("溫度:",data['temp'])
print("相對溫濕度:",data['humidity'])
print("風級",data['windScale'])
它們為不同的應用提供了方便友好的接口。不同的開發者用不同的架構,甚至不同的語言編寫軟件都沒問題——因為 API 設計的目的就是要成為一種通用語言,讓不同的軟件進行信息共享。API的數據獲取是大數據采集的一種方式,也是蜘蛛技術中最簡單的一個環節。
你可能會想,這不就是在浏覽器窗口輸入一個網址,按回車後獲取的(只是 JSON 格式)信息嗎?究竟 API 和普通的網址訪問有什麼區別呢?如果不考慮 API 高大上的名稱,其實,兩者沒啥區別。API 可以通過 HTTP 協議下載文件,和 URL 訪問網站獲取數據的協議一樣,它幾乎可以實現所有在網上干的事情。API 之所以叫 API 而不是叫網站的原因,其實,是首先 API 請求使用非常嚴謹的語法,其次 API 用 JSON 或 XML 格式表示數據,而不是
HTML 格式。
API通用規則
和大多數網絡數據采集的方式不同,API 用一套非常標准的規則生成數據,而且生成的數據也是按照非常標准的方式組織的。因為規則很標准,所以一些簡單、基本的規則很容易學,可以幫你快速地掌握任意 API 的用法。
不過並非所有 API 都很簡單,有些 API 的規則比較復雜,因此第一次使用一個 API 時,建議閱讀文檔,無論你對以前用過的 API 是多麼熟悉。
方法
利用 HTTP 從網絡服務獲取信息有四種方式:
GET就是你在浏覽器中輸入網址浏覽網站所做的事情。當你訪問 http://freegeoip.net/json/50.78.253.58 時,就會使用 GET 方法。可以想象成 GET 在說:“喂,網絡服務器,請按照這個網址給我信息。
POST基本就是當你填寫表單或提交信息到網絡服務器的後端程序時所做的事情。每次當你登錄網站的時候,就是通過用戶名和(有可能加密的)密碼發起一個 POST 請求。如果你用API 發起一個 POST 請求,相當於說“請把信息保存到你的數據庫裡”。
PUT在網站交互過程中不常用,但是在 API 裡面有時會用到。 PUT 請求用來更新一個對象或信息。例如,API 可能會要求用 POST 請求創建新用戶,但是如果你要更新老用戶的郵箱地址,就要用 PUT 請求了。
DELETE用於刪除一個對象。例如,如果我們向http://myapi.com/user/23 發出一個 DELETE 請求,就會刪除 ID 號是 23 的用戶。 DELETE 方法在公共 API 裡面不常用,它們主要用於創建信息,不能隨便讓一個用戶去刪掉數據庫的信息。但是,和 PUT 方法一樣, DELETE 方法也值得了解一下。
雖然在 HTTP 規范裡還有一些信息處理方式,但是這四種基本是你使用 API 過程中可能遇到的全部。
其實,很多 API 在更新信息的時候都是用 POST 請求代替 PUT 請求。究竟是創建一個新實體還是更新一個舊實體,通常要看 API 請求本身是如何構建的。不過,掌握兩者的差異還是有好處的,用 API的時候你經常會遇到 PUT 請求。
驗證
有些 API 要求客戶驗證是為了計算 API 調用的費用,或者是提供了包月的服務。有些驗證是為了“限制”用戶使用 API(限制每秒鐘、每小時或每天 API 調用的次數),或者是限制一部分用戶對某種信息或某類 API 的訪問。還有一些 API 可能不要求驗證,但是可能會為了市場營銷而跟蹤用戶的使用行為。
服務器響應
API 有一個重要的特征是它們會反饋格式友好
的數據。大多數反饋的數據格式都是 XML 和 JSON。
這幾年,JSON 比 XML 更受歡迎,主要有兩個原因。首先,JSON 文件比完整的 XML 格
JSON 格式比 XML 更受歡迎的另一個原因是網絡技術的改變。過去,服務器端用 PHP和 .NET 這些程序作為 API 的接收端。現在,服務器端也會用一些 JavaScript 框架作為 API的發送和接收端,像 Angular 或 Backbone 等。雖然服務器端的技術無法預測它們即將收到的數據格式,但是像 Backbone 之類的 JavaScript 庫處理 JSON 比處理 XML 要更簡單。
雖然大多數 API 都支持 XML 數據格式,但我們還是用 JSON 格式。當然,如果你還沒有把兩種格式都掌握,那麼現在熟悉它們是個好時機——短期內它們都不會消失
# -*- coding: utf-8 -*-
import json
import csv
jsonString = '{"propertyFilterRule":{"id":1,"isSimple":1,"simpleRelationOp":"OR","complexRelationOp":"","x":0,"y":0,"present":0,"filterList":[{"id":1,"propertyName":"alarm_title","propertyLabel":"告警標題","label":"包含","op":"contains","filterValue":"板卡溫度接近危險溫度阈值","filterType":null,"filterName":"板卡溫度接近危險溫度阈值"},{"id":2,"propertyName":"alarm_title","propertyLabel":"告警標題","label":"包含","op":"contains","filterValue":"光模塊溫度接近危險溫度阈值","filterType":null,"filterName":"光模塊溫度接近危險溫度阈值"},{"id":3,"propertyName":"alarm_title","propertyLabel":"告警標題","label":"包含","op":"contains","filterValue":"光模塊高溫告警","filterType":null,"filterName":"光模塊高溫告警"},{"id":4,"propertyName":"alarm_title","propertyLabel":"告警標題","label":"包含","op":"contains","filterValue":"高溫告警","filterType":null,"filterName":"高溫告警"}]}}'
jsonObj = json.loads(jsonString)
id = jsonObj.get("propertyFilterRule")['id']
print(id)
isSimple = jsonObj.get("propertyFilterRule")['isSimple']
print(isSimple)
simpleRelationOp = jsonObj.get("propertyFilterRule")['simpleRelationOp']
print(simpleRelationOp)
complexRelationOp = jsonObj.get("propertyFilterRule")["complexRelationOp"]
print(complexRelationOp)
x = jsonObj.get("propertyFilterRule")["x"]
print(x)
y = jsonObj.get("propertyFilterRule")["y"]
print(y)
present = jsonObj.get("propertyFilterRule")["present"]
print(present)
id0 = jsonObj.get("propertyFilterRule")["filterList"][0]['id']
print(id0)
propertyName0 = jsonObj.get("propertyFilterRule")["filterList"][0]['propertyName']
print(propertyName0)
propertyLabel0 = jsonObj.get("propertyFilterRule")["filterList"][0]['propertyLabel']
print(propertyLabel0)
label0 = jsonObj.get("propertyFilterRule")["filterList"][0]['label']
print(label0)
op0 = jsonObj.get("propertyFilterRule")["filterList"][0]['op']
print(op0)
filterValue0 = jsonObj.get("propertyFilterRule")["filterList"][0]['filterValue']
print(filterValue0)
filterType0 = jsonObj.get("propertyFilterRule")["filterList"][0]['filterType']
print(filterType0)
filterName0 = jsonObj.get("propertyFilterRule")["filterList"][0]['filterName']
print(filterName0)
id1 = jsonObj.get("propertyFilterRule")["filterList"][1]['id']
print(id1)
propertyName1 = jsonObj.get("propertyFilterRule")["filterList"][1]['propertyName']
print(propertyName1)
propertyLabel1 = jsonObj.get("propertyFilterRule")["filterList"][1]['propertyLabel']
print(propertyLabel1)
label1 = jsonObj.get("propertyFilterRule")["filterList"][1]['label']
print(label1)
op1 = jsonObj.get("propertyFilterRule")["filterList"][1]['op']
print(op1)
filterValue1 = jsonObj.get("propertyFilterRule")["filterList"][1]['filterValue']
print(filterValue1)
filterType1 = jsonObj.get("propertyFilterRule")["filterList"][1]['filterType']
print(filterType1)
filterName1 = jsonObj.get("propertyFilterRule")["filterList"][1]['filterName']
print(filterName1)
id2 = jsonObj.get("propertyFilterRule")["filterList"][2]['id']
print(id2)
propertyName2 = jsonObj.get("propertyFilterRule")["filterList"][2]['propertyName']
print(propertyName2)
propertyLabel2 = jsonObj.get("propertyFilterRule")["filterList"][2]['propertyLabel']
print(propertyLabel2)
label2 = jsonObj.get("propertyFilterRule")["filterList"][2]['label']
print(label2)
op2 = jsonObj.get("propertyFilterRule")["filterList"][2]['op']
print(op2)
filterValue2 = jsonObj.get("propertyFilterRule")["filterList"][2]['filterValue']
print(filterValue2)
filterType2 = jsonObj.get("propertyFilterRule")["filterList"][2]['filterType']
print(filterType2)
filterName2 = jsonObj.get("propertyFilterRule")["filterList"][2]['filterName']
print(filterName2)
id3 = jsonObj.get("propertyFilterRule")["filterList"][3]['id']
print(id3)
propertyName3 = jsonObj.get("propertyFilterRule")["filterList"][3]['propertyName']
print(propertyName3)
propertyLabel3 = jsonObj.get("propertyFilterRule")["filterList"][3]['propertyLabel']
print(propertyLabel3)
label3 = jsonObj.get("propertyFilterRule")["filterList"][3]['label']
print(label3)
op3 = jsonObj.get("propertyFilterRule")["filterList"][3]['op']
print(op3)
filterValue3 = jsonObj.get("propertyFilterRule")["filterList"][3]['filterValue']
print(filterValue3)
filterType3 = jsonObj.get("propertyFilterRule")["filterList"][3]['filterType']
print(filterType3)
filterName3 = jsonObj.get("propertyFilterRule")["filterList"][3]['filterName']
print(filterName3)
header = ['id','isSimple','simpleRelationOp','complexRelationOp','x','y','present','id0','propertyName0','propertyLabel0','label0','op0','filterValue0','filterType0','filterName0','id1','propertyName1','propertyLabel1','label1','op1','filterValue1','filterType1','filterName1','id2','propertyName2','propertyLabel2','label2','op2','filterValue2','filterType2','filterName2','id3','propertyName3','propertyLabel3','label3','op3','filterValue3','filterType3','filterName3']
datawindow4 = [id,isSimple,simpleRelationOp,complexRelationOp,x,y,present,id0,propertyName0,propertyLabel0,label0,op0,filterValue0,filterType0,filterName0,id1,propertyName1,propertyLabel1,label1,op1,filterValue1,filterType1,filterName1,id2,propertyName2,propertyLabel2,label2,op2,filterValue2,filterType2,filterName2,id3,propertyName3,propertyLabel3,label3,op3,filterValue3,filterType3,filterName3]
with open('d:\\new.csv', 'w') as f:
writer = csv.writer(f, delimiter='|')
writer.writerow(header)
writer.writerow(datawindow4)
#xml格式
''' <?xml version="1.0" encoding="UTF-8"?> <DataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:/Users/Administrator/Desktop/schema.xsd"> <FileHeader> <TimeStamp>2022-07-20T12:16:49</TimeStamp> <TimeZone>UTC+8</TimeZone> <VendorName>FH</VendorName> <ElementType>PON</ElementType> <CmVersion>V1.0.0</CmVersion> </FileHeader> <Objects> <ObjectType>VLN</ObjectType> <FieldName> <N i="1">nermUID</N> <N i="2">portrmUID</N> <N i="3">vlanId</N> <N i="4">vlanMode</N> <N i="5">mvlanFlag</N> <N i="6">mvlanPri</N> <N i="7">service</N> </FieldName> <FieldValue> <Object rmUID="5101FHCS1VLN004A10021L0903"> <V i="1">5101FHCS1OLT004A1</V> <V i="2">5101FHCS1PRT004A1009L03</V> <V i="3">21</V> <V i="4">SINGLE</V> <V i="5">0</V> <V i="6">--</V> <V i="7">HSI</V> </Object> <Object rmUID="5101FHCS1VLN004A10021A0000"> <V i="1">5101FHCS1OLT004A1</V> <V i="2">--</V> <V i="3">21</V> <V i="4">SINGLE</V> <V i="5">0</V> <V i="6">--</V> <V i="7">HSI</V> </Object> <Object rmUID="5101FHCS1VLN004A10022L0903"> <V i="1">5101FHCS1OLT004A1</V> <V i="2">5101FHCS1PRT004A1009L03</V> <V i="3">22</V> <V i="4">SINGLE</V> <V i="5">0</V> <V i="6">--</V> <V i="7">HSI</V> </Object> </FieldValue> </Objects> </DataFile> '''
# -*- coding: utf-8 -*-
""" @Author : sunbo @Time : 2022/7/26 0024 上午 9:19 @Comment : """
import csv
from xml.dom.minidom import parse
import os
import time
date_ = time.strftime("%Y%m%d",time.localtime())
dst_file_path = "D:\\"+date_+ "\CM"
if not os.path.exists(dst_file_path):
os.makedirs(dst_file_path)
else:
print(dst_file_path)
def readXML():
domTree = parse("CM-PON-VLN-A1-V1.0.0-20220720120000-002.xml")
# 文檔根元素
rootNode = domTree.documentElement
print(rootNode.nodeName)
table_heads = rootNode.getElementsByTagName("FieldName")
print(len(table_heads))
print("****所有表頭信息****:",table_heads)
for table_head in table_heads:
name = table_head.getElementsByTagName("N")[0]
v_nermuid = name.childNodes[0].data
name = table_head.getElementsByTagName("N")[1]
v_portrmuid = name.childNodes[0].data
name = table_head.getElementsByTagName("N")[2]
v_vlanid = name.childNodes[0].data
name = table_head.getElementsByTagName("N")[3]
v_lanmode = name.childNodes[0].data
name = table_head.getElementsByTagName("N")[4]
v_mvlanflag = name.childNodes[0].data
name = table_head.getElementsByTagName("N")[5]
v_mvlanpri = name.childNodes[0].data
name = table_head.getElementsByTagName("N")[6]
v_service = name.childNodes[0].data
headers = [v_nermuid,v_portrmuid,v_vlanid,v_lanmode,v_mvlanflag,v_mvlanpri,v_service]
with open(dst_file_path+"\\"+"new"+date_+".csv",'w',newline="") as f:
writer = csv.writer(f,delimiter = '|')
writer.writerow(headers)
objects = rootNode.getElementsByTagName("Object")
print("****所有記錄信息****")
for object in objects:
if object.hasAttribute("rmUID"):
v_nermuid_value = object.getAttribute("rmUID")
name = object.getElementsByTagName("V")[0]
v_portrmuid_value = name.childNodes[0].data
name = object.getElementsByTagName("V")[1]
v_vlanid_value = name.childNodes[0].data
name = object.getElementsByTagName("V")[2]
v_lanmode_value = name.childNodes[0].data
name = object.getElementsByTagName("V")[3]
v_mvlanflag_value = name.childNodes[0].data
name = object.getElementsByTagName("V")[4]
v_mvlanpri_value =name.childNodes[0].data
name = object.getElementsByTagName("V")[5]
v_service_value = name.childNodes[0].data
data_value = [v_nermuid_value,v_portrmuid_value,v_vlanid_value,
v_lanmode_value,v_mvlanflag_value,v_mvlanpri_value,v_service_value]
with open(dst_file_path+"\\"+"new"+date_+".csv", "a+",newline="") as f:
writer = csv.writer(f, delimiter='|')
writer.writerow(data_value)
if __name__ == '__main__':
readXML()