From ad55d8f709af8cc67f5cce7ca11fb5727003d0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=87=E8=B4=A4=E5=B9=B3?= Date: Thu, 5 Sep 2019 14:48:00 +0800 Subject: [PATCH] add selenium config --- TickerConfig.py | 14 +-- config/getCookie.py | 175 ++++++++++++++++++++++++++++++++++--- init/login.py | 137 +---------------------------- init/select_ticket_info.py | 2 +- myUrllib/httpUtils.py | 5 +- requirements.txt | 1 + 6 files changed, 177 insertions(+), 157 deletions(-) diff --git a/TickerConfig.py b/TickerConfig.py index 190d0f4..58d822f 100644 --- a/TickerConfig.py +++ b/TickerConfig.py @@ -23,10 +23,10 @@ STATION_TRAINS = [ ] # 出发城市,比如深圳北,就填深圳就搜得到 -FROM_STATION = "" +FROM_STATION = "深圳北" # 到达城市 比如深圳北,就填深圳就搜得到 -TO_STATION = "" +TO_STATION = "隆回" # 座位(list) 多个座位ex: # "商务座", @@ -39,7 +39,7 @@ TO_STATION = "" # "无座", # "动卧", SET_TYPE = [ - "", + "二等座", ] # 当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交 @@ -112,8 +112,12 @@ IS_PROXY = 0 # 预售放票时间, 如果是捡漏模式,可以忽略此操作 OPEN_TIME = "13:00:00" -# chromeDriver路径,下载地址http://chromedriver.storage.googleapis.com/index.html -# CHROME_PATH = "/Users/wenxianping/Downloads/chromedriver" +# 1=使用selenium获取devicesID +# 2=使用网页端/otn/HttpZF/logdevice获取devicesId,这个接口的算法目前可能有点问题,如果登录一直302的请改为配置1 +COOKIE_TYPE = 1 +# 如果COOKIE_TYPE=2,则需配置chromeDriver路径,下载地址http://chromedriver.storage.googleapis.com/index.html +# chromedriver配置版本只要和chrome的大版本匹配就行 +CHROME_PATH = "/Users/wenxianping/Downloads/chromedriver" PASSENGER_TICKER_STR = { '一等座': 'M', diff --git a/config/getCookie.py b/config/getCookie.py index 3d8d666..5f3a075 100644 --- a/config/getCookie.py +++ b/config/getCookie.py @@ -1,5 +1,9 @@ +import json +import random +import re import time import TickerConfig +from config.urlConf import urls def getDrvicesID(session): @@ -7,16 +11,161 @@ def getDrvicesID(session): :return: """ print("cookie获取中") - from selenium import webdriver - cookies = [] - driver = webdriver.Chrome(TickerConfig.CHROME_PATH) - driver.get("https://www.12306.cn/index/index.html") - time.sleep(10) - for c in driver.get_cookies(): - cookie = dict() - if c.get("name") == "RAIL_DEVICEID" or c.get("name") == "RAIL_EXPIRATION": - cookie[c.get("name")] = c.get("value") - cookies.append(cookie) - if cookies: - session.httpClint.set_cookies(cookies) - print("cookie获取完成") + if TickerConfig.COOKIE_TYPE is 1: + from selenium import webdriver + cookies = [] + options = webdriver.ChromeOptions() + options.add_argument('headless') + driver = webdriver.Chrome(chrome_options=options, executable_path=TickerConfig.CHROME_PATH) + driver.get("https://www.12306.cn/index/index.html") + time.sleep(10) + + for c in driver.get_cookies(): + cookie = dict() + if c.get("name") == "RAIL_DEVICEID" or c.get("name") == "RAIL_EXPIRATION": + cookie[c.get("name")] = c.get("value") + cookies.append(cookie) + if cookies: + session.httpClint.set_cookies(cookies) + print("cookie获取完成") + elif TickerConfig.COOKIE_TYPE is 2: + request_device_id(session) + + +def request_device_id(session): + """ + 获取加密后的浏览器特征 ID + :return: + """ + params = {"algID": request_alg_id(session), "timestamp": int(time.time() * 1000)} + params = dict(params, **_get_hash_code_params()) + response = session.httpClint.send(urls.get("getDevicesId"), params=params) + if response.find('callbackFunction') >= 0: + result = response[18:-2] + try: + result = json.loads(result) + session.httpClint.set_cookies([{ + 'RAIL_EXPIRATION': result.get('exp'), + 'RAIL_DEVICEID': result.get('dfp'), + }]) + except: + return False + + +def request_alg_id(session): + response = session.httpClint.send(urls.get("GetJS")) + result = re.search(r'algID\\x3d(.*?)\\x26', response) + try: + return result.group(1) + except (IndexError, AttributeError) as e: + pass + return "" + + +def _get_hash_code_params(): + from collections import OrderedDict + data = { + 'adblock': '0', + 'browserLanguage': 'en-US', + 'cookieEnabled': '1', + 'custID': '133', + 'doNotTrack': 'unknown', + 'flashVersion': '0', + 'javaEnabled': '0', + 'jsFonts': 'c227b88b01f5c513710d4b9f16a5ce52', + 'localCode': '3232236206', + 'mimeTypes': '52d67b2a5aa5e031084733d5006cc664', + 'os': 'MacIntel', + 'platform': 'WEB', + 'plugins': 'd22ca0b81584fbea62237b14bd04c866', + 'scrAvailSize': str(random.randint(500, 1000)) + 'x1920', + 'srcScreenSize': '24xx1080x1920', + 'storeDb': 'i1l1o1s1', + 'timeZone': '-8', + 'touchSupport': '99115dfb07133750ba677d055874de87', + 'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.' + str( + random.randint( + 5000, 7000)) + '.0 Safari/537.36', + 'webSmartID': 'f4e3b7b14cc647e30a6267028ad54c56', + } + data_trans = { + 'browserVersion': 'd435', + 'touchSupport': 'wNLf', + 'systemLanguage': 'e6OK', + 'scrWidth': 'ssI5', + 'openDatabase': 'V8vl', + 'scrAvailSize': 'TeRS', + 'hasLiedResolution': '3neK', + 'hasLiedOs': 'ci5c', + 'timeZone': 'q5aJ', + 'userAgent': '0aew', + 'userLanguage': 'hLzX', + 'jsFonts': 'EOQP', + 'scrAvailHeight': '88tV', + 'browserName': '-UVA', + 'cookieCode': 'VySQ', + 'online': '9vyE', + 'scrAvailWidth': 'E-lJ', + 'flashVersion': 'dzuS', + 'scrDeviceXDPI': '3jCe', + 'srcScreenSize': 'tOHY', + 'storeDb': 'Fvje', + 'doNotTrack': 'VEek', + 'mimeTypes': 'jp76', + 'sessionStorage': 'HVia', + 'cookieEnabled': 'VPIf', + 'os': 'hAqN', + 'hasLiedLanguages': 'j5po', + 'hasLiedBrowser': '2xC5', + 'webSmartID': 'E3gR', + 'appcodeName': 'qT7b', + 'javaEnabled': 'yD16', + 'plugins': 'ks0Q', + 'appMinorVersion': 'qBVW', + 'cpuClass': 'Md7A', + 'indexedDb': '3sw-', + 'adblock': 'FMQw', + 'localCode': 'lEnu', + 'browserLanguage': 'q4f3', + 'scrHeight': '5Jwy', + 'localStorage': 'XM7l', + 'historyList': 'kU5z', + 'scrColorDepth': "qmyu" + } + data = OrderedDict(data) + d = '' + params = {} + for key, item in data.items(): + d += key + item + key = data_trans[key] if key in data_trans else key + params[key] = item + d_len = len(d) + d_f = int(d_len / 3) if d_len % 3 == 0 else int(d_len / 3) + 1 + if d_len >= 3: + d = d[d_f:2 * d_f] + d[2 * d_f:d_len] + d[0: d_f] + d_len = len(d) + d_f = int(d_len / 3) if d_len % 3 == 0 else int(d_len / 3) + 1 + if d_len >= 3: + d = d[2 * d_f:d_len] + d[0: d_f] + d[1 * d_f: 2 * d_f] + + d = _encode_data_str_v2(d) + d = _encode_data_str_v2(d) + d = _encode_data_str_v2(d) + data_str = _encode_string(d) + params['hashCode'] = data_str + return params + + +def _encode_data_str_v2(d): + b = len(d) + if b % 2 == 0: + return d[b // 2: b] + d[0:b // 2] + else: + return d[b // 2 + 1:b] + d[b // 2] + d[0:b // 2] + + +def _encode_string(str): + import hashlib + import base64 + result = base64.b64encode(hashlib.sha256(str.encode()).digest()).decode() + return result.replace('+', '-').replace('/', '_').replace('=', '') diff --git a/init/login.py b/init/login.py index a01b877..fe2aedd 100755 --- a/init/login.py +++ b/init/login.py @@ -123,7 +123,6 @@ class GoLogin: :return: """ user, passwd = TickerConfig.USER, TickerConfig.PWD - self.request_device_id() if not user or not passwd: raise UserPasswordException(u"温馨提示: 用户名或者密码为空,请仔细检查") login_num = 0 @@ -146,138 +145,4 @@ class GoLogin: else: loginAysnSuggest(self.session, username=user, password=passwd) login_num += 1 - break - - def request_device_id(self): - """ - 获取加密后的浏览器特征 ID - :return: - """ - params = {"algID": self.request_alg_id(), "timestamp": int(time.time() * 1000)} - params = dict(params, **self._get_hash_code_params()) - response = self.session.httpClint.send(urls.get("getDevicesId"), params=params) - if response.find('callbackFunction') >= 0: - result = response[18:-2] - try: - result = json.loads(result) - self.session.httpClint.set_cookies({ - 'RAIL_EXPIRATION': result.get('exp'), - 'RAIL_DEVICEID': result.get('dfp'), - }) - except: - return False - - def request_alg_id(self): - response = self.session.httpClint.send(urls.get("GetJS")) - result = re.search(r'algID\\x3d(.*?)\\x26', response) - try: - return result.group(1) - except (IndexError, AttributeError) as e: - pass - return "" - - def _get_hash_code_params(self): - from collections import OrderedDict - data = { - 'adblock': '0', - 'browserLanguage': 'en-US', - 'cookieEnabled': '1', - 'custID': '133', - 'doNotTrack': 'unknown', - 'flashVersion': '0', - 'javaEnabled': '0', - 'jsFonts': 'c227b88b01f5c513710d4b9f16a5ce52', - 'localCode': '3232236206', - 'mimeTypes': '52d67b2a5aa5e031084733d5006cc664', - 'os': 'MacIntel', - 'platform': 'WEB', - 'plugins': 'd22ca0b81584fbea62237b14bd04c866', - 'scrAvailSize': str(random.randint(500, 1000)) + 'x1920', - 'srcScreenSize': '24xx1080x1920', - 'storeDb': 'i1l1o1s1', - 'timeZone': '-8', - 'touchSupport': '99115dfb07133750ba677d055874de87', - 'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.' + str( - random.randint( - 5000, 7000)) + '.0 Safari/537.36', - 'webSmartID': 'f4e3b7b14cc647e30a6267028ad54c56', - } - data_trans = { - 'browserVersion': 'd435', - 'touchSupport': 'wNLf', - 'systemLanguage': 'e6OK', - 'scrWidth': 'ssI5', - 'openDatabase': 'V8vl', - 'scrAvailSize': 'TeRS', - 'hasLiedResolution': '3neK', - 'hasLiedOs': 'ci5c', - 'timeZone': 'q5aJ', - 'userAgent': '0aew', - 'userLanguage': 'hLzX', - 'jsFonts': 'EOQP', - 'scrAvailHeight': '88tV', - 'browserName': '-UVA', - 'cookieCode': 'VySQ', - 'online': '9vyE', - 'scrAvailWidth': 'E-lJ', - 'flashVersion': 'dzuS', - 'scrDeviceXDPI': '3jCe', - 'srcScreenSize': 'tOHY', - 'storeDb': 'Fvje', - 'doNotTrack': 'VEek', - 'mimeTypes': 'jp76', - 'sessionStorage': 'HVia', - 'cookieEnabled': 'VPIf', - 'os': 'hAqN', - 'hasLiedLanguages': 'j5po', - 'hasLiedBrowser': '2xC5', - 'webSmartID': 'E3gR', - 'appcodeName': 'qT7b', - 'javaEnabled': 'yD16', - 'plugins': 'ks0Q', - 'appMinorVersion': 'qBVW', - 'cpuClass': 'Md7A', - 'indexedDb': '3sw-', - 'adblock': 'FMQw', - 'localCode': 'lEnu', - 'browserLanguage': 'q4f3', - 'scrHeight': '5Jwy', - 'localStorage': 'XM7l', - 'historyList': 'kU5z', - 'scrColorDepth': "qmyu" - } - data = OrderedDict(data) - d = '' - params = {} - for key, item in data.items(): - d += key + item - key = data_trans[key] if key in data_trans else key - params[key] = item - d_len = len(d) - d_f = int(d_len / 3) if d_len % 3 == 0 else int(d_len / 3) + 1 - if d_len >= 3: - d = d[d_f:2 * d_f] + d[2 * d_f:d_len] + d[0: d_f] - d_len = len(d) - d_f = int(d_len / 3) if d_len % 3 == 0 else int(d_len / 3) + 1 - if d_len >= 3: - d = d[2 * d_f:d_len] + d[0: d_f] + d[1 * d_f: 2 * d_f] - - d = self._encode_data_str_v2(d) - d = self._encode_data_str_v2(d) - d = self._encode_data_str_v2(d) - data_str = self._encode_string(d) - params['hashCode'] = data_str - return params - - def _encode_data_str_v2(self, d): - b = len(d) - if b % 2 == 0: - return d[b // 2: b] + d[0:b // 2] - else: - return d[b // 2 + 1:b] + d[b // 2] + d[0:b // 2] - - def _encode_string(self, str): - import hashlib - import base64 - result = base64.b64encode(hashlib.sha256(str.encode()).digest()).decode() - return result.replace('+', '-').replace('/', '_').replace('=', '') \ No newline at end of file + break \ No newline at end of file diff --git a/init/select_ticket_info.py b/init/select_ticket_info.py index e4bd378..a718dd7 100755 --- a/init/select_ticket_info.py +++ b/init/select_ticket_info.py @@ -145,7 +145,7 @@ class select: self.cdn_certification() l = liftTicketInit(self) l.reqLiftTicketInit() - # getDrvicesID(self) + getDrvicesID(self) self.call_login() check_user = checkUser(self) t = threading.Thread(target=check_user.sendCheckUser) diff --git a/myUrllib/httpUtils.py b/myUrllib/httpUtils.py index 9423719..9bc7076 100755 --- a/myUrllib/httpUtils.py +++ b/myUrllib/httpUtils.py @@ -47,8 +47,9 @@ class HTTPClient(object): :param kwargs: :return: """ - for k, v in kwargs.items(): - self._s.cookies.set(k, v) + for kwarg in kwargs: + for k, v in kwarg.items(): + self._s.cookies.set(k, v) def get_cookies(self): """ diff --git a/requirements.txt b/requirements.txt index d92067f..a763b59 100755 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ tensorflow matplotlib>=3.0.2 numpy>=1.14.6 scipy>=1.1.0 +selenium==3.11.0 \ No newline at end of file