如何使用 pysimplesoap 构造 SOAP 消息?
How to construct SOAP message with pysimplesoap?
我正在尝试从荷兰政府土地登记处调用 SOAP 服务(WSDL here) with PySimpleSoap。到目前为止,我这样做是为了连接:
from pysimplesoap.client import SoapClient
client = SoapClient(wsdl='http://www1.kadaster.nl/1/schemas/kik-inzage/20141101/verzoekTotInformatie-2.1.wsdl')
在 的帮助下,我现在明白我需要使用 client.VerzoekTotInformatie()
方法发送下面的 xml。
然而,我不明白的是如何获得所需的 XML(见下文)。我当然可以手动构建它,但我感觉有一种 smarter/more pythonic 方式来构建它。我可以使用 pysimplesoap 来构造此消息吗 xml?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.kadaster.nl/schemas/kik-inzage/20141101" xmlns:v20="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
<soapenv:Header/>
<soapenv:Body>
<ns:VerzoekTotInformatieRequest>
<v20:Aanvraag>
<v20:berichtversie>?</v20:berichtversie>
<v20:klantReferentie>ABC</v20:klantReferentie>
<v20:productAanduiding>?</v20:productAanduiding>
<v20:Ingang>
<v20:Object>
<v20:IMKAD_KadastraleAanduiding>
<v20:gemeente>Amsterdam</v20:gemeente>
<v20:sectie>123</v20:sectie>
<v20:perceelnummer>456</v20:perceelnummer>
<v20:appartementsindex>789</v20:appartementsindex>
<v20:deelperceelnummer>10</v20:deelperceelnummer>
<v20:AKRKadastraleGemeenteCode>20</v20:AKRKadastraleGemeenteCode>
</v20:IMKAD_KadastraleAanduiding>
</v20:Object>
</v20:Ingang>
</v20:Aanvraag>
</ns:VerzoekTotInformatieRequest>
</soapenv:Body>
</soapenv:Envelope>
[编辑]
按照 the docs 中的示例,我现在尝试添加带有 berichtversie
的 VerzoekTotInformatieRequest,之后我尝试向 soap-service 发出请求。但是正如您在下面看到的,主体仍然只有一个空的 <VerzoekTotInformatie>
(其中没有 Request
),而且我得到了一个巨大的错误。我有什么想法可以构建上面的消息吗?
>>> client['VerzoekTotInformatieRequest'] = {'Aanvraag': {'berichtversie': 'yay'}}
>>> c.VerzoekTotInformatie()
INFO:pysimplesoap.client:POST https://service1.kadaster.nl/kik/inzage/20141101/VerzoekTotInformatieService
DEBUG:pysimplesoap.client:SOAPAction: "VerzoekTotInformatie"
Content-length: 378
Content-type: text/xml; charset="UTF-8"
DEBUG:pysimplesoap.client:<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header/>
<soap:Body>
<VerzoekTotInformatie xmlns="http://www.kadaster.nl/schemas/kik-inzage/20141101">
</VerzoekTotInformatie>
</soap:Body>
</soap:Envelope>
DEBUG:pysimplesoap.client:date: Fri, 24 Apr 2015 12:51:05 GMT
status: 404
content-length: 956
content-type: text/html;charset=utf-8
DEBUG:pysimplesoap.client:<html><head><title>JBossWeb/2.0.0.GA_CP05 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;b
ackground-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-s
erif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - </h1><HR si
ze="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The requested resource () is not available.</u></p><HR size="1" noshade="noshade"><h3>JBossWeb/2.0.0.GA_CP05</h3></body></html>
ERROR:pysimplesoap.simplexml:<html><head><title>JBossWeb/2.0.0.GA_CP05 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:whit
e;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,san
s-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - </h1><HR
size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The requested resource () is not available.</u></p><HR size="1" noshade="noshade"><h3>JBossWeb/2.0.0.GA_CP05</h3></body></html>
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 181, in <lambda>
return lambda *args, **kwargs: self.wsdl_call(attr, *args, **kwargs)
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 346, in wsdl_call
return self.wsdl_call_with_args(method, args, kwargs)
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 370, in wsdl_call_with_args
response = self.call(method, *params)
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 262, in call
jetty=self.__soap_server in ('jetty',))
File "/Library/Python/2.7/site-packages/pysimplesoap/simplexml.py", line 56, in __init__
self.__document = xml.dom.minidom.parseString(text)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/minidom.py", line 1928, in parseString
return expatbuilder.parseString(string)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/expatbuilder.py", line 940, in parseString
return builder.parseString(string)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/expatbuilder.py", line 223, in parseString
parser.Parse(string, True)
ExpatError: mismatched tag: line 1, column 944
构造 xml 不是调用 soap 方法的必要(或正确)方式。 PySimpleSoap
已经提供了一种非常优雅且易于阅读的方式来做到这一点:
client = SoapClient(wsdl='http://www1.kadaster.nl/1/schemas/kik-inzage/20141101/verzoekTotInformatie-2.1.wsdl', trace=True)
client.VerzoekTotInformatie(Aanvraag={'berichtversie':4.7,
'klantReferentie':'cum murmure',
'productAanduiding': 'aeoliam venit'})
调试日志是这样的:
INFO:pysimplesoap.client:POST https://service1.kadaster.nl/kik/inzage/20141101/VerzoekTotInformatieService
DEBUG:pysimplesoap.client:SOAPAction: "VerzoekTotInformatie"
Content-length: 842
Content-type: text/xml; charset="UTF-8"
DEBUG:pysimplesoap.client:<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header/>
<soap:Body>
<VerzoekTotInformatieRequest xmlns="http://www.kadaster.nl/schemas/kik-inzage/20141101">
<Aanvraag xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
<berichtversie xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">4.7000000000</berichtversie>
<klantReferentie xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">cum murmure</klantReferentie>
<productAanduiding xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">aeoliam venit</productAanduiding>
</Aanvraag>
</VerzoekTotInformatieRequest>
</soap:Body>
</soap:Envelope>
如您所见,xml 是自动构建并发送到服务器的。但是我遇到了 401: Unauthorized
错误,您可能知道如何修复。
我正在尝试从荷兰政府土地登记处调用 SOAP 服务(WSDL here) with PySimpleSoap。到目前为止,我这样做是为了连接:
from pysimplesoap.client import SoapClient
client = SoapClient(wsdl='http://www1.kadaster.nl/1/schemas/kik-inzage/20141101/verzoekTotInformatie-2.1.wsdl')
在 client.VerzoekTotInformatie()
方法发送下面的 xml。
然而,我不明白的是如何获得所需的 XML(见下文)。我当然可以手动构建它,但我感觉有一种 smarter/more pythonic 方式来构建它。我可以使用 pysimplesoap 来构造此消息吗 xml?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.kadaster.nl/schemas/kik-inzage/20141101" xmlns:v20="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
<soapenv:Header/>
<soapenv:Body>
<ns:VerzoekTotInformatieRequest>
<v20:Aanvraag>
<v20:berichtversie>?</v20:berichtversie>
<v20:klantReferentie>ABC</v20:klantReferentie>
<v20:productAanduiding>?</v20:productAanduiding>
<v20:Ingang>
<v20:Object>
<v20:IMKAD_KadastraleAanduiding>
<v20:gemeente>Amsterdam</v20:gemeente>
<v20:sectie>123</v20:sectie>
<v20:perceelnummer>456</v20:perceelnummer>
<v20:appartementsindex>789</v20:appartementsindex>
<v20:deelperceelnummer>10</v20:deelperceelnummer>
<v20:AKRKadastraleGemeenteCode>20</v20:AKRKadastraleGemeenteCode>
</v20:IMKAD_KadastraleAanduiding>
</v20:Object>
</v20:Ingang>
</v20:Aanvraag>
</ns:VerzoekTotInformatieRequest>
</soapenv:Body>
</soapenv:Envelope>
[编辑]
按照 the docs 中的示例,我现在尝试添加带有 berichtversie
的 VerzoekTotInformatieRequest,之后我尝试向 soap-service 发出请求。但是正如您在下面看到的,主体仍然只有一个空的 <VerzoekTotInformatie>
(其中没有 Request
),而且我得到了一个巨大的错误。我有什么想法可以构建上面的消息吗?
>>> client['VerzoekTotInformatieRequest'] = {'Aanvraag': {'berichtversie': 'yay'}}
>>> c.VerzoekTotInformatie()
INFO:pysimplesoap.client:POST https://service1.kadaster.nl/kik/inzage/20141101/VerzoekTotInformatieService
DEBUG:pysimplesoap.client:SOAPAction: "VerzoekTotInformatie"
Content-length: 378
Content-type: text/xml; charset="UTF-8"
DEBUG:pysimplesoap.client:<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header/>
<soap:Body>
<VerzoekTotInformatie xmlns="http://www.kadaster.nl/schemas/kik-inzage/20141101">
</VerzoekTotInformatie>
</soap:Body>
</soap:Envelope>
DEBUG:pysimplesoap.client:date: Fri, 24 Apr 2015 12:51:05 GMT
status: 404
content-length: 956
content-type: text/html;charset=utf-8
DEBUG:pysimplesoap.client:<html><head><title>JBossWeb/2.0.0.GA_CP05 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;b
ackground-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-s
erif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - </h1><HR si
ze="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The requested resource () is not available.</u></p><HR size="1" noshade="noshade"><h3>JBossWeb/2.0.0.GA_CP05</h3></body></html>
ERROR:pysimplesoap.simplexml:<html><head><title>JBossWeb/2.0.0.GA_CP05 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:whit
e;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,san
s-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - </h1><HR
size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The requested resource () is not available.</u></p><HR size="1" noshade="noshade"><h3>JBossWeb/2.0.0.GA_CP05</h3></body></html>
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 181, in <lambda>
return lambda *args, **kwargs: self.wsdl_call(attr, *args, **kwargs)
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 346, in wsdl_call
return self.wsdl_call_with_args(method, args, kwargs)
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 370, in wsdl_call_with_args
response = self.call(method, *params)
File "/Library/Python/2.7/site-packages/pysimplesoap/client.py", line 262, in call
jetty=self.__soap_server in ('jetty',))
File "/Library/Python/2.7/site-packages/pysimplesoap/simplexml.py", line 56, in __init__
self.__document = xml.dom.minidom.parseString(text)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/minidom.py", line 1928, in parseString
return expatbuilder.parseString(string)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/expatbuilder.py", line 940, in parseString
return builder.parseString(string)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/dom/expatbuilder.py", line 223, in parseString
parser.Parse(string, True)
ExpatError: mismatched tag: line 1, column 944
构造 xml 不是调用 soap 方法的必要(或正确)方式。 PySimpleSoap
已经提供了一种非常优雅且易于阅读的方式来做到这一点:
client = SoapClient(wsdl='http://www1.kadaster.nl/1/schemas/kik-inzage/20141101/verzoekTotInformatie-2.1.wsdl', trace=True)
client.VerzoekTotInformatie(Aanvraag={'berichtversie':4.7,
'klantReferentie':'cum murmure',
'productAanduiding': 'aeoliam venit'})
调试日志是这样的:
INFO:pysimplesoap.client:POST https://service1.kadaster.nl/kik/inzage/20141101/VerzoekTotInformatieService
DEBUG:pysimplesoap.client:SOAPAction: "VerzoekTotInformatie"
Content-length: 842
Content-type: text/xml; charset="UTF-8"
DEBUG:pysimplesoap.client:<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header/>
<soap:Body>
<VerzoekTotInformatieRequest xmlns="http://www.kadaster.nl/schemas/kik-inzage/20141101">
<Aanvraag xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">
<berichtversie xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">4.7000000000</berichtversie>
<klantReferentie xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">cum murmure</klantReferentie>
<productAanduiding xmlns="http://www.kadaster.nl/schemas/kik-inzage/ip-aanvraag/v20141101">aeoliam venit</productAanduiding>
</Aanvraag>
</VerzoekTotInformatieRequest>
</soap:Body>
</soap:Envelope>
如您所见,xml 是自动构建并发送到服务器的。但是我遇到了 401: Unauthorized
错误,您可能知道如何修复。