Найти - Пользователи
Полная версия: python soap zeen где данные?
Начало » Network » python soap zeen где данные?
1 2
CoLoR
print(result._value_1):
 [<Schema(location=None, tns=None)>, <Element {urn:schemas-microsoft-com:xml-diffgram-v1}diffgram at 0x3e8d648>]

print(result._value_2):
 None

От себя добавлю: я вроде умею пользоваться отладчиком, после запроса я прошерстил все variables которые вообще используются на данный момент, но там нет необходимых мне данных.
В PHP в результатах есть массив diffgram в котором и находятся все необходимые данные, а здесь - нет.
py.user.next
CoLoR
но там нет необходимых мне данных
Ты предлагаешь догадываться, каких у тебя данных нет. Ты не заметил, что ты вообще не написал, что тебе приходит? Дал только какой-то похожий сайт.

CoLoR
В PHP в результатах есть массив diffgram
А это что?
<Element {urn:schemas-microsoft-com:xml-diffgram-v1}diffgram at 0x3e8d648>

CoLoR
я вроде умею пользоваться отладчиком
Вот где это подтверждено? Ты даже через Wireshark не проверил, приходят ли тебе одни и те же данные на оба скрипта. То есть ты можешь спокойно какую-то фигню додумать и пытаться её решить, а там вообще что-нибудь другое пришло.
CoLoR
py.user.next
Ты предлагаешь догадываться, каких у тебя данных нет. Ты не заметил, что ты вообще не написал, что тебе приходит? Дал только какой-то похожий сайт.
Сорри, сейчас исправлюсь. Сайт дал, т.к. он общедоступный, и ситуация идентичная. Можно даже забыть о моём внутреннем soap сервисе, а отработать на этом, что я даю здесь, от центробанка.

py.user.next
А это что?
<Element {urn:schemas-microsoft-com:xml-diffgram-v1}diffgram at 0x3e8d648>
На сколько я понимаю, это что-то вроде заголовков/схемы но не данные.

py.user.next
Вот где это подтверждено?
исправляюсь:

Итак, берём общедоступный soap-сервис от центробанка и тестим на нём:

Test #1 (c включенной опцией (raw_response=True))
код скрипта:
 from zeep import Client
from datetime import datetime, timedelta
client = Client("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?wsdl", strict=False)
with client.options(raw_response=True):
    result = client.service.OstatDepo((datetime.now() - timedelta(days=2)),datetime.now())
print(result.text)

Wireshark сформированный запрос:
<?xml version='1.0' encoding='utf-8'?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/“>
<soap-env:Body>
<ns0:OstatDepo xmlns:ns0=”http://web.cbr.ru/">
<ns0:fromDate>2018-02-08T08:57:37.802996</ns0:fromDate>
<ns0:ToDate>2018-02-10T08:57:37.802996</ns0:ToDate>
</ns0:OstatDepo>
</soap-env:Body>
</soap-env:Envelope>

Wireshark ответ сервиса:
<?xml version=“1.0” encoding=“utf-8”?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns:xsd=”http://www.w3.org/2001/XMLSchema“>
<soap:Body>
<OstatDepoResponse xmlns=”http://web.cbr.ru/“>
<OstatDepoResult>
<xs:schema id=”OD“ xmlns=”“ xmlns:xs=”http://www.w3.org/2001/XMLSchema“ xmlns:msdata=”urn:schemas-microsoft-com:xml-msdata“>
<xs:element name=”OD“ msdata:IsDataSet=”true“ msdata:UseCurrentLocale=”true“>
<xs:complexType>
<xs:choice minOccurs=”0“ maxOccurs=”unbounded“>
<xs:element name=”odr“>
<xs:complexType>
<xs:sequence>
<xs:element name=”D0“ msdata:Caption=”“ type=”xs:dateTime“ minOccurs=”0“ />
<xs:element name=”D1_7“ msdata:Caption=” 1 7 “ type=”xs:decimal“ minOccurs=”0“ />
<xs:element name=”D8_30“ msdata:Caption=” 8 30 “ type=”xs:decimal“ minOccurs=”0“ />
<xs:element name=”depo“ msdata:Caption=” “ type=”xs:decimal“ minOccurs=”0“ />
<xs:element name=”total“ msdata:Caption=”“ type=”xs:decimal“ minOccurs=”0“ />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata=”urn:schemas-microsoft-com:xml-msdata“ xmlns:diffgr=”urn:schemas-microsoft-com:xml-diffgram-v1“>
<OD xmlns=”“>
<odr diffgr:id=”odr1“ msdata:rowOrder=”0">
<D0>2018-02-09T00:00:00+03:00</D0>
<D1_7>3005371.02</D1_7>
<depo>7890.29</depo>
<total>3013261.31</total>
</odr>
</OD>
</diffgr:diffgram>
</OstatDepoResult>
</OstatDepoResponse>
</soap:Body>
</soap:Envelope>


результат работы скрипта в консоли:
 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.
xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><OstatDepoResponse xml
ns="http://web.cbr.ru/"><OstatDepoResult><xs:schema id="OD" xmlns="" xmlns:xs="h
ttp://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msd
ata"><xs:element name="OD" msdata:IsDataSet="true" msdata:UseCurrentLocale="true
"><xs:complexType><xs:choice minOccurs="0" maxOccurs="unbounded"><xs:element nam
e="odr"><xs:complexType><xs:sequence><xs:element name="D0" msdata:Caption="Дата"
 type="xs:dateTime" minOccurs="0" /><xs:element name="D1_7" msdata:Caption="от 1
 до 7 дней" type="xs:decimal" minOccurs="0" /><xs:element name="D8_30" msdata:Ca
ption="от 8 до 30 дней" type="xs:decimal" minOccurs="0" /><xs:element name="depo
" msdata:Caption="до востребования" type="xs:decimal" minOccurs="0" /><xs:elemen
t name="total" msdata:Caption="Итого" type="xs:decimal" minOccurs="0" /></xs:seq
uence></xs:complexType></xs:element></xs:choice></xs:complexType></xs:element></
xs:schema><diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" x
mlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"><OD xmlns=""><odr diffgr
:id="odr1" msdata:rowOrder="0"><D0>2018-02-09T00:00:00+03:00</D0><D1_7>3005371.0
2</D1_7><depo>7890.29</depo><total>3013261.31</total></odr></OD></diffgr:diffgra
m></OstatDepoResult></OstatDepoResponse></soap:Body></soap:Envelope>



Test #2 (c ВЫключенной опцией (raw_response=False))
скрипт:
 from zeep import Client
from datetime import datetime, timedelta
client = Client("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?wsdl", strict=False)
with client.options(raw_response=False):
    result = client.service.OstatDepo((datetime.now() - timedelta(days=2)),datetime.now())
print(result)

Wireshark мой запрос:
<?xml version='1.0' encoding='utf-8'?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/“>
<soap-env:Body>
<ns0:OstatDepo xmlns:ns0=”http://web.cbr.ru/">
<ns0:fromDate>2018-02-08T09:07:57.479439</ns0:fromDate>
<ns0:ToDate>2018-02-10T09:07:57.479439</ns0:ToDate>
</ns0:OstatDepo>
</soap-env:Body>
</soap-env:Envelope>

Wireshark ответ:
<?xml version=“1.0” encoding=“utf-8”?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns:xsd=”http://www.w3.org/2001/XMLSchema“>
<soap:Body>
<OstatDepoResponse xmlns=”http://web.cbr.ru/“>
<OstatDepoResult>
<xs:schema id=”OD“ xmlns=”“ xmlns:xs=”http://www.w3.org/2001/XMLSchema“ xmlns:msdata=”urn:schemas-microsoft-com:xml-msdata“>
<xs:element name=”OD“ msdata:IsDataSet=”true“ msdata:UseCurrentLocale=”true“>
<xs:complexType>
<xs:choice minOccurs=”0“ maxOccurs=”unbounded“>
<xs:element name=”odr“>
<xs:complexType>
<xs:sequence>
<xs:element name=”D0“ msdata:Caption=”“ type=”xs:dateTime“ minOccurs=”0“ />
<xs:element name=”D1_7“ msdata:Caption=” 1 7 “ type=”xs:decimal“ minOccurs=”0“ />
<xs:element name=”D8_30“ msdata:Caption=” 8 30 “ type=”xs:decimal“ minOccurs=”0“ />
<xs:element name=”depo“ msdata:Caption=” “ type=”xs:decimal“ minOccurs=”0“ />
<xs:element name=”total“ msdata:Caption=”“ type=”xs:decimal“ minOccurs=”0“ />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata=”urn:schemas-microsoft-com:xml-msdata“ xmlns:diffgr=”urn:schemas-microsoft-com:xml-diffgram-v1“>
<OD xmlns=”“>
<odr diffgr:id=”odr1“ msdata:rowOrder=”0">
<D0>2018-02-09T00:00:00+03:00</D0>
<D1_7>3005371.02</D1_7>
<depo>7890.29</depo>
<total>3013261.31</total>
</odr>
</OD>
</diffgr:diffgram>
</OstatDepoResult>
</OstatDepoResponse>
</soap:Body>
</soap:Envelope>

результат работы скрипта в консоли:
 {
    'schema': <Schema(location=None, tns=None)>,
    '_value_1': <Element {urn:schemas-microsoft-com:xml-diffgram-v1}diffgram at
0x3422a80>
}


ИТОГО: в обоих случаях формируется одинаковый запрос (меняется только время datetime, не суть важно), ответ - идентичен, что с включенным параметром, что с выключенным. То есть фактически данные приходят, но zeep не формирует из них массив с данными и не передаёт пользователю.
Вопросы: 1) где данные? как их получить в массив?
2) может быть полученные данные (при включенной опции raw_response=True) можно как то легко парсить в массив?
py.user.next
  
>>> from zeep import Client
>>> from datetime import datetime, timedelta
>>> 
>>> client = Client("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?wsdl", strict=False)
>>> 
>>> with client.options(raw_response=False):
...     result = client.service.OstatDepo((datetime.now() - timedelta(days=2)),datetime.now())
... 
>>> print(result)
{
    'schema': <Schema(location=None, tns=None)>,
    '_value_1': <Element {urn:schemas-microsoft-com:xml-diffgram-v1}diffgram at 0x7f9011d687c8>
}
>>> [i.text for i in result._value_1[0][0]]
['2018-02-09T00:00:00+03:00', '3005371.02', '7890.29', '3013261.31']
>>>

CoLoR
На сколько я понимаю, это что-то вроде заголовков/схемы но не данные.
Это узел с данными. Он не может его представить, поэтому просто разбирает дотуда, докуда может, а потом просто прицепляетс к атрибутам с именами _value_N неразобранные узлы.

CoLoR
2) может быть полученные данные (при включенной опции raw_response=True) можно как то легко парсить в массив?
Да конечно можно. Просто берёшь и делаешь функцию, которая принимает сырые данные, а возвращает словарь (или список, если там одинаковые элементы есть в данных). А внутри функции через lxml и встроенный в него xpath ищешь всё что нужно и составляешь из этих данных словарь. Словарь - это аналог ассоциативного массива в php, но в питоне это не одно и то же, потому что ассоциативные массивы в php имеют порядок, тогда как в питоне это классическое нагруженное множество с быстрым поиском и без порядка.

Пример обработки сырых данных
  
>>> from zeep import Client
>>> from datetime import datetime, timedelta
>>> import lxml
>>> import pprint
>>> 
>>> client = Client(
...     "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?wsdl",
...     strict=False)
>>> 
>>> with client.options(raw_response=True):
...     result = client.service.OstatDepo(
...         datetime.now() - timedelta(days=2),
...         datetime.now())
... 
>>> print(result)
<Response [200]>
>>> 
>>> def f(data):
...     doc = lxml.etree.fromstring(data)
...     nodes = doc.xpath(
...         '//xs:element',
...         namespaces={'xs': 'http://www.w3.org/2001/XMLSchema'})
...     out = [i.attrib for i in nodes]
...     return out
... 
>>> data = f(result.content)
>>> pprint.pprint(data)
[{'name': 'OD', '{urn:schemas-microsoft-com:xml-msdata}IsDataSet': 'true', '{urn:schemas-microsoft-com:xml-msdata}UseCurrentLocale': 'true'},
 {'name': 'odr'},
 {'name': 'D0', '{urn:schemas-microsoft-com:xml-msdata}Caption': 'Дата', 'type': 'xs:dateTime', 'minOccurs': '0'},
 {'name': 'D1_7', '{urn:schemas-microsoft-com:xml-msdata}Caption': 'от 1 до 7 дней', 'type': 'xs:decimal', 'minOccurs': '0'},
 {'name': 'D8_30', '{urn:schemas-microsoft-com:xml-msdata}Caption': 'от 8 до 30 дней', 'type': 'xs:decimal', 'minOccurs': '0'},
 {'name': 'depo', '{urn:schemas-microsoft-com:xml-msdata}Caption': 'до востребования', 'type': 'xs:decimal', 'minOccurs': '0'},
 {'name': 'total', '{urn:schemas-microsoft-com:xml-msdata}Caption': 'Итого', 'type': 'xs:decimal', 'minOccurs': '0'}]
>>> 
Тут не стал удалять пространства имён (они затрудняют взятие значений по ключу), но всё это так же можно удалить внутри функции, чтобы на выход в словаре шли только нужные данные.
CoLoR
Спасибо большое. То есть проблема всё же в zeep - не разбирает ответ в словарь.
Я на гитхабе по zeep обнаружил аналогичные запросы от пользователей, и ответа им пока не дали. Zeep отлично отрабатывает когда в ответе String, пусть даже несколько, а вот когда та xml - то, с чем я столкнулся, вот
py.user.next
Ну вот он пишет
http://docs.python-zeep.org/en/master/
The SOAP specifications are unfortunately really vague and leave a lot of things open for interpretation. Due to this there are a lot of WSDL documents available which are invalid or SOAP servers which contain bugs. Zeep tries to be as compatible as possible but there might be cases where you run into problems. Don’t hesitate to submit an issue in this case (but please first read Reporting bugs).
Он, видимо, разбирает только то, в чём уверен в соответствии со спецификацией. Может быть и баг, конечно, у него в модуле, раз куда-то данные вообще пропадают. Обычно принято такое складывать куда-то, даже если оно неправильное.
CoLoR
Я задавал свой вопрос разработчику zeep, вчера получил ответ:
The call returns an any without a schema. So zeep has no idea how to parse the result.
I can add a lxml element to dict, need to think about that

Спасибо большое py.user.next за отклик в теме и набросанную функцию для разбора сырого ответа, в ближайшее время пойду по этому пути.
py.user.next
Да похоже, что у него баг там. Он и сам думает “куда оно делось?”.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB