1、更新新版登录

2、优化代码
dev
wenxianping 2018-01-20 23:23:51 +08:00
parent 501fd388bd
commit aa6d628c82
7 changed files with 391 additions and 258 deletions

View File

@ -164,4 +164,10 @@
- 优化提交订单有很大记录无限排队的情况,感谢群里的小伙伴提供的思路 - 优化提交订单有很大记录无限排队的情况,感谢群里的小伙伴提供的思路
- 修改休眠时间为早上6点 - 修改休眠时间为早上6点
- 2018.1.20更新,好久没跟新了,群里的小伙伴说登录不行了,今晚抽空改了一版登录,妥妥的
- 更新新版登录功能,经测试,更稳定有高效
- 优化手动打码功能
- 更新请求第三方库
- 优化若干代码,小伙伴尽情的放肆起来

89
config/urlConf.py Normal file
View File

@ -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"
}
}

View File

@ -9,20 +9,26 @@ from time import sleep
from config.ticketConf import _get_yaml from config.ticketConf import _get_yaml
from PIL import Image from PIL import Image
from damatuCode.damatuWeb import DamatuApi from damatuCode.damatuWeb import DamatuApi
from myException.UserPasswordException import UserPasswordException
from myUrllib import myurllib2 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(): def cookietp(self):
stoidinput("获取Cookie") print("正在获取cookie")
Url = "https://kyfw.12306.cn/otn/login/init" url = self.urlConf["loginInit"]["req_url"]
myurllib2.get(Url) self.httpClint.send(url)
# Url = "https://kyfw.12306.cn/otn/login/init"
# myurllib2.get(Url)
# for index, c in enumerate(myurllib2.cookiejar): # for index, c in enumerate(myurllib2.cookiejar):
# stoidinput(c) # stoidinput(c)
def readImg(self):
def readImg():
""" """
增加手动打码只是登录接口完全不用担心提交订单效率 增加手动打码只是登录接口完全不用担心提交订单效率
思路 思路
@ -31,52 +37,30 @@ def readImg():
3.控制台输入对应下标按照英文逗号分开即可手动完成打码 3.控制台输入对应下标按照英文逗号分开即可手动完成打码
:return: :return:
""" """
print ("下载验证码...")
global randCode codeimgUrl = self.urlConf["getCodeImg"]["req_url"]
stoidinput("下载验证码...")
img_path = './tkcode' img_path = './tkcode'
result = myurllib2.get(codeimg) result = self.httpClint.send(codeimgUrl)
try: try:
open(img_path, 'wb').write(result) open(img_path, 'wb').write(result)
if _get_yaml()["is_aotu_code"]: if _get_yaml()["is_aotu_code"]:
randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main() self.randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main()
else: else:
img = Image.open('./tkcode') img = Image.open('./tkcode')
img.show() img.show()
codexy() self.codexy()
except OSError as e: except OSError as e:
print (e) print (e)
pass pass
def codexy(self):
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 :return: str
""" """
Ofset = raw_input("[*] 请输入验证码: ") Ofset = raw_input("请输入验证码: ")
select = Ofset.split(',') select = Ofset.split(',')
global randCode
post = [] post = []
offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题 offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题
offsetsY = 0 # 选择的答案的top值 offsetsY = 0 # 选择的答案的top值
@ -109,10 +93,86 @@ def codexy():
pass pass
post.append(offsetsX) post.append(offsetsX)
post.append(offsetsY) post.append(offsetsY)
randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '') 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 go_login(): def codeCheck(self):
"""
验证码校验
:return:
"""
codeCheck = self.urlConf["codeCheck"]["req_url"]
codeCheckData = {
"answer": self.randCode,
"rand": "sjrand",
"login_site": "E"
}
fresult = self.httpClint.send(codeCheck, codeCheckData)
if "result_code" in fresult and fresult["result_code"] == "4":
print ("验证码通过,开始登录..")
return True
else:
if "result_message" in fresult:
print(fresult["result_message"])
sleep(1)
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 user: 账户名
@ -122,90 +182,26 @@ def go_login():
user, passwd = _get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"] user, passwd = _get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"]
login_num = 0 login_num = 0
while True: while True:
cookietp() self.cookietp()
readImg() 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 login_num += 1
randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn' self.auth()
logurl = 'https://kyfw.12306.cn/otn/login/loginAysnSuggest' if self.codeCheck():
surl = 'https://kyfw.12306.cn/otn/login/userLogin' uamtk = self.baseLogin(user, passwd)
randdata = { if uamtk:
"randCode": randCode, if self.getUserName(uamtk):
"rand": "sjrand"
}
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))
else:
stoidinput("验证码通过,开始登录..")
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]))
break 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):
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'<input name="userDTO.loginUserDTO.user_name" style="display:none;" type="text" value="(\S+)" />'
try:
stoidinput("欢迎 %s 登录" % re.search(name, result).group(1))
except AttributeError:
pass
def logout():
url = 'https://kyfw.12306.cn/otn/login/loginOut' url = 'https://kyfw.12306.cn/otn/login/loginOut'
result = myurllib2.get(url) result = myurllib2.get(url)
if result: if result:
stoidinput("已退出") print ("已退出")
else: else:
errorinput("退出失败") print ("退出失败")
if __name__ == "__main__": # if __name__ == "__main__":
main() # # main()
# logout() # # logout()

View File

@ -4,22 +4,24 @@ import datetime
import random import random
import re import re
import socket import socket
import threading
import urllib import urllib
import sys import sys
import time import time
from collections import OrderedDict from collections import OrderedDict
from config import urlConf
from init import login from init import login
from config.emailConf import sendEmail from config.emailConf import sendEmail
from config.ticketConf import _get_yaml from config.ticketConf import _get_yaml
from damatuCode.damatuWeb import DamatuApi from damatuCode.damatuWeb import DamatuApi
from init.login import go_login from init.login import GoLogin
from myException.PassengerUserException import PassengerUserException from myException.PassengerUserException import PassengerUserException
from myException.UserPasswordException import UserPasswordException
from myException.ticketConfigException import ticketConfigException from myException.ticketConfigException import ticketConfigException
from myException.ticketIsExitsException import ticketIsExitsException from myException.ticketIsExitsException import ticketIsExitsException
from myException.ticketNumOutException import ticketNumOutException from myException.ticketNumOutException import ticketNumOutException
from myUrllib import myurllib2 from myUrllib.httpUtils import HTTPClient
reload(sys) reload(sys)
sys.setdefaultencoding('utf-8') sys.setdefaultencoding('utf-8')
@ -37,6 +39,8 @@ class select:
self.secretStr = "" self.secretStr = ""
self.ticket_black_list = dict() self.ticket_black_list = dict()
self.is_check_user = dict() self.is_check_user = dict()
self.httpClint = HTTPClient()
self.confUrl = urlConf.urls
def get_ticket_info(self): def get_ticket_info(self):
""" """
@ -137,12 +141,11 @@ class select:
获取提交车票请求token 获取提交车票请求token
:return: token :return: token
""" """
initdc_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc' initdc_url = self.confUrl["initdc_url"]["req+url"]
initdc_result = myurllib2.get(initdc_url) initdc_result = self.httpClint.send(initdc_url)
token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'") token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'")
ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?') ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?')
order_request_params_name = re.compile(r'var orderRequestDTO=(\{.+\})?') 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) self.token = re.search(token_name, initdc_result).group(1)
re_tfpf = re.findall(ticketInfoForPassengerForm_name, initdc_result) re_tfpf = re.findall(ticketInfoForPassengerForm_name, initdc_result)
re_orp = re.findall(order_request_params_name, initdc_result) re_orp = re.findall(order_request_params_name, initdc_result)
@ -160,15 +163,14 @@ class select:
获取乘客信息 获取乘客信息
:return: :return:
""" """
get_passengerDTOs = 'https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs' get_passengerDTOs = self.confUrl["get_passengerDTOs"]["req_url"]
get_data = { get_data = {
'_json_att': None, '_json_att': None,
'REPEAT_SUBMIT_TOKEN': self.token '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'][ if 'data' in jsonData and jsonData['data'] and 'normal_passengers' in jsonData['data'] and jsonData['data'][
'normal_passengers']: 'normal_passengers']:
# return jsonData['data']['normal_passengers']
normal_passengers = 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] _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] # 如果配置乘车人没有在账号,则默认返回第一个用户 return _normal_passenger if _normal_passenger else normal_passengers[0] # 如果配置乘车人没有在账号,则默认返回第一个用户
@ -182,9 +184,9 @@ class select:
raise PassengerUserException("未查找到常用联系人,请先添加联系人在试试") raise PassengerUserException("未查找到常用联系人,请先添加联系人在试试")
def submitOrderRequestFunc(self, from_station, to_station, station_date=None): 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) 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 return station_ticket
def submitOrderRequestImplement(self, from_station, to_station,): def submitOrderRequestImplement(self, from_station, to_station,):
@ -246,9 +248,9 @@ class select:
检查用户是否达到订票条件 检查用户是否达到订票条件
:return: :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) 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'] check_user_flag = check_user['data']['flag']
if check_user_flag is True: if check_user_flag is True:
return True return True
@ -275,7 +277,7 @@ class select:
:return: :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)), # 字符串加密 data = [('secretStr', urllib.unquote(self.secretStr)), # 字符串加密
('train_date', self.time()), # 出发时间 ('train_date', self.time()), # 出发时间
('back_train_date', self.time()), # 返程时间 ('back_train_date', self.time()), # 返程时间
@ -284,7 +286,7 @@ class select:
('query_from_station_name', self.from_station), # 起始车站 ('query_from_station_name', self.from_station), # 起始车站
('query_to_station_name', self.to_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 'data' in submitResult and submitResult['data']:
if submitResult['data'] == 'N': if submitResult['data'] == 'N':
print ('出票成功') print ('出票成功')
@ -355,7 +357,7 @@ class select:
:return: :return:
""" """
passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr() passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
checkOrderInfoUrl = 'https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo' checkOrderInfoUrl = self.confUrl["checkOrderInfoUrl"]["req_url"]
data = OrderedDict() data = OrderedDict()
data['cancel_flag'] = 2 data['cancel_flag'] = 2
data['bed_level_order_num'] = "000000000000000000000000000000" data['bed_level_order_num'] = "000000000000000000000000000000"
@ -364,7 +366,7 @@ class select:
data['tour_flag'] = 'dc' data['tour_flag'] = 'dc'
data['whatsSelect'] = 1 data['whatsSelect'] = 1
data['REPEAT_SUBMIT_TOKEN'] = self.token data['REPEAT_SUBMIT_TOKEN'] = self.token
checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, )) checkOrderInfo = self.httpClint.send(checkOrderInfoUrl, data)
if 'data' in checkOrderInfo: if 'data' in checkOrderInfo:
if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y": if "ifShowPassCode" in checkOrderInfo["data"] and checkOrderInfo["data"]["ifShowPassCode"] == "Y":
is_need_code = True is_need_code = True
@ -393,7 +395,7 @@ class select:
""" """
l_time = time.localtime(time.time()) l_time = time.localtime(time.time())
new_train_date = time.strftime("%a %b %d %Y", l_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 = { data = {
'train_date': str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)", 'train_date': str(new_train_date) + " 00:00:00 GMT+0800 (中国标准时间)",
'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'], 'train_no': self.get_ticketInfoForPassengerForm()['queryLeftTicketRequestDTO']['train_no'],
@ -406,7 +408,7 @@ class select:
'train_location': self.get_ticketInfoForPassengerForm()['train_location'], 'train_location': self.get_ticketInfoForPassengerForm()['train_location'],
'REPEAT_SUBMIT_TOKEN': self.get_token(), '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 "status" in getQueueCountResult and getQueueCountResult["status"] is True:
if "countT" in getQueueCountResult["data"]: if "countT" in getQueueCountResult["data"]:
ticket = getQueueCountResult["data"]["ticket"] ticket = getQueueCountResult["data"]["ticket"]
@ -441,7 +443,7 @@ class select:
""" """
passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr() passengerTicketStrList, oldPassengerStr = self.getPassengerTicketStrListAndOldPassengerStr()
checkQueueOrderUrl = "https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue" checkQueueOrderUrl = self.confUrl["checkQueueOrderUrl"]["req_url"]
data = { data = {
"passengerTicketStr": self.set_type + "," + ",".join(passengerTicketStrList).rstrip("_{0}".format(self.set_type)), "passengerTicketStr": self.set_type + "," + ",".join(passengerTicketStrList).rstrip("_{0}".format(self.set_type)),
"oldPassengerStr": "".join(oldPassengerStr), "oldPassengerStr": "".join(oldPassengerStr),
@ -460,9 +462,9 @@ class select:
for i in range(3): for i in range(3):
if is_node_code: if is_node_code:
print("正在使用自动识别验证码功能") print("正在使用自动识别验证码功能")
randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn' checkRandCodeAnsyn = self.confUrl["checkRandCodeAnsyn"]["req_url"]
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s' % random.random() codeImgByOrder = self.confUrl["codeImgByOrder"]["req_url"]
result = myurllib2.get(codeimg) result = self.httpClint.send(codeImgByOrder)
img_path = './tkcode' img_path = './tkcode'
open(img_path, 'wb').write(result) open(img_path, 'wb').write(result)
randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"],
@ -473,7 +475,7 @@ class select:
"_json_att": None, "_json_att": None,
"REPEAT_SUBMIT_TOKEN": self.get_token() "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'] checkcode = fresult['data']['msg']
if checkcode == 'TRUE': if checkcode == 'TRUE':
print("验证码通过,正在提交订单") print("验证码通过,正在提交订单")
@ -484,8 +486,7 @@ class select:
else: else:
print("不需要验证码") print("不需要验证码")
break break
# print("".join(data)) checkQueueOrderResult = self.httpClint.send(checkQueueOrderUrl, data)
checkQueueOrderResult = json.loads(myurllib2.Post(checkQueueOrderUrl, data))
if "status" in checkQueueOrderResult and checkQueueOrderResult["status"]: if "status" in checkQueueOrderResult and checkQueueOrderResult["status"]:
c_data = checkQueueOrderResult["data"] if "data" in checkQueueOrderResult else {} c_data = checkQueueOrderResult["data"] if "data" in checkQueueOrderResult else {}
if 'submitStatus' in c_data and c_data['submitStatus'] is True: if 'submitStatus' in c_data and c_data['submitStatus'] is True:
@ -509,12 +510,6 @@ class select:
排队获取订单等待信息,每隔3秒请求一次最高请求次数为20次 排队获取订单等待信息,每隔3秒请求一次最高请求次数为20次
:return: :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 num = 1
while True: while True:
_random = int(round(time.time() * 1000)) _random = int(round(time.time() * 1000))
@ -523,10 +518,9 @@ class select:
print("超出排队时间,自动放弃,正在重新刷票") print("超出排队时间,自动放弃,正在重新刷票")
break break
try: 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"} data = {"random": _random, "tourFlag": "dc"}
queryOrderWaitTimeUrl = "https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime" queryOrderWaitTimeUrl = self.confUrl["queryOrderWaitTimeUrl"]["req_url"]
queryOrderWaitTimeResult = json.loads(myurllib2.Post(queryOrderWaitTimeUrl, data)) queryOrderWaitTimeResult = self.httpClint.send(queryOrderWaitTimeUrl, data)
except ValueError: except ValueError:
queryOrderWaitTimeResult = {} queryOrderWaitTimeResult = {}
if queryOrderWaitTimeResult: if queryOrderWaitTimeResult:
@ -562,10 +556,10 @@ class select:
:return: :return:
""" """
self.initNoComplete() self.initNoComplete()
queryMyOrderNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete" queryMyOrderNoCompleteUrl = self.confUrl["queryMyOrderNoCompleteUrl"]["req_url"]
data = {"_json_att": None} data = {"_json_att": None}
try: try:
queryMyOrderNoCompleteResult = json.loads(myurllib2.Post(queryMyOrderNoCompleteUrl, data)) queryMyOrderNoCompleteResult = self.httpClint.send(queryMyOrderNoCompleteUrl, data)
except ValueError: except ValueError:
queryMyOrderNoCompleteResult = {} queryMyOrderNoCompleteResult = {}
if queryMyOrderNoCompleteResult: if queryMyOrderNoCompleteResult:
@ -590,9 +584,9 @@ class select:
获取订单前需要进入订单列表页获取订单列表页session 获取订单前需要进入订单列表页获取订单列表页session
:return: :return:
""" """
initNoCompleteUrl = "https://kyfw.12306.cn/otn/queryOrder/initNoComplete" initNoCompleteUrl = self.confUrl["initNoCompleteUrl"]["req_url"]
data = {"_json_att": None} data = {"_json_att": None}
myurllib2.Post(initNoCompleteUrl, data) self.httpClint.send(initNoCompleteUrl, data)
# def call_submit_ticket(self, function_name=None): # def call_submit_ticket(self, function_name=None):
# """ # """
@ -608,7 +602,8 @@ class select:
def call_login(self): def call_login(self):
"""登录回调方法""" """登录回调方法"""
go_login() login = GoLogin(self.httpClint, self.confUrl)
login.go_login()
def main(self): def main(self):
self.call_login() self.call_login()
@ -641,6 +636,9 @@ class select:
except ticketNumOutException as e: except ticketNumOutException as e:
print e.message print e.message
break break
except UserPasswordException as e:
print e.message
break
except ValueError as e: except ValueError as e:
if e.message == "No JSON object could be decoded": if e.message == "No JSON object could be decoded":
print("12306接口无响应正在重试") print("12306接口无响应正在重试")

View File

@ -0,0 +1,2 @@
class UserPasswordException(Exception):
pass

View File

@ -1,5 +1,8 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
import datetime import datetime
import json
import socket
import requests import requests
@ -10,45 +13,84 @@ class HTTPClient(object):
:param method: :param method:
:param headers: Must be a dict. Such as headers={'Content_Type':'text/html'} :param headers: Must be a dict. Such as headers={'Content_Type':'text/html'}
""" """
self.session = requests.session() self.initS()
self._set_header()
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): def _set_header(self):
"""设置header""" """设置header"""
add_header = { return {
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"X-Requested-With": "xmlHttpRequest", "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", "Referer": "https://kyfw.12306.cn/otn/login/init",
"Accept": "*/*", "Accept": "*/*",
} }
self.session.headers.update(add_header)
def get(self, url, proxy=None, **kwargs): def setHeaders(self, headers):
if proxy: self._s.headers.update(headers)
proxies = {"http": proxy} return self
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 post(self, url, data=None, proxy=None, **kwargs): def getHeadersHost(self):
if proxy: return self._s.headers["Host"]
proxies = {"http": proxy}
else: def setHeadersHost(self, host):
proxies = "" self._s.headers.update({"Host": host})
response = self.session.request(method="POST", 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, url=url,
data=data, data=data,
proxies=proxies,
**kwargs) **kwargs)
if response.status_code == 200: try:
return response.content if response.content:
return json.loads(response.content) if method == "post" else response.content
else: else:
print("请求失败。{0}".format(response)) 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)

BIN
tkcode

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB