前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python3 xmlrpc clien

python3 xmlrpc clien

作者头像
py3study
发布2020-01-03 11:15:39
7360
发布2020-01-03 11:15:39
举报
文章被收录于专栏:python3python3

RPC(Remote Procedure Call Protocol)是远程过程调用协议,一种不同于http协议的用于构建分布式系统。python提供xmlrpc库,下面是py2和py3的client类,可以带cookie请求数据。Show you the code:

python2

代码语言:javascript
复制
class CookieTransportRequest:
    """A Transport request method that retains cookies over its lifetime.

    The regular xmlrpclib transports ignore cookies. Which causes
    a bit of a problem when you need a cookie-based login, as with
    the XPLAN XMLRPC EDAI interface.

    So this is a helper for defining a Transport which looks for
    cookies being set in responses and saves them to add to all future
    requests.
    """
    def __init__(self, use_datetime=0):
        self._use_datetime = use_datetime
        self._connection = (None, None)
        self._extra_headers = []
        self.cookies = {}

    def extract_cookies(self, response):  # 生成cookie,具体根据应用rpc修改
        for header in response.msg.getallmatchingheaders("Set-Cookie"):
            val = header.split(':', 1)[1].strip()
            cookie = val.split(';', 1)[0].strip()
            cookiePair = cookie.split('=', 1)
            self.cookies[cookiePair[0].strip()] = cookiePair[1].strip()

    def get_cookies_header(self):
        cookieStr = ''
        for cookieName in self.cookies.keys():
            cookieStr = cookieStr + '%s=%s' % (cookieName, self.cookies[cookieName])
        return cookieStr

    def send_cookies(self, connection):
        cookieStr = ''
        for cookieName in self.cookies.keys():
            cookieStr = cookieStr + '%s=%s' % (cookieName, self.cookies[cookieName])
        if cookieStr != '':
            connection.putheader("Cookie", cookieStr)

    def login(self, host, homeUri, authUri, authBody, verbose=0):
        headers = {}
        self.verbose = verbose
        conn = self.make_connection(host)
        if verbose:
            conn.set_debuglevel(1)

        conn.request('GET', homeUri)

        try:
            response = conn.getresponse()
        except AttributeError:
            response = conn._conn.getresponse()

        self.extract_cookies(response) ##生成一个self.cookie
        response.read()  # 生成页面

        if response.status in (404,500,503,505,501):
            raise xmlrpclib.ProtocolError(host + homeUri, response.status,
                                          response.reason, response.msg.headers)
        #判断页面状态

        headers.clear()
        headers = {"Content-Type": "application/x-www-form-urlencoded","Accept": "text/plain","Connection":"keep-alive"}
        headers['Cookie'] = self.get_cookies_header()
        conn.request('POST', authUri, authBody, headers) ##进行登录
        try:
            response = conn.getresponse()
        except AttributeError:
            response = conn._conn.getresponse()

        self.extract_cookies(response)
        response.read()

        if response.status in (403,404,401,500,503,505,501):
            raise xmlrpclib.ProtocolError(host + homeUri, response.status,
                                          'Authenticate error', response.msg.headers)


        headers.clear()
        headers['Cookie'] = self.get_cookies_header() ##在header中加入cookie
        conn.request('GET', homeUri, None, headers)  ##请求这页面传入 cookie 与 header

        try:
            response = conn.getresponse()
        except AttributeError:
            response = conn._conn.getresponse()

        self.extract_cookies(response)  ##再次获取cookie
        response.read()


    def request(self, host, handler, request_body, verbose=0):
        self.verbose = verbose

        # issue XML-RPC request
        h = self.make_connection(host)
        if verbose:
            h.set_debuglevel(1)

        self.send_request(h, handler, request_body)
        self.send_host(h, host)
        self.send_cookies(h)
        self.send_user_agent(h)
        self.send_content(h, request_body)

        # Deal with differences between Python 2.4-2.6 and 2.7.
        # In the former h is a HTTP(S). In the latter it's a
        # HTTP(S)Connection. Luckily, the 2.4-2.6 implementation of
        # HTTP(S) has an underlying HTTP(S)Connection, so extract
        # that and use it.
        try:
            response = h.getresponse()
        except AttributeError:
            response = h._conn.getresponse()

        # Add any cookie definitions to our list.
        self.extract_cookies(response)

        if response.status != 200:
            raise xmlrpclib.ProtocolError(host + handler, response.status,
                                          response.reason, response.msg.headers)

#         if response.info().get('Content-Encoding') == 'gzip':
#             buf = StringIO(response.read())
#             f = gzip.GzipFile(fileobj=buf)
#             data = f.read()
#         else:
#             data = response.read()

        data = response.read()
        parser, unmarshaller = self.getparser()
        # import re, pickle
        # data = re.sub(u"[\x00-\x08\x0b-\x0c\x0e-\x1f]+", u"", data)
        # data = re.sub(u"[\n]+", u"", data)
        # print('\n', "re after:", data)
        # data = xmlrpclib.Binary(pickle.dumps(data)).data
        # import chardet
        # print chardet.detect(data)

        parser.feed(data)
        parser.close()

        return unmarshaller.close()

class CookieTransport(CookieTransportRequest, xmlrpclib.Transport):
    pass

class SafeCookieTransport(CookieTransportRequest, xmlrpclib.SafeTransport):
    pass



def getCookie():
    cookie = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
    AUTHBODY = urllib.urlencode(AUTHDATA)
    req = urllib2.Request(url='http://' + HOST + HOMEURL)
    opener.open(req)
    cookistr = ''
    for item in cookie:
        cookistr = cookistr + '%s=%s' % (item.name, item.value)
    headers = {}
    headers.clear()
    headers = {'Content-type': 'application/x-www-form-urlencoded', "Accept": "text/plain", "Connection": "keep-alive"}
    headers['Cookie'] = cookistr

    loginpage = urllib2.Request(url='http://' + HOST + AUTHURL, data=AUTHBODY, headers=headers)
    opener.open(loginpage)

    cookistr = ''
    for item in cookie:
        cookistr = cookistr + '%s=%s' % (item.name, item.value)
    headers = {}
    headers.clear()
    headers = {'Content-type': 'application/x-www-form-urlencoded', "Accept": "text/plain", "Connection": "keep-alive"}
    headers['Cookie'] = cookistr
    return headers

python3

代码语言:javascript
复制
class CookieTransportRequest:
    """A Transport request method that retains cookies over its lifetime.

    The regular xmlrpclib transports ignore cookies. Which causes
    a bit of a problem when you need a cookie-based login, as with
    the XPLAN XMLRPC EDAI interface.

    So this is a helper for defining a Transport which looks for
    cookies being set in responses and saves them to add to all future
    requests.
    """
    def __init__(self, use_datetime=0, use_builtin_types=False):
        self._use_datetime = use_datetime
        self._use_builtin_types = use_builtin_types
        self._connection = (None, None)
        self._extra_headers = []
        self.cookies = []

    def extract_cookies(self, response):
        print(response.msg.getallmatchingheaders("Set-Cookie"))
        print(response.msg.get_all("Set-Cookie"))   # 与py2的区别
        if not response.msg.getallmatchingheaders("Set-Cookie") and not response.msg.get_all("Set-Cookie"):
            print("\n extract_cookies", self.cookies)
            return self.cookies
        else:
            cookie_info = response.msg.get_all("Set-Cookie")
            if "SERVERID" in cookie_info[0]:
                return self.cookies
            self.cookies = []
            for header in cookie_info:
                self.cookies.append(header.split(";", 1)[0])
                print("\n extract_cookies", self.cookies)
                return self.cookies

    def get_cookies_header(self):
        cookieStr = ''
        for cookieName in self.cookies:
            cookieStr = cookieStr + '%s=%s' % (cookieName.split('=', 1)[0], cookieName.split('=', 1)[1])
        print("get_cookies", cookieStr)
        return cookieStr

    def send_headers(self, connection, headers):
        for key, val in headers:
            connection.putheader(key, val)

    def send_request(self, host, handler, request_body, debug):
        connection = self.make_connection(host)
        extra_headers = self._extra_headers[:]
        print("\nextra_headers", extra_headers)
        if extra_headers:
            if isinstance(extra_headers, dict):
                extra_headers = extra_headers.items()
                print("\nextra_headers", extra_headers)
            for key, value in extra_headers:
                connection.putheader(key, value)
        if debug:
            connection.set_debuglevel(1)
        if self.accept_gzip_encoding and gzip:
            connection.putrequest("POST", handler, skip_accept_encoding=True)
            extra_headers.append(("Accept-Encoding", "gzip"))
        else:
            connection.putrequest("POST", handler)
        extra_headers.append(("Cookie", self.get_cookies_header()))
        extra_headers.append(("User-Agent", self.user_agent))
        extra_headers.append(("Content-Type", "text/xml"))
        self.send_headers(connection, extra_headers)
        self.send_content(connection, request_body)
        return connection

    def login(self, host, homeUri, authUri, authBody, verbose=0):
        headers = {}
        conn = self.make_connection(host)
        if verbose:
            conn.set_debuglevel(1)

        conn.request('GET', homeUri)

        try:
            response = conn.getresponse()
        except AttributeError:
            response = conn._conn.getresponse()

        self.extract_cookies(response) ##生成一个self.cookies
        response.read()  # 生成页面
        print(response.status)

        if response.status in (404,500,503,505,501):
            raise xmlrpc.client.ProtocolError(host + homeUri, response.status,
                                          response.reason, response.msg.headers)
        #判断页面状态

        headers.clear()
        headers = {"Content-Type": "application/x-www-form-urlencoded","Accept": "text/plain","Connection":"keep-alive"}
        headers['Cookie'] = self.get_cookies_header()
        print(headers)
        conn.request('POST', authUri, authBody, headers) ##进行登录
        try:
            response = conn.getresponse()
        except AttributeError:
            response = conn._conn.getresponse()

        self.extract_cookies(response)
        response.read()
        print(response.status)

        if response.status in (403,404,401,500,503,505,501):
            raise xmlrpc.client.ProtocolError(host + homeUri, response.status,
                                          'Authenticate error', response.msg.headers)

        headers.clear()
        headers['Cookie'] = self.get_cookies_header() ##在header中加入cookie
        print(headers)
        conn.request('GET', homeUri, None, headers)  ##请求这页面传入 cookie 与 header

        try:
            response = conn.getresponse()
        except AttributeError:
            response = conn._conn.getresponse()

        self.extract_cookies(response)  ##再次获取cookie
        response.read()
        print("\nagain get", response.status)

    def request(self, host, handler, request_body, verbose=1):

        # issue XML-RPC request
        print(host, handler, request_body, self.cookies)
        # h = self.make_connection(host)
        # if verbose:
        #     h.set_debuglevel(1)

        h = self.send_request(host, handler, request_body, verbose)

        # Deal with differences between Python 2.4-2.6 and 2.7.
        # In the former h is a HTTP(S). In the latter it's a
        # HTTP(S)Connection. Luckily, the 2.4-2.6 implementation of
        # HTTP(S) has an underlying HTTP(S)Connection, so extract
        # that and use it.
        try:
            response = h.getresponse()
        except AttributeError:
            response = h._conn.getresponse()

        # Add any cookie definitions to our list.
        # self.extract_cookies(response)

        if response.status != 200:
            raise xmlrpc.client.ProtocolError(host + handler, response.status,
                                          response.reason, response.msg.headers)

        #         if response.info().get('Content-Encoding') == 'gzip':
        #             buf = StringIO(response.read())
        #             f = gzip.GzipFile(fileobj=buf)
        #             data = f.read()
        #         else:
        #             data = response.read()

        data = response.read().decode('utf-8')
        parser, unmarshaller = self.getparser()
        if not data:
            return parser.close()
        if verbose:
            print("body:", repr(data))
        # import re, pickle
        # data = re.sub(u"[\x00-\x08\x0b-\x0c\x0e-\x1f]+", u"", data)
        # data = re.sub(u"[\n]+", u"", data)
        # print('\n', "re after:", data)
        # data = xmlrpc.client.Binary(pickle.dumps(data)).data
        # import chardet
        # print chardet.detect(data)
        parser.feed(data)
        parser.close()

        return unmarshaller.close()


class CookieTransport(CookieTransportRequest, xmlrpc.client.Transport):
    pass


class SafeCookieTransport(CookieTransportRequest, xmlrpc.client.SafeTransport):
    pass


def getCookie():

    cookie = http.cookiejar.CookieJar()
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie))
    AUTHBODY = urllib.parse.urlencode(AUTHDATA).encode(encoding='UTF8')
    req = urllib.request.Request(url='http://' + HOST + HOMEURL)
    opener.open(req)
    cookistr = ''
    for item in cookie:
        cookistr = cookistr + '%s=%s' % (item.name, item.value)
    headers = {}
    headers.clear()
    headers = {'Content-type': 'application/x-www-form-urlencoded', "Accept": "text/plain", "Connection": "keep-alive"}
    headers['Cookie'] = cookistr

    loginpage = urllib.request.Request(url='http://' + HOST + AUTHURL, data=AUTHBODY, headers=headers)
    opener.open(loginpage)  #### 408

    cookistr = ''
    for item in cookie:
        cookistr = cookistr + '%s=%s' % (item.name, item.value)
    headers = {}
    headers.clear()
    headers = {'Content-type': 'application/x-www-form-urlencoded', "Accept": "text/plain", "Connection": "keep-alive"}
    headers['Cookie'] = cookistr
    return headers
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档