python3 xmlrpc client帶cookie請求的類
阿新 • • 發佈:2018-06-14
info over regular ring attribute raise {} re.sub ace 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
python3 xmlrpc client帶cookie請求的類