默认的Python xmlrpc.client.Transport
(可与xmlrpc.client.ServerProxy
一起使用)不会保留cookie,这有时是基于cookie的登录所需的。
例如,以下代理与TapaTalk API(login
method使用Cookie进行身份验证时)一起使用时,在尝试修改帖子时会出现权限错误。
proxy = xmlrpc.client.ServerProxy(URL, xmlrpc.client.Transport())
网上有{2}的Python {2},但它们与Python 3不兼容。
如何使用保留Cookie的Transport
?
答案 0 :(得分:4)
GermainZ的现有答案仅适用于HTTP。经过大量的时间与之斗争,有适应HTTPS。请注意context
选项至关重要。
class CookiesTransport(xmlrpc.client.SafeTransport):
"""A SafeTransport (HTTPS) subclass that retains cookies over its lifetime."""
# Note context option - it's required for success
def __init__(self, context=None):
super().__init__(context=context)
self._cookies = []
def send_headers(self, connection, headers):
if self._cookies:
connection.putheader("Cookie", "; ".join(self._cookies))
super().send_headers(connection, headers)
def parse_response(self, response):
# This check is required if in some responses we receive no cookies at all
if response.msg.get_all("Set-Cookie"):
for header in response.msg.get_all("Set-Cookie"):
cookie = header.split(";", 1)[0]
self._cookies.append(cookie)
return super().parse_response(response)
原因是ServerProxy不尊重与传输相关的context
选项,如果指定了传输,那么我们需要在传输构造函数中直接使用它。
用法:
import xmlrpc.client
import ssl
transport = CookiesTransport(context=ssl._create_unverified_context())
# Note the closing slash in address as well, very important
server = xmlrpc.client.ServerProxy("https://<api_link>/", transport=transport)
# do stuff with server
server.myApiFunc({'param1': 'x', 'param2': 'y'})
答案 1 :(得分:1)
这是一个简单的Transport
子类,它将保留所有cookie:
class CookiesTransport(xmlrpc.client.Transport):
"""A Transport subclass that retains cookies over its lifetime."""
def __init__(self):
super().__init__()
self._cookies = []
def send_headers(self, connection, headers):
if self._cookies:
connection.putheader("Cookie", "; ".join(self._cookies))
super().send_headers(connection, headers)
def parse_response(self, response):
for header in response.msg.get_all("Set-Cookie"):
cookie = header.split(";", 1)[0]
self._cookies.append(cookie)
return super().parse_response(response)
用法:
proxy = xmlrpc.client.ServerProxy(URL, CookiesTransport())
由于Python 3中的xmlrpc.client
具有更适合的钩子,因此它比等效的Python 2版本简单得多。