diff --git a/README.md b/README.md index 10e2c6b..2c4ac8e 100644 --- a/README.md +++ b/README.md @@ -164,4 +164,10 @@ - 优化提交订单有很大记录无限排队的情况,感谢群里的小伙伴提供的思路 - 修改休眠时间为早上6点 +- 2018.1.20更新,好久没跟新了,群里的小伙伴说登录不行了,今晚抽空改了一版登录,妥妥的 + - 更新新版登录功能,经测试,更稳定有高效 + - 优化手动打码功能 + - 更新请求第三方库 + - 优化若干代码,小伙伴尽情的放肆起来 + diff --git a/config/urlConf.py b/config/urlConf.py new file mode 100644 index 0000000..d2e7651 --- /dev/null +++ b/config/urlConf.py @@ -0,0 +1,89 @@ +import random + +urls = { + "auth": { + "req_url": "https://kyfw.12306.cn/passport/web/auth/uamtk", + "req_type": "post" + }, + "login": { + "req_url": "https://kyfw.12306.cn/passport/web/login", + "req_type": "post" + }, + "getCodeImg": { + "req_url": "https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{0}".format(random.random()), + "req_type": "get" + }, + "codeCheck": { + "req_url": "https://kyfw.12306.cn/passport/captcha/captcha-check", + "req_type": "post" + }, + "loginInit": { + "req_url": "https://kyfw.12306.cn/otn/login/init", + "req_type": "get" + }, + "getUserInfo": { + "req_url": "https://kyfw.12306.cn/otn/index/initMy12306", + "req_type": "get" + }, + "userLogin": { + "req_url": "https://kyfw.12306.cn/otn/login/userLogin", + "req_type": "get" + }, + "uamauthclient": { + "req_url": "https://kyfw.12306.cn/otn/uamauthclient", + "req_type": "post" + }, + "initdc_url": { + "req_url": "https://kyfw.12306.cn/otn/confirmPassenger/initDc", + "req_type": "get" + }, + "get_passengerDTOs": { + "req_url": "https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs", + "req_type": "post" + }, + "select_url": { + "req_url": "https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT", + "req_type": "post" + }, + "check_user_url": { + "req_url": "https://kyfw.12306.cn/otn/login/checkUser", + "req_type": "post" + }, + "submit_station_url": { + "req_url": "https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest", + "req_type": "post" + }, + "checkOrderInfoUrl": { + "req_url": "https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo", + "req_type": "post" + }, + "getQueueCountUrl": { + "req_url": "https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount", + "req_type": "post" + }, + "checkQueueOrderUrl": { + "req_url": "https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue", + "req_type": "post" + }, + "checkRandCodeAnsyn": { + "req_url": "https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn", + "req_type": "post" + }, + "codeImgByOrder": { + "req_url": "https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s" % random.random(), + "req_type": "post" + }, + "queryOrderWaitTimeUrl": { + "req_url": "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime", + "req_type": "post" + }, + "queryMyOrderNoCompleteUrl": { + "req_url": "https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete", + "req_type": "post" + }, + "initNoCompleteUrl": { + "req_url": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete", + "req_type": "post" + } + +} \ No newline at end of file diff --git a/init/login.py b/init/login.py index 28ae5d9..6fbb34d 100644 --- a/init/login.py +++ b/init/login.py @@ -9,203 +9,199 @@ from time import sleep from config.ticketConf import _get_yaml from PIL import Image from damatuCode.damatuWeb import DamatuApi +from myException.UserPasswordException import UserPasswordException from myUrllib import myurllib2 -codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&%s' % random.random() +class GoLogin: + def __init__(self, httpClint, urlConf): + self.httpClint = httpClint + self.randCode = "" + self.urlConf = urlConf -def cookietp(): - stoidinput("获取Cookie") - Url = "https://kyfw.12306.cn/otn/login/init" - myurllib2.get(Url) - # for index, c in enumerate(myurllib2.cookiejar): - # stoidinput(c) + def cookietp(self): + print("正在获取cookie") + url = self.urlConf["loginInit"]["req_url"] + self.httpClint.send(url) + # Url = "https://kyfw.12306.cn/otn/login/init" + # myurllib2.get(Url) + # for index, c in enumerate(myurllib2.cookiejar): + # stoidinput(c) - -def readImg(): - """ - 增加手动打码,只是登录接口,完全不用担心提交订单效率 - 思路 - 1.调用PIL显示图片 - 2.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8 - 3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码, - :return: - """ - - global randCode - stoidinput("下载验证码...") - img_path = './tkcode' - result = myurllib2.get(codeimg) - try: - open(img_path, 'wb').write(result) - if _get_yaml()["is_aotu_code"]: - randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main() - else: - img = Image.open('./tkcode') - img.show() - codexy() - except OSError as e: - print (e) - pass - - -def stoidinput(text): - """ - 正常信息输出 - :param text: - :return: - """ - print "\033[34m[*]\033[0m %s " % text - - -def errorinput(text): - """ - 错误信息输出 - :param text: - :return: - """ - print "\033[32m[!]\033[0m %s " % text - return False - - -def codexy(): - """ - 获取验证码 - :return: str - """ - - Ofset = raw_input("[*] 请输入验证码: ") - select = Ofset.split(',') - global randCode - post = [] - offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题 - offsetsY = 0 # 选择的答案的top值 - for ofset in select: - if ofset == '1': - offsetsY = 46 - offsetsX = 42 - elif ofset == '2': - offsetsY = 46 - offsetsX = 105 - elif ofset == '3': - offsetsY = 45 - offsetsX = 184 - elif ofset == '4': - offsetsY = 48 - offsetsX = 256 - elif ofset == '5': - offsetsY = 36 - offsetsX = 117 - elif ofset == '6': - offsetsY = 112 - offsetsX = 115 - elif ofset == '7': - offsetsY = 114 - offsetsX = 181 - elif ofset == '8': - offsetsY = 111 - offsetsX = 252 - else: + def readImg(self): + """ + 增加手动打码,只是登录接口,完全不用担心提交订单效率 + 思路 + 1.调用PIL显示图片 + 2.图片位置说明,验证码图片中每个图片代表一个下标,依次类推,1,2,3,4,5,6,7,8 + 3.控制台输入对应下标,按照英文逗号分开,即可手动完成打码, + :return: + """ + print ("下载验证码...") + codeimgUrl = self.urlConf["getCodeImg"]["req_url"] + img_path = './tkcode' + result = self.httpClint.send(codeimgUrl) + try: + open(img_path, 'wb').write(result) + if _get_yaml()["is_aotu_code"]: + self.randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main() + else: + img = Image.open('./tkcode') + img.show() + self.codexy() + except OSError as e: + print (e) pass - post.append(offsetsX) - post.append(offsetsY) - randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '') + def codexy(self): + """ + 获取验证码 + :return: str + """ -def go_login(): - """ - 登陆 - :param user: 账户名 - :param passwd: 密码 - :return: - """ - user, passwd = _get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"] - login_num = 0 - while True: - cookietp() - readImg() - login_num += 1 - randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn' - logurl = 'https://kyfw.12306.cn/otn/login/loginAysnSuggest' - surl = 'https://kyfw.12306.cn/otn/login/userLogin' - randdata = { - "randCode": randCode, - "rand": "sjrand" + Ofset = raw_input("请输入验证码: ") + select = Ofset.split(',') + post = [] + offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题 + offsetsY = 0 # 选择的答案的top值 + for ofset in select: + if ofset == '1': + offsetsY = 46 + offsetsX = 42 + elif ofset == '2': + offsetsY = 46 + offsetsX = 105 + elif ofset == '3': + offsetsY = 45 + offsetsX = 184 + elif ofset == '4': + offsetsY = 48 + offsetsX = 256 + elif ofset == '5': + offsetsY = 36 + offsetsX = 117 + elif ofset == '6': + offsetsY = 112 + offsetsX = 115 + elif ofset == '7': + offsetsY = 114 + offsetsX = 181 + elif ofset == '8': + offsetsY = 111 + offsetsX = 252 + else: + pass + post.append(offsetsX) + post.append(offsetsY) + self.randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '') + + def auth(self): + """认证""" + authUrl = self.urlConf["auth"]["req_url"] + authData = {"appid": "otn"} + tk = self.httpClint.send(authUrl, authData) + return tk + + def codeCheck(self): + """ + 验证码校验 + :return: + """ + codeCheck = self.urlConf["codeCheck"]["req_url"] + codeCheckData = { + "answer": self.randCode, + "rand": "sjrand", + "login_site": "E" } - logdata = { - "loginUserDTO.user_name": user, - "userDTO.password": passwd, - "randCode": randCode - } - ldata = { - "_json_att": None - } - fresult = json.loads(myurllib2.Post(randurl, randdata), encoding='utf8') - checkcode = fresult['data']['msg'] - if checkcode == 'FALSE': - errorinput("验证码有误,第{}次尝试重试".format(login_num)) + fresult = self.httpClint.send(codeCheck, codeCheckData) + if "result_code" in fresult and fresult["result_code"] == "4": + print ("验证码通过,开始登录..") + return True else: - stoidinput("验证码通过,开始登录..") + if "result_message" in fresult: + print(fresult["result_message"]) sleep(1) - try: - tresult = json.loads(myurllib2.Post(logurl, logdata), encoding='utf8') - if 'data' not in tresult: - errorinput("登录失败: %s" % tresult['messages'][0]) - # elif "messages" in tresult and tresult["messages"][0].find("密码输入错误") is not -1: - # errorinput("登陆失败:{}".format(tresult["messages"][0])) - # break - elif 'messages' in tresult and tresult['messages']: - messages = tresult['messages'][0] - if messages.find("密码输入错误") is not -1: - errorinput("登陆失败:{}".format(tresult["messages"][0])) + self.httpClint.del_cookies() + + def baseLogin(self, user, passwd): + """ + 登录过程 + :param user: + :param passwd: + :return: 权限校验码 + """ + logurl = self.urlConf["login"]["req_url"] + logData = { + "username": user, + "password": passwd, + "appid": "otn" + } + tresult = self.httpClint.send(logurl, logData) + if 'result_code' in tresult and tresult["result_code"] == 0: + print ("登录成功") + tk = self.auth() + if "newapptk" in tk and tk["newapptk"]: + return tk["newapptk"] + else: + return False + elif 'result_message' in tresult and tresult['result_message']: + messages = tresult['result_message'] + if messages.find("密码输入错误") is not -1: + raise UserPasswordException("{0}".format(messages)) + else: + print ("登录失败: {0}".format("".join(tresult))) + print ("尝试重新登陆") + return False + else: + return False + + def getUserName(self, uamtk): + """ + 登录成功后,显示用户名 + :return: + """ + if not uamtk: + return "权限校验码不能为空" + else: + uamauthclientUrl = self.urlConf["uamauthclient"]["req_url"] + data = {"tk": uamtk} + uamauthclientResult = self.httpClint.send(uamauthclientUrl, data) + if "result_code" in uamauthclientResult and uamauthclientResult["result_code"] == 0: + print("欢迎 {} 登录".format(uamauthclientResult["username"])) + return True + else: + return False + + def go_login(self): + """ + 登陆 + :param user: 账户名 + :param passwd: 密码 + :return: + """ + user, passwd = _get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"] + login_num = 0 + while True: + self.cookietp() + self.httpClint.set_cookies(_jc_save_wfdc_flag="dc", _jc_save_fromStation="%u4E0A%u6D77%u8679%u6865%2CAOH", _jc_save_toStation="%u5170%u5DDE%u897F%2CLAJ", _jc_save_fromDate="2018-02-14", _jc_save_toDate="2018-01-16", RAIL_DEVICEID="EN_3_EGSe2GWGHXJeCkFQ52kHvNCrNlkz9n1GOqqQ1wR0i98WsD8Gj-a3YHZ-XYKeESWgCiJyyucgSwkFOzVHhHqfpidLPcm2vK9n83uzOPuShO3Pl4lCydAtQu4BdFqz-RVmiduNFixrcrN_Ny43135JiEtqLaI") + self.readImg() + login_num += 1 + self.auth() + if self.codeCheck(): + uamtk = self.baseLogin(user, passwd) + if uamtk: + if self.getUserName(uamtk): break - else: - errorinput("登录失败: %s" % tresult['messages'][0]) - stoidinput("尝试重新登陆") - else: - stoidinput("登录成功") - myurllib2.Post(surl, ldata) - getUserinfo() - break - except ValueError as e: - if e.message == "No JSON object could be decoded": - print("12306接口无响应,正在重试") - else: - print(e.message) - except KeyError as e: - print(e.message) - except TypeError as e: - print(e.message) - except socket.error as e: - print(e.message) - sleep(1) + + def logout(self): + url = 'https://kyfw.12306.cn/otn/login/loginOut' + result = myurllib2.get(url) + if result: + print ("已退出") + else: + print ("退出失败") -def getUserinfo(): - """ - 登录成功后,显示用户名 - :return: - """ - url = 'https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfo' - data = dict(_json_att=None) - result = myurllib2.Post(url, data) - userinfo = result - name = r'' - try: - stoidinput("欢迎 %s 登录" % re.search(name, result).group(1)) - except AttributeError: - pass - - -def logout(): - url = 'https://kyfw.12306.cn/otn/login/loginOut' - result = myurllib2.get(url) - if result: - stoidinput("已退出") - else: - errorinput("退出失败") - - -if __name__ == "__main__": - main() - # logout() \ No newline at end of file +# if __name__ == "__main__": +# # main() +# # logout() \ No newline at end of file diff --git a/init/select_ticket_info.py b/init/select_ticket_info.py index 82503cd..8754487 100644 --- a/init/select_ticket_info.py +++ b/init/select_ticket_info.py @@ -4,22 +4,24 @@ import datetime import random import re import socket -import threading import urllib import sys import time from collections import OrderedDict + +from config import urlConf from init import login from config.emailConf import sendEmail from config.ticketConf import _get_yaml from damatuCode.damatuWeb import DamatuApi -from init.login import go_login +from init.login import GoLogin from myException.PassengerUserException import PassengerUserException +from myException.UserPasswordException import UserPasswordException from myException.ticketConfigException import ticketConfigException from myException.ticketIsExitsException import ticketIsExitsException from myException.ticketNumOutException import ticketNumOutException -from myUrllib import myurllib2 +from myUrllib.httpUtils import HTTPClient reload(sys) sys.setdefaultencoding('utf-8') @@ -37,6 +39,8 @@ class select: self.secretStr = "" self.ticket_black_list = dict() self.is_check_user = dict() + self.httpClint = HTTPClient() + self.confUrl = urlConf.urls def get_ticket_info(self): """ @@ -137,12 +141,11 @@ class select: 获取提交车票请求token :return: token """ - initdc_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc' - initdc_result = myurllib2.get(initdc_url) + initdc_url = self.confUrl["initdc_url"]["req+url"] + initdc_result = self.httpClint.send(initdc_url) token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'") ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?') order_request_params_name = re.compile(r'var orderRequestDTO=(\{.+\})?') - # if token_name and ticketInfoForPassengerForm_name and order_request_params_name: self.token = re.search(token_name, initdc_result).group(1) re_tfpf = re.findall(ticketInfoForPassengerForm_name, initdc_result) re_orp = re.findall(order_request_params_name, initdc_result) @@ -160,15 +163,14 @@ class select: 获取乘客信息 :return: """ - get_passengerDTOs = 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs' + get_passengerDTOs = self.confUrl["get_passengerDTOs"]["req_url"] get_data = { '_json_att': None, 'REPEAT_SUBMIT_TOKEN': self.token } - jsonData = json.loads(myurllib2.Post(get_passengerDTOs, get_data)) + jsonData = self.httpClint.send(get_passengerDTOs, get_data) if 'data' in jsonData and jsonData['data'] and 'normal_passengers' in jsonData['data'] and jsonData['data'][ 'normal_passengers']: - # return jsonData['data']['normal_passengers'] normal_passengers = jsonData['data']['normal_passengers'] _normal_passenger = [normal_passengers[i] for i in range(len(normal_passengers))if normal_passengers[i]["passenger_name"] in self.ticke_peoples] return _normal_passenger if _normal_passenger else normal_passengers[0] # 如果配置乘车人没有在账号,则默认返回第一个用户 @@ -182,9 +184,9 @@ class select: raise PassengerUserException("未查找到常用联系人,请先添加联系人在试试") def submitOrderRequestFunc(self, from_station, to_station, station_date=None): - select_url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT'.format( + select_url = self.confUrl["select_url"]["req_url"].format( self.station_date if station_date is None else station_date, from_station, to_station) - station_ticket = json.loads(myurllib2.get(select_url), encoding='utf-8') + station_ticket = self.httpClint.send(select_url) return station_ticket def submitOrderRequestImplement(self, from_station, to_station,): @@ -246,9 +248,9 @@ class select: 检查用户是否达到订票条件 :return: """ - check_user_url = 'https://kyfw.12306.cn/otn/login/checkUser' + check_user_url = self.confUrl["check_user_url"]["req_url"] data = dict(_json_att=None) - check_user = json.loads(myurllib2.Post(check_user_url, data), encoding='utf-8') + check_user = self.httpClint.send(check_user_url, data) check_user_flag = check_user['data']['flag'] if check_user_flag is True: return True @@ -275,7 +277,7 @@ class select: :return: """ - submit_station_url = 'https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest' + submit_station_url = self.confUrl["submit_station_url"]["req_url"] data = [('secretStr', urllib.unquote(self.secretStr)), # 字符串加密 ('train_date', self.time()), # 出发时间 ('back_train_date', self.time()), # 返程时间 @@ -284,7 +286,7 @@ class select: ('query_from_station_name', self.from_station), # 起始车站 ('query_to_station_name', self.to_station), # 终点车站 ] - submitResult = json.loads(myurllib2.Post(submit_station_url, data), encoding='utf-8') + submitResult = self.httpClint.send(submit_station_url, data) if 'data' in submitResult and submitResult['data']: if submitResult['data'] == 'N': print ('出票成功') @@ -355,7 +357,7 @@ class select: :return: """ passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr() - checkOrderInfoUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo' + checkOrderInfoUrl = self.confUrl["checkOrderInfoUrl"]["req_url"] data = OrderedDict() data['cancel_flag'] = 2 data['bed_level_order_num'] = "000000000000000000000000000000" @@ -364,7 +366,7 @@ class select: data['tour_flag'] = 'dc' data['whatsSelect'] = 1 data['REPEAT_SUBMIT_TOKEN'] = self.token - checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, )) + checkOrderInfo = self.httpClint.send(checkOrderInfoUrl, data) if 'data' in checkOrderInfo: if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y": is_need_code = True @@ -393,7 +395,7 @@ class select: """ l_time = time.localtime(time.time()) new_train_date = time.strftime("%a %b %d %Y", l_time) - getQueueCountUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount' + getQueueCountUrl = self.confUrl["getQueueCountUrl"]["req_url"] data = { 'train_date': str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)", 'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'], @@ -406,7 +408,7 @@ class select: 'train_location': self.get_ticketInfoForPassengerForm()['train_location'], 'REPEAT_SUBMIT_TOKEN': self.get_token(), } - getQueueCountResult = json.loads(myurllib2.Post(getQueueCountUrl, data)) + getQueueCountResult = self.httpClint.send(getQueueCountUrl, data) if "status" in getQueueCountResult and getQueueCountResult["status"] is True: if "countT" in getQueueCountResult["data"]: ticket = getQueueCountResult["data"]["ticket"] @@ -441,7 +443,7 @@ class select: """ passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr() - checkQueueOrderUrl = "https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue" + checkQueueOrderUrl = self.confUrl["checkQueueOrderUrl"]["req_url"] data = { "passengerTicketStr": self.set_type + "," + ",".join(passengerTicketStrList).rstrip("_{0}".format(self.set_type)), "oldPassengerStr": "".join(oldPassengerStr), @@ -460,9 +462,9 @@ class select: for i in range(3): if is_node_code: print("正在使用自动识别验证码功能") - randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn' - codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s' % random.random() - result = myurllib2.get(codeimg) + checkRandCodeAnsyn = self.confUrl["checkRandCodeAnsyn"]["req_url"] + codeImgByOrder = self.confUrl["codeImgByOrder"]["req_url"] + result = self.httpClint.send(codeImgByOrder) img_path = './tkcode' open(img_path, 'wb').write(result) randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], @@ -473,7 +475,7 @@ class select: "_json_att": None, "REPEAT_SUBMIT_TOKEN": self.get_token() } - fresult = json.loads(myurllib2.Post(randurl, randData), encoding='utf8') # 校验验证码是否正确 + fresult = self.httpClint.send(checkRandCodeAnsyn, randData) # 校验验证码是否正确 checkcode = fresult['data']['msg'] if checkcode == 'TRUE': print("验证码通过,正在提交订单") @@ -484,8 +486,7 @@ class select: else: print("不需要验证码") break - # print("".join(data)) - checkQueueOrderResult = json.loads(myurllib2.Post(checkQueueOrderUrl, data)) + checkQueueOrderResult = self.httpClint.send(checkQueueOrderUrl, data) if "status" in checkQueueOrderResult and checkQueueOrderResult["status"]: c_data = checkQueueOrderResult["data"] if "data" in checkQueueOrderResult else {} if 'submitStatus' in c_data and c_data['submitStatus'] is True: @@ -509,12 +510,6 @@ class select: 排队获取订单等待信息,每隔3秒请求一次,最高请求次数为20次! :return: """ - # queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime" - # data = { - # "random": "{0}{1}".format(int(time.time()), random.randint(1, 9)), - # "tourFlag": "dc", - # "REPEAT_SUBMIT_TOKEN": self.get_token(), - # } num = 1 while True: _random = int(round(time.time() * 1000)) @@ -523,10 +518,9 @@ class select: print("超出排队时间,自动放弃,正在重新刷票") break try: - # queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN={1}".format(_random, self.get_token()) data = {"random": _random, "tourFlag": "dc"} - queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime" - queryOrderWaitTimeResult = json.loads(myurllib2.Post(queryOrderWaitTimeUrl, data)) + queryOrderWaitTimeUrl = self.confUrl["queryOrderWaitTimeUrl"]["req_url"] + queryOrderWaitTimeResult = self.httpClint.send(queryOrderWaitTimeUrl, data) except ValueError: queryOrderWaitTimeResult = {} if queryOrderWaitTimeResult: @@ -562,10 +556,10 @@ class select: :return: """ self.initNoComplete() - queryMyOrderNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete" + queryMyOrderNoCompleteUrl = self.confUrl["queryMyOrderNoCompleteUrl"]["req_url"] data = {"_json_att": None} try: - queryMyOrderNoCompleteResult = json.loads(myurllib2.Post(queryMyOrderNoCompleteUrl, data)) + queryMyOrderNoCompleteResult = self.httpClint.send(queryMyOrderNoCompleteUrl, data) except ValueError: queryMyOrderNoCompleteResult = {} if queryMyOrderNoCompleteResult: @@ -590,9 +584,9 @@ class select: 获取订单前需要进入订单列表页,获取订单列表页session :return: """ - initNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/initNoComplete" + initNoCompleteUrl = self.confUrl["initNoCompleteUrl"]["req_url"] data = {"_json_att": None} - myurllib2.Post(initNoCompleteUrl, data) + self.httpClint.send(initNoCompleteUrl, data) # def call_submit_ticket(self, function_name=None): # """ @@ -608,7 +602,8 @@ class select: def call_login(self): """登录回调方法""" - go_login() + login = GoLogin(self.httpClint, self.confUrl) + login.go_login() def main(self): self.call_login() @@ -641,6 +636,9 @@ class select: except ticketNumOutException as e: print e.message break + except UserPasswordException as e: + print e.message + break except ValueError as e: if e.message == "No JSON object could be decoded": print("12306接口无响应,正在重试") diff --git a/myException/UserPasswordException.py b/myException/UserPasswordException.py new file mode 100644 index 0000000..290b47f --- /dev/null +++ b/myException/UserPasswordException.py @@ -0,0 +1,2 @@ +class UserPasswordException(Exception): + pass \ No newline at end of file diff --git a/myUrllib/httpUtils.py b/myUrllib/httpUtils.py index e0f6504..45a9c13 100644 --- a/myUrllib/httpUtils.py +++ b/myUrllib/httpUtils.py @@ -1,5 +1,8 @@ # -*- coding: utf8 -*- import datetime +import json +import socket + import requests @@ -10,45 +13,84 @@ class HTTPClient(object): :param method: :param headers: Must be a dict. Such as headers={'Content_Type':'text/html'} """ - self.session = requests.session() - self._set_header() + self.initS() + + def initS(self): + self._s = requests.Session() + self._s.headers.update(self._set_header()) + return self + + def set_cookies(self, **kwargs): + """ + 设置cookies + :param kwargs: + :return: + """ + for k, v in kwargs.items(): + self._s.cookies.set(k, v) + + def del_cookies(self): + """ + 删除所有的key + :return: + """ + self._s.cookies.clear() + + def del_cookies_by_key(self, key): + """ + 删除指定key的session + :return: + """ + self._s.cookies.set(key, None) def _set_header(self): """设置header""" - add_header = { + return { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "X-Requested-With": "xmlHttpRequest", - "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36", + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", "Referer": "https://kyfw.12306.cn/otn/login/init", "Accept": "*/*", } - self.session.headers.update(add_header) - def get(self, url, proxy=None, **kwargs): - if proxy: - proxies = {"http": proxy} - else: - proxies = "" - response = self.session.request(method="GET", - url=url, - proxies=proxies, - **kwargs) - if response.status_code == 200: - return response.content - else: - print("请求失败。{0}".format(response)) + def setHeaders(self, headers): + self._s.headers.update(headers) + return self - def post(self, url, data=None, proxy=None, **kwargs): - if proxy: - proxies = {"http": proxy} - else: - proxies = "" - response = self.session.request(method="POST", - url=url, - data=data, - proxies=proxies, - **kwargs) - if response.status_code == 200: - return response.content - else: - print("请求失败。{0}".format(response)) \ No newline at end of file + def getHeadersHost(self): + return self._s.headers["Host"] + + def setHeadersHost(self, host): + self._s.headers.update({"Host": host}) + return self + + def getHeadersReferer(self): + return self._s.headers["Referer"] + + def setHeadersReferer(self, referer): + self._s.headers.update({"Referer": referer}) + return self + + def send(self, url, data=None, **kwargs): + """send request to url.If response 200,return response, else return None.""" + method = "post"if data else "get" + response = self._s.request(method=method, + url=url, + data=data, + **kwargs) + try: + if response.content: + return json.loads(response.content) if method == "post" else response.content + else: + return "" + except ValueError as e: + if e.message == "No JSON object could be decoded": + print("12306接口无响应,正在重试") + else: + print(e.message) + except KeyError as e: + print(e.message) + except TypeError as e: + print(e.message) + except socket.error as e: + print(e.message) \ No newline at end of file diff --git a/tkcode b/tkcode index f252118..d7eb6d9 100644 Binary files a/tkcode and b/tkcode differ