Python:将xmlrpc模块与需要身份验证的服务器一起使用

时间:2015-06-24 09:58:44

标签: python xml python-requests rpc xml-rpc

我想使用Python脚本查询XML-RPC服务器。

第一个障碍是服务器使用身份验证,我不得不求助于request.Session来克服这个问题。现在我做了,我可以通过RPC查询服务器,但我正在使用相当丑陋的机制来做 - 粘合字符串。当然,这只会产生XML数据,我将再次手动处理它以将其转换为可用的列表或字典。

我发现有一个用于Python的xmlrpc模块,它允许干净地使用服务器;但是,在使用XML-RPC之前,我找不到如何自我授权。

以下是我已使用请求编写的代码:

from requests import Session

myserver_address='http://myserver.test.com/admin'
myserver_RPC=myserver_address+'?RPC2'
myserver_header={'Content-Type': "text/xml; charset=UTF-8"}
myserver_login={"srvAction":"LoginAdmin", "login":"testuser", "password":"testpassword", "Submit":"Login", "select_locale":"en"}
myserver_login2={"srvAction":"LoginOrg", "selectSection":"20", "submit":"Continue"}

method_header = '<methodCall xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions"><methodName>'
param_header = '</methodName><params>'
param_body_header = '<param><value><string>'
param_body_footer = '</string></value></param>'
method_footer = '</params></methodCall>'

def myserver_get_xml(myserver_method, myserver_method_param):
    param_body = ''

    for param in myserver_method_param:
        param_body = param_body + param_body_header + str(param) + param_body_footer

    myserver_post = method_header + myserver_method + param_header + param_body + method_footer
    page = s.post(myserver_RPC, myserver_post)
    return page.text

s = Session()
s.get(myserver_address)
s.post(myserver_address, myserver_login) 
s.post(myserver_address, myserver_login2)

s.headers.update(myserver_header)

result_xml = myserver_get_xml('myserverServer.getNetworkTree', ['31', ] )
print(result_xml)

所以问题是:

  • 如何在经过身份验证的会话中使用xmlrpc模块?

  • 如果不可能,将XML转换为字典(最好)或列表是否有好处?

示例输出:

<?xml version="1.0" encoding="UTF-8"?><methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions"><params><param><value><array><data><value><array><data><value>10.0.0.0/16</value><value><i4>1</i4></value><value>31</value></data></array></value><value><array><data><value>10.1.0.0/16</value><value><i4>2</i4></value><value>31</value></data></array></value></data></array></value></param></params></methodResponse>

2 个答案:

答案 0 :(得分:0)

您需要实现自己的specialMethod类,并在实例化xmlrpclib.ServerProxy时将其指定为传输参数。请参阅https://docs.python.org/2/library/xmlrpclib.html#example-of-client-usage上代理传输实现的示例。 您可能只需要实现和修改xmlrpclib.Transport,它需要返回一个Transport.make_connection实例,该实例具有来自您的登录操作的http响应头中的 Cookie 标头集。您无法真正使用httplib.HTTPConnection类来发出请求,因为它与其余Session类方法使用的httplib.HTTPConnection类不兼容。因此,为了简单起见,您可以使用Transport实例执行登录,提取标头(特别是cookie标头)并使用这些标头创建HTTPConnection。

Session

我不确定它是否会像这样工作,我还没有测试过。我希望它能为您提供足够的信息来尝试这种方法。

答案 1 :(得分:0)

前一段时间找到解决方案,到目前为止工作。它非常粗糙,不适合处理XML,但由于我只需要应用程序中的一些数据,它就可以工作。

#!/cygdrive/c/Python34/python.exe

from requests import Session
import sys
import json
import xmltodict

myserver_address='http://myserver.test.com/admin'
myserver_RPC=myserver_address+'?RPC2'
myserver_header={'Content-Type': "text/xml; charset=UTF-8"}
myserver_login={"srvAction":"LoginAdmin", "login":"testuser", "password":"testpassword", "Submit":"Login", "select_locale":"en"}
myserver_login2={"srvAction":"LoginOrg", "selectSection":"20", "submit":"Continue"}

s = Session()
s.get(myserver_address)
s.post(myserver_address, myserver_login) 
s.post(myserver_address, myserver_login2)

s.headers.update(myserver_header)

myserverMethod = '<methodCall xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions"><methodName>myserverMyViewUsage.getMyViewChildrenArray</methodName><params><param><value><int>602</int></value></param></params></methodCall>'
subnet_list = s.post(myserver_RPC, myserverMethod)
subnet_dictionary_coarse = xmltodict.parse(subnet_org_list.text)

#print( json.dumps(subnet_org_dictionary_coarse, indent=2))

for subnet_org_dictionary in subnet_org_dictionary_coarse['methodResponse']['params']['param']['value']['array']['data']['value']:
<put code here>

毫无疑问,这基本上是强调XML来获取我需要的数据;它是一个快速而又非常脏的&#34;破解。