parent
501fd388bd
commit
aa6d628c82
|
@ -164,4 +164,10 @@
|
|||
- 优化提交订单有很大记录无限排队的情况,感谢群里的小伙伴提供的思路
|
||||
- 修改休眠时间为早上6点
|
||||
|
||||
- 2018.1.20更新,好久没跟新了,群里的小伙伴说登录不行了,今晚抽空改了一版登录,妥妥的
|
||||
- 更新新版登录功能,经测试,更稳定有高效
|
||||
- 优化手动打码功能
|
||||
- 更新请求第三方库
|
||||
- 优化若干代码,小伙伴尽情的放肆起来
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
||||
}
|
368
init/login.py
368
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'<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'
|
||||
result = myurllib2.get(url)
|
||||
if result:
|
||||
stoidinput("已退出")
|
||||
else:
|
||||
errorinput("退出失败")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
# logout()
|
||||
# if __name__ == "__main__":
|
||||
# # main()
|
||||
# # logout()
|
|
@ -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接口无响应,正在重试")
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
class UserPasswordException(Exception):
|
||||
pass
|
|
@ -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))
|
||||
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)
|
Loading…
Reference in New Issue