如何用Python Zeep/Requests调用Oracle BI Publisher SOAP接口导出CSV
问题原因与修复方案
1. Requests模块代码修复
原代码问题
- 误用
GET请求发送SOAP载荷,SOAP协议要求调用操作必须使用POST请求 - 请求URL携带
?wsdl后缀,该地址仅用于获取WSDL定义,实际服务调用端点为去掉?wsdl的地址
修正后代码
import requests import base64 from requests.auth import HTTPBasicAuth from xml.etree import ElementTree # 注意去掉末尾的?wsdl,这是实际服务调用端点 url = "https://xxxx.yyyy.us6.oraclecloud.com/xmlpserver/services/ExternalReportWSSService" headers = {'Content-Type': 'text/xml;charset=utf-8'} body = """<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:pub="http://xmlns.oracle.com/oxp/service/PublicReportService"> <soap:Header/> <soap:Body> <pub:runReport> <pub:reportRequest> <pub:attributeFormat>csv</pub:attributeFormat> <pub:flattenXML>false</pub:flattenXML> <pub:parameterNameValues> <pub:item> <pub:name>p_name</pub:name> <pub:values> <pub:item>tapan</pub:item> </pub:values> </pub:item> </pub:parameterNameValues> <pub:reportAbsolutePath>/Custom/Integration/test_data_rpt.xdo</pub:reportAbsolutePath> <pub:sizeOfDataChunkDownload>-1</pub:sizeOfDataChunkDownload> </pub:reportRequest> </pub:runReport> </soap:Body> </soap:Envelope>""" # 改为POST请求 response = requests.post(url, data=body, headers=headers, auth=HTTPBasicAuth('XXXX', 'XXXX')) # 解析返回的XML提取base64编码的CSV内容 root = ElementTree.fromstring(response.content) # 定位reportBytes节点 ns = {'pub': 'http://xmlns.oracle.com/oxp/service/PublicReportService'} report_bytes = root.find('.//pub:reportBytes', ns).text # 解码base64保存为CSV with open('report.csv', 'wb') as f: f.write(base64.b64decode(report_bytes))
2. Zeep模块代码修复
原代码问题
Zeep是SOAP客户端封装工具,会自动根据WSDL生成请求结构,无需手动拼接完整SOAP信封,直接传入符合参数规范的字典即可。
修正后代码
import base64 from zeep import Client from requests import Session from requests.auth import HTTPBasicAuth from zeep.transports import Transport wsdl = "https://XXXX.XXXX.us6.oraclecloud.com/xmlpserver/services/ExternalReportWSSService?wsdl" session = Session() session.auth = HTTPBasicAuth('XXXX', 'XXXX') client = Client(wsdl, transport=Transport(session=session)) # 按照WSDL定义的参数结构构造字典即可 report_request = { 'attributeFormat': 'csv', 'flattenXML': False, 'parameterNameValues': { 'item': [ { 'name': 'p_name', 'values': {'item': ['tapan']} } # 第二个参数需要时直接在列表内追加即可 ] }, 'reportAbsolutePath': '/Custom/Integration/test_data_rpt.xdo', 'sizeOfDataChunkDownload': -1 } # 直接传构造好的请求字典 response = client.service.runReport(reportRequest=report_request) # 解码返回的base64内容保存为CSV with open('report.csv', 'wb') as f: f.write(base64.b64decode(response['reportBytes']))
内容的提问来源于stack exchange,提问作者tapan sharma
相关产品推荐
相关产品推荐

