python3 xmlrpc clien

发布时间:2019-09-26 07:34:04编辑:auto阅读(1657)

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

    python2

    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

    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


关键字