默認情況下,SOAPpy使用方法名稱作爲HTTP SOAPAction
標頭的值。如果您運行下面的代碼,你會看到在調試輸出值:
from SOAPpy import SOAPProxy
from datetime import datetime
input = datetime.now()
namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
proxy = SOAPProxy(url, namespace)
proxy.config.debug = 1
proxy.GetCursOnDate(input)
調試表明這一點:
*** Outgoing HTTP headers ***************************
POST /DailyInfoWebServ/DailyInfo.asmx HTTP/1.0
Host: www.cbr.ru
User-agent: SOAPpy 0.12.5 (http://pywebsvcs.sf.net)
Content-type: text/xml; charset=UTF-8
Content-length: 406
SOAPAction: "GetCursOnDate"
*****************************************************
但服務需要另一個值(http://web.cbr.ru/GetCursOnDate
),您可以在設置代理與一個額外的參數。 下面的代碼清除錯誤:
from SOAPpy import SOAPProxy
from datetime import datetime
input = datetime.now()
namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
soapaction = "http://web.cbr.ru/GetCursOnDate"
proxy = SOAPProxy(url, namespace = namespace, soapaction = soapaction)
proxy.config.debug = 1
proxy.GetCursOnDate(input)
調試現在將顯示此:
*** Outgoing HTTP headers ***************************
POST /DailyInfoWebServ/DailyInfo.asmx HTTP/1.0
Host: www.cbr.ru
User-agent: SOAPpy 0.12.5 (http://pywebsvcs.sf.net)
Content-type: text/xml; charset=UTF-8
Content-length: 406
SOAPAction: "http://web.cbr.ru/GetCursOnDate"
*****************************************************
但是,雖然特定故障消失了,電話將無法工作。因爲你會回來的問題,我想我會留下一些消息交流,直接寫續集。我提到了我對Python的SOAP支持on another occasion的失望。對於這篇文章,我在這裏添加所有的細節作爲對我自己的參考,並希望作爲其他用戶的幫助。所以在這裏...
該調用將不起作用,因爲默認情況下,SOAPpy使用有序參數進行調用。它們被稱爲v1
,v2
,v3
等(請參閱SOAPpy下載中的MethodParameterNaming.txt
文件以獲取更多詳細信息)。您的SOAP消息看起來就像這樣:
<SOAP-ENV:Body>
<ns1:GetCursOnDate xmlns:ns1="http://web.cbr.ru/" SOAP-ENC:root="1">
<v1>
</v1>
</ns1:GetCursOnDate>
</SOAP-ENV:Body>
這個特定的Web服務期待一個名爲On_date
,不v1
參數。你可以嘗試使用命名參數來解決這個問題:
from SOAPpy import SOAPProxy
from datetime import datetime
input = datetime.now()
namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
soapaction = "http://web.cbr.ru/GetCursOnDate"
proxy = SOAPProxy(url, namespace = namespace, soapaction = soapaction)
proxy.config.debug = 1
proxy.GetCursOnDate(On_date = input)
你的消息現在看起來是這樣的:
<SOAP-ENV:Body>
<ns1:GetCursOnDate xmlns:ns1="http://web.cbr.ru/" SOAP-ENC:root="1">
<On_date>
</On_date>
</ns1:GetCursOnDate>
</SOAP-ENV:Body>
我想日期的值丟失,因爲代理與datetime
對象的問題。我沒有實際檢查以確定問題所在,因爲此消息存在另一個問題:Web服務期望<ns1:On_date>
不是<On_date>
。
這是SOAPpy在命名空間中遇到的一些問題。使用原始的SOAPpy源代碼,您不能更改命名空間。看起來,對於大多數Python的SOAP庫,您只能通過調整代碼來獲得所需的行爲,這正是我所做的。我在某些處理名稱空間和標記前綴的地方更改了SOAPBuilder.py
文件。請參閱原始文件here和更改的here。
這些變化讓我用一個SOAPpy的類型用於在消息的更精細的控制:
from SOAPpy import SOAPProxy
from SOAPpy import Types
namespace = "http://web.cbr.ru/"
url = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"
soapaction = "http://web.cbr.ru/GetCursOnDate"
input = Types.dateType(name = (namespace, "On_date"))
proxy = SOAPProxy(url, namespace = namespace, soapaction = soapaction)
proxy.config.debug = 1
proxy.GetCursOnDate(input)
現在我得到我一直在尋找的結果:
<SOAP-ENV:Body>
<ns1:GetCursOnDate xmlns:ns1="http://web.cbr.ru/" SOAP-ENC:root="1">
<ns1:On_date xsi:type="xsd:date">2013-11-02Z</ns1:On_date>
</ns1:GetCursOnDate>
</SOAP-ENV:Body>
服務器返回關於上述請求的數據。
但是即使是上面的代碼也可以改進。請注意,我將SOAPAction
設置爲代理服務器上的一項特定操作:GetCursOnDate
。如果我想用另一個操作,我需要另一個代理或我需要修改這個。通過使用WSDL.Proxy
,您可以從WSDL中自動獲取該文件(它提供了一個SOAPProxy
包裝器,用於解析來自Web服務的WSDL的方法名稱,名稱空間和SOAPAction
)。
但即使這會自動處理SOAPAction
,它不會爲該方法拾取名稱空間。所以我調整了WSDL.py
文件。原始版本是here,更改的文件是here。新的客戶端的代碼現在看起來是這樣的:
from SOAPpy import WSDL
from SOAPpy import Types
# you can download this and use it locally for better performance
wsdl = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?wsdl"
namespace = "http://web.cbr.ru/"
input = Types.dateType(name = (namespace, "On_date"))
proxy = WSDL.Proxy(wsdl, namespace = namespace)
proxy.soapproxy.config.debug = 1
proxy.GetCursOnDate(input)
對於上面我使用的Python 2.6.6,SOAPpy的0.12.5,fpconst 0.7.2和wstools 0.4.3的例子。對於其他人,我認爲YMMV取決於您所調用的版本或特定的Web服務。總之我還想提一提,如果你在Google上搜索,你會發現大多數人推薦使用SUDS而不是SOAPpy作爲SOAP客戶端,所以也許可以看一下。祝你好運!