Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	init/select_ticket_info.py
pull/2/head
wenxianping 2018-01-11 18:40:20 +08:00
commit 39b10e05c0
4 changed files with 72 additions and 118 deletions

View File

@ -20,7 +20,7 @@
- myUrllib - urllib库 - myUrllib - urllib库
- 思路图 - 思路图
![image](https://github.com/testerSunshine/master/uml/uml.png) ![image](https://github.com/testerSunshine/12306/blob/master/uml/uml.png)
- 项目声明: - 项目声明:
- 本软件只供学习交流使用务作为商业用途交流群286271084 - 本软件只供学习交流使用务作为商业用途交流群286271084

View File

@ -18,8 +18,8 @@ def md5(byte): # md5加密byte
class DamatuApi(): class DamatuApi():
ID = '40838' ID = '53330'
KEY = 'ca9507e17e8d5ddf7c57cd18d8d33010' KEY = '9e5dd939b00d7473c2fa8c1283baa306'
HOST = 'http://api.dama2.com:7766/app/' HOST = 'http://api.dama2.com:7766/app/'
def __init__(self, username, password, file_path): def __init__(self, username, password, file_path):
@ -124,4 +124,3 @@ class DamatuApi():
# print(dmt.decode('tkcode', 287)) # 上传打码 # print(dmt.decode('tkcode', 287)) # 上传打码
# # print(dmt.decodeUrl('https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&0.7586344633015405', 310)) # 上传打码 # # print(dmt.decodeUrl('https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&0.7586344633015405', 310)) # 上传打码
# # print(dmt.reportError('894657096')) # 上报错误 # # print(dmt.reportError('894657096')) # 上报错误

View File

@ -7,7 +7,7 @@ import threading
import urllib import urllib
import sys import sys
import time import time
from Queue import Queue import Queue
from collections import OrderedDict from collections import OrderedDict
from config.ticketConf import _get_yaml from config.ticketConf import _get_yaml
@ -33,6 +33,7 @@ class select:
self.user_info = "" self.user_info = ""
self.secretStr = "" self.secretStr = ""
self.ticket_black_list = dict() self.ticket_black_list = dict()
self.submitQueue=Queue.Queue(15)
def get_ticket_info(self): def get_ticket_info(self):
""" """
@ -234,7 +235,7 @@ class select:
break break
else: else:
print ('正在尝试提交订票...') print ('正在尝试提交订票...')
return train_no # 提交车次 self.submitQueue.put({"obj":self,"train_no":train_no,"seat":self._station_seat[j].encode("utf8")})
# if self.check_user(): # if self.check_user():
# self.submit_station() # self.submit_station()
# self.getPassengerTicketStr(self._station_seat[j].encode("utf8")) # self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
@ -248,7 +249,7 @@ class select:
pass pass
time.sleep(self.expect_refresh_interval) time.sleep(self.expect_refresh_interval)
else: else:
raise ticketConfigException("车次配置信息有误,请检查") print "车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
def check_user(self): def check_user(self):
""" """
@ -370,54 +371,24 @@ class select:
data['REPEAT_SUBMIT_TOKEN'] = self.token data['REPEAT_SUBMIT_TOKEN'] = self.token
checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, )) checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, ))
if 'data' in checkOrderInfo: if 'data' in checkOrderInfo:
if checkOrderInfo["data"]["ifShowPassCode"] == "y": if checkOrderInfo["data"]["ifShowPassCode"] == "Y":
print("需要验证码,正在使用自动识别验证码功能") is_need_code = True
for i in range(3): if self.getQueueCount(train_no, set_type, is_need_code):
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&%s' % random.random() return True
result = myurllib2.get(codeimg)
img_path = './tkcode'
open(img_path, 'wb').write(result)
data['pass_code'] = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main()
checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, ))
if checkOrderInfo['data']['submitStatus'] is True:
print ('车票提交通过,正在尝试排队')
if self.getQueueCount(train_no, set_type):
return True
else:
raise ticketNumOutException("提交订单失败")
else:
print("验证码识别错误,第{0}次重试".format(i))
if checkOrderInfo['data']['submitStatus'] is True: if checkOrderInfo['data']['submitStatus'] is True:
print ('车票提交通过,正在尝试排队') print ('车票提交通过,正在尝试排队')
if self.getQueueCount(train_no, set_type): is_need_code = False
if self.getQueueCount(train_no, set_type, is_need_code):
return True return True
else: else:
if "errMsg" in checkOrderInfo['data'] and checkOrderInfo['data']["errMsg"]: if "errMsg" in checkOrderInfo['data'] and checkOrderInfo['data']["errMsg"]:
print checkOrderInfo['data']["errMsg"] print checkOrderInfo['data']["errMsg"]
if checkOrderInfo['data']["errMsg"].find("验证码") != -1:
print("需要验证码,正在使用自动识别验证码功能")
for i in range(3):
codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&%s' % random.random()
result = myurllib2.get(codeimg)
img_path = './tkcode'
open(img_path, 'wb').write(result)
data['pass_code'] = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"],
img_path).main()
checkOrderInfo = json.loads(myurllib2.Post(checkOrderInfoUrl, data, ))
if checkOrderInfo['data']['submitStatus'] is True:
print ('车票提交通过,正在尝试排队')
if self.getQueueCount(train_no, set_type):
return True
else:
raise ticketNumOutException("提交订单失败")
else:
print("验证码识别错误,第{0}次重试".format(i))
else: else:
print checkOrderInfo print checkOrderInfo
elif 'messages' in checkOrderInfo and checkOrderInfo['messages']: elif 'messages' in checkOrderInfo and checkOrderInfo['messages']:
print (checkOrderInfo['messages'][0]) print (checkOrderInfo['messages'][0])
def getQueueCount(self, train_no, set_type): def getQueueCount(self, train_no, set_type, is_need_code):
""" """
# 模拟查询当前的列车排队人数的方法 # 模拟查询当前的列车排队人数的方法
# 返回信息组成的提示字符串 # 返回信息组成的提示字符串
@ -457,7 +428,7 @@ class select:
print("当前余票数小于乘车人数,放弃订票") print("当前余票数小于乘车人数,放弃订票")
else: else:
print("排队成功, 当前余票还剩余: {0}".format(ticket_split)) print("排队成功, 当前余票还剩余: {0}".format(ticket_split))
if self.checkQueueOrder(): if self.checkQueueOrder(is_need_code):
return True return True
else: else:
print("当前排队人数:" + str(countT) + "当前余票还剩余:{0} 张,继续排队中".format(ticket_split)) print("当前排队人数:" + str(countT) + "当前余票还剩余:{0} 张,继续排队中".format(ticket_split))
@ -474,7 +445,7 @@ class select:
else: else:
print("未知错误 {0}".format("".join(getQueueCountResult))) print("未知错误 {0}".format("".join(getQueueCountResult)))
def checkQueueOrder(self): def checkQueueOrder(self, is_node_code=False):
""" """
模拟提交订单是确认按钮参数获取方法还是get_ticketInfoForPassengerForm 中获取 模拟提交订单是确认按钮参数获取方法还是get_ticketInfoForPassengerForm 中获取
:return: :return:
@ -495,20 +466,39 @@ class select:
} }
try: try:
for i in range(3): for i in range(3):
checkQueueOrderResult = json.loads(myurllib2.Post(checkQueueOrderUrl, data)) if is_node_code:
if checkQueueOrderResult: print("正在使用自动识别验证码功能")
break randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn'
except ValueError: codeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=passenger&rand=sjrand&%s' % random.random()
checkQueueOrderResult = {} result = myurllib2.get(codeimg)
if checkQueueOrderResult: img_path = './tkcode'
open(img_path, 'wb').write(result)
randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"],
img_path).main()
randData = {
"randCode": randCode,
"rand": "randp",
"_json_att": None,
"REPEAT_SUBMIT_TOKEN": self.get_token()
}
fresult = json.loads(myurllib2.Post(randurl, randData), encoding='utf8') # 校验验证码是否正确
checkcode = fresult['data']['msg']
if checkcode == 'FALSE':
print ("验证码有误,第{}次尝试重试".format(i))
else:
print("验证码通过,正在提交订单")
data['randCode'] = randCode
else:
print("不需要验证码")
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']: if 'submitStatus' in c_data and c_data['submitStatus'] is True:
print("提交订单成功!") print("提交订单成功!")
self.queryOrderWaitTime() self.queryOrderWaitTime()
else: else:
if 'errMsg' in c_data and c_data['errMsg']: if 'errMsg' in c_data and c_data['errMsg']:
print("提交订单失败," + c_data['errMsg']) print("提交订单失败,{0}".format(c_data['errMsg']))
else: else:
print(c_data) print(c_data)
print('订票失败!很抱歉,请重试提交预订功能!') print('订票失败!很抱歉,请重试提交预订功能!')
@ -516,7 +506,7 @@ class select:
print("提交订单失败,错误信息: " + checkQueueOrderResult["messages"]) print("提交订单失败,错误信息: " + checkQueueOrderResult["messages"])
else: else:
print("提交订单中,请耐心等待:" + str(checkQueueOrderResult["validateMessages"])) print("提交订单中,请耐心等待:" + str(checkQueueOrderResult["validateMessages"]))
else: except ValueError:
print("接口 {} 无响应".format(checkQueueOrderUrl)) print("接口 {} 无响应".format(checkQueueOrderUrl))
def queryOrderWaitTime(self): def queryOrderWaitTime(self):
@ -619,17 +609,22 @@ class select:
def main(self): def main(self):
from_station, to_station = self.station_table(self.from_station, self.to_station) from_station, to_station = self.station_table(self.from_station, self.to_station)
if self.leftTicketLog(from_station, to_station): if self.leftTicketLog(from_station, to_station):
submitOrderConsumer("daemon1",self.submitQueue).start()
num = 1 num = 1
runedTime=0
while 1: while 1:
try: try:
num += 1 num += 1
time.sleep(self.select_refresh_interval) sleepTime=self.select_refresh_interval*1000-runedTime
if sleepTime>0:
time.sleep(sleepTime/1000.0)
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00": if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
print "12306休息时间本程序自动停止,明天早上七点运行" print "12306休息时间本程序自动停止,明天早上七点运行"
break break
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
self.submitOrderRequest(from_station, to_station) self.submitOrderRequest(from_station, to_station)
print "正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 代理设置 无 总耗时{3}ms".format(num, self.station_date, ",".join(self.station_trains), (datetime.datetime.now()-start_time).microseconds/1000) runedTime=(datetime.datetime.now()-start_time).microseconds/1000
print "正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 代理设置 无 总耗时{3}ms".format(num, self.station_date, ",".join(self.station_trains), runedTime)
except PassengerUserException as e: except PassengerUserException as e:
print e.message print e.message
break break
@ -651,80 +646,40 @@ class select:
class selectProducer(threading.Thread): class selectProducer(threading.Thread):
"""刷票队列""" """刷票队列"""
def __init__(self, t_name, queue, selectObj, from_station, to_station, expect_refresh_interval, select_refresh_interval): def __init__(self, t_name, data):
self.data=data
# tName=data.train_no+"_"+str(random.random)
threading.Thread.__init__(self, name=t_name) threading.Thread.__init__(self, name=t_name)
self.data = queue
self.selectObj = selectObj
self.from_station, self.to_station = from_station, to_station
self.expect_refresh_interval, self.select_refresh_interval = expect_refresh_interval, select_refresh_interval
print "{0} 正在运行".format(t_name) print "{0} 正在运行".format(t_name)
def run(self): def run(self):
from_station, to_station = self.selectObj.station_table(self.from_station, self.to_station) self.worker(self.data)
if self.selectObj.leftTicketLog(from_station, to_station):
num = 1
while 1:
try:
num += 1
time.sleep(self.select_refresh_interval)
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
print "12306休息时间本程序自动停止,明天早上七点运行
break
else:
self.selectObj
tain_no = self.selectObj.submitOrderRequest()
def worker(self,data):
obj=data['obj']
if obj.check_user():
obj.submit_station()
obj.getPassengerTicketStr(data['seat'])
obj.getRepeatSubmitToken()
obj.user_info = obj.getPassengerDTOs()
if obj.checkOrderInfo(data['train_no'], data['seat']):
return
obj.submitQueue.task_done()
class submitOrderConsumer(threading.Thread): class submitOrderConsumer(threading.Thread):
"""订单队列""" """订单队列"""
def __init__(self, t_name, queue, selectObj): def __init__(self,t_name, queue):
threading.Thread.__init__(self, name=t_name) threading.Thread.__init__(self, name=t_name)
self.data = queue self.data = queue
print "{0} 正在运行".format(t_name) print "{0} 正在运行".format(t_name)
def run(self): def run(self):
pass while 1:
if not self.data.empty():
def get_ticket_info(): taskData=self.data.get()
""" selectProducer(taskData['train_no']+str(random.random()),taskData).start()
获取配置信息 else:
:return: time.sleep(1.5)
"""
ticket_info_config = _get_yaml()
from_station = ticket_info_config["set"]["from_station"].encode("utf8")
to_station = ticket_info_config["set"]["to_station"].encode("utf8")
station_date = ticket_info_config["set"]["station_date"].encode("utf8")
set_type = ticket_info_config["set"]["set_type"]
is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
select_refresh_interval = ticket_info_config["select_refresh_interval"]
station_trains = ticket_info_config["set"]["station_trains"]
expect_refresh_interval = ticket_info_config["expect_refresh_interval"]
ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
print "*"*20
print "当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:{6}\n候选购买车次:{7}\n未开始刷票间隔时间:{8}\n僵尸票关小黑屋时长:{9}".format\
(
from_station,
to_station,
station_date,
",".join(set_type),
is_more_ticket,
",".join(ticke_peoples),
select_refresh_interval,
",".join(station_trains),
expect_refresh_interval,
ticket_black_list_time,
)
print "*"*20
return from_station, to_station, station_date, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, expect_refresh_interval, ticket_black_list_time
def main():
queue = Queue(20)
from_station, to_station, station_date, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, expect_refresh_interval, ticket_black_list_time = get_ticket_info()
if __name__ == '__main__': if __name__ == '__main__':
a = select('上海', '北京') a = select('上海', '北京')

BIN
tkcode

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB