2017-05-17 12:32:37 +00:00
|
|
|
|
# -*- coding=utf-8 -*-
|
|
|
|
|
import datetime
|
2018-01-29 13:59:01 +00:00
|
|
|
|
import random
|
2019-01-04 03:00:10 +00:00
|
|
|
|
import os
|
2018-01-13 01:44:57 +00:00
|
|
|
|
import socket
|
2017-05-21 13:39:31 +00:00
|
|
|
|
import sys
|
2018-12-26 08:05:51 +00:00
|
|
|
|
import threading
|
2017-05-21 13:39:31 +00:00
|
|
|
|
import time
|
2019-09-01 04:41:25 +00:00
|
|
|
|
import TickerConfig
|
2018-08-29 11:19:13 +00:00
|
|
|
|
import wrapcache
|
2018-08-31 16:24:40 +00:00
|
|
|
|
from agency.cdn_utils import CDNProxy
|
2019-01-06 04:16:45 +00:00
|
|
|
|
from config import urlConf, configCommon
|
2018-08-29 11:19:13 +00:00
|
|
|
|
from config.TicketEnmu import ticket
|
2019-09-01 04:41:25 +00:00
|
|
|
|
from config.configCommon import seat_conf_2, seat_conf
|
2019-09-01 06:41:37 +00:00
|
|
|
|
from config.getCookie import getDrvicesID
|
2018-01-20 15:23:51 +00:00
|
|
|
|
from init.login import GoLogin
|
2018-08-29 11:19:13 +00:00
|
|
|
|
from inter.AutoSubmitOrderRequest import autoSubmitOrderRequest
|
2019-09-01 04:41:25 +00:00
|
|
|
|
from inter.ChechFace import chechFace
|
2018-08-29 11:19:13 +00:00
|
|
|
|
from inter.CheckUser import checkUser
|
|
|
|
|
from inter.GetPassengerDTOs import getPassengerDTOs
|
|
|
|
|
from inter.LiftTicketInit import liftTicketInit
|
|
|
|
|
from inter.Query import query
|
|
|
|
|
from inter.SubmitOrderRequest import submitOrderRequest
|
2018-01-08 07:28:10 +00:00
|
|
|
|
from myException.PassengerUserException import PassengerUserException
|
2018-01-20 15:23:51 +00:00
|
|
|
|
from myException.UserPasswordException import UserPasswordException
|
2018-01-08 07:28:10 +00:00
|
|
|
|
from myException.ticketConfigException import ticketConfigException
|
|
|
|
|
from myException.ticketIsExitsException import ticketIsExitsException
|
|
|
|
|
from myException.ticketNumOutException import ticketNumOutException
|
2018-01-20 15:23:51 +00:00
|
|
|
|
from myUrllib.httpUtils import HTTPClient
|
2017-05-17 12:32:37 +00:00
|
|
|
|
|
2018-01-07 01:54:36 +00:00
|
|
|
|
|
2017-05-17 12:32:37 +00:00
|
|
|
|
class select:
|
2018-08-29 11:19:13 +00:00
|
|
|
|
"""
|
|
|
|
|
快速提交车票通道
|
|
|
|
|
"""
|
2018-01-07 01:54:36 +00:00
|
|
|
|
def __init__(self):
|
2019-09-01 04:41:25 +00:00
|
|
|
|
self.get_ticket_info()
|
|
|
|
|
self._station_seat = [seat_conf[x] for x in TickerConfig.SET_TYPE]
|
|
|
|
|
self.auto_code_type = 2
|
|
|
|
|
self.httpClint = HTTPClient(TickerConfig.IS_PROXY)
|
2018-08-29 11:19:13 +00:00
|
|
|
|
self.urls = urlConf.urls
|
2019-09-01 04:41:25 +00:00
|
|
|
|
self.login = GoLogin(self, TickerConfig.IS_AUTO_CODE, self.auto_code_type)
|
2018-01-28 06:27:24 +00:00
|
|
|
|
self.cdn_list = []
|
2019-09-01 04:41:25 +00:00
|
|
|
|
self.queryUrl = "leftTicket/queryT"
|
2018-08-29 11:19:13 +00:00
|
|
|
|
self.passengerTicketStrList = ""
|
2019-09-01 04:41:25 +00:00
|
|
|
|
self.passengerTicketStrByAfterLate = ""
|
2018-08-29 11:19:13 +00:00
|
|
|
|
self.oldPassengerStr = ""
|
2018-09-19 07:42:39 +00:00
|
|
|
|
self.set_type = ""
|
2019-09-03 06:54:01 +00:00
|
|
|
|
self.flag = True
|
2018-01-07 01:54:36 +00:00
|
|
|
|
|
2019-09-01 04:41:25 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
def get_ticket_info():
|
2018-01-07 01:54:36 +00:00
|
|
|
|
"""
|
|
|
|
|
获取配置信息
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2019-01-03 12:38:08 +00:00
|
|
|
|
print(u"*" * 50)
|
2019-09-03 01:38:14 +00:00
|
|
|
|
print(f"检查当前版本为: {TickerConfig.RE_VERSION}")
|
2019-08-31 07:51:09 +00:00
|
|
|
|
print(u"检查当前python版本为:{},目前版本只支持3.6以上".format(sys.version.split(" ")[0]))
|
2019-09-03 01:38:14 +00:00
|
|
|
|
print(u"12306刷票小助手,最后更新于2019.09.03,请勿作为商业用途,交流群号:"
|
|
|
|
|
u" 1群:286271084(已满)\n"
|
2019-01-14 10:13:00 +00:00
|
|
|
|
u" 2群:649992274(已满)\n"
|
|
|
|
|
u" 3群:632501142(已满)\n"
|
|
|
|
|
u" 4群: 606340519(已满)\n"
|
2019-01-16 03:19:32 +00:00
|
|
|
|
u" 5群: 948526733(已满)\n"
|
2019-01-14 10:13:00 +00:00
|
|
|
|
u" 6群: 444101020(未满)\n"
|
|
|
|
|
u" 7群: 660689659(未满)\n"
|
|
|
|
|
)
|
2019-09-01 04:41:25 +00:00
|
|
|
|
print(
|
|
|
|
|
f"当前配置:\n出发站:{TickerConfig.FROM_STATION}\n到达站:{TickerConfig.TO_STATION}\n乘车日期:{','.join(TickerConfig.STATION_DATES)}\n坐席:{','.join(TickerConfig.SET_TYPE)}\n是否有票优先提交:{TickerConfig.IS_MORE_TICKET}\n乘车人:{TickerConfig.TICKET_PEOPLES}\n" \
|
|
|
|
|
f"刷新间隔: 随机(1-3S)\n僵尸票关小黑屋时长: {TickerConfig.TICKET_BLACK_LIST_TIME}\n下单接口: {TickerConfig.ORDER_TYPE}\n下单模式: {TickerConfig.ORDER_MODEL}\n预售踩点时间:{TickerConfig.OPEN_TIME}")
|
|
|
|
|
print(u"*" * 50)
|
2017-05-17 12:32:37 +00:00
|
|
|
|
|
2017-05-21 08:48:34 +00:00
|
|
|
|
def station_table(self, from_station, to_station):
|
2017-05-17 12:32:37 +00:00
|
|
|
|
"""
|
|
|
|
|
读取车站信息
|
|
|
|
|
:param station:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2019-01-04 03:00:10 +00:00
|
|
|
|
path = os.path.join(os.path.dirname(__file__), '../station_name.txt')
|
2019-01-16 13:20:56 +00:00
|
|
|
|
try:
|
|
|
|
|
with open(path, encoding="utf-8") as result:
|
|
|
|
|
info = result.read().split('=')[1].strip("'").split('@')
|
2019-01-17 07:33:10 +00:00
|
|
|
|
except Exception:
|
2019-01-16 13:20:56 +00:00
|
|
|
|
with open(path) as result:
|
|
|
|
|
info = result.read().split('=')[1].strip("'").split('@')
|
2017-05-17 12:32:37 +00:00
|
|
|
|
del info[0]
|
|
|
|
|
station_name = {}
|
|
|
|
|
for i in range(0, len(info)):
|
|
|
|
|
n_info = info[i].split('|')
|
|
|
|
|
station_name[n_info[1]] = n_info[2]
|
2019-01-12 07:26:02 +00:00
|
|
|
|
try:
|
|
|
|
|
from_station = station_name[from_station.encode("utf8")]
|
|
|
|
|
to_station = station_name[to_station.encode("utf8")]
|
|
|
|
|
except KeyError:
|
|
|
|
|
from_station = station_name[from_station]
|
|
|
|
|
to_station = station_name[to_station]
|
2017-05-17 12:32:37 +00:00
|
|
|
|
return from_station, to_station
|
|
|
|
|
|
2018-01-23 04:59:47 +00:00
|
|
|
|
def call_login(self, auth=False):
|
2018-01-21 05:47:38 +00:00
|
|
|
|
"""
|
|
|
|
|
登录回调方法
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2018-01-23 04:59:47 +00:00
|
|
|
|
if auth:
|
2018-01-24 02:06:25 +00:00
|
|
|
|
return self.login.auth()
|
2018-01-23 04:59:47 +00:00
|
|
|
|
else:
|
2019-01-16 03:19:32 +00:00
|
|
|
|
configCommon.checkSleepTime(self) # 防止网上启动晚上到点休眠
|
2018-01-24 02:06:25 +00:00
|
|
|
|
self.login.go_login()
|
2018-01-15 15:30:15 +00:00
|
|
|
|
|
2018-08-31 16:24:40 +00:00
|
|
|
|
def cdn_req(self, cdn):
|
|
|
|
|
for i in range(len(cdn) - 1):
|
2019-01-08 09:04:40 +00:00
|
|
|
|
http = HTTPClient(0)
|
2018-12-26 08:05:51 +00:00
|
|
|
|
urls = self.urls["loginInitCdn"]
|
|
|
|
|
http._cdn = cdn[i].replace("\n", "")
|
2018-09-30 06:35:27 +00:00
|
|
|
|
start_time = datetime.datetime.now()
|
2018-08-31 16:24:40 +00:00
|
|
|
|
rep = http.send(urls)
|
|
|
|
|
if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 500:
|
2018-12-26 08:05:51 +00:00
|
|
|
|
if cdn[i].replace("\n", "") not in self.cdn_list: # 如果有重复的cdn,则放弃加入
|
2019-01-08 01:48:18 +00:00
|
|
|
|
# print(u"加入cdn {0}".format(cdn[i].replace("\n", "")))
|
2018-12-26 08:05:51 +00:00
|
|
|
|
self.cdn_list.append(cdn[i].replace("\n", ""))
|
2018-08-31 16:24:40 +00:00
|
|
|
|
print(u"所有cdn解析完成...")
|
|
|
|
|
|
|
|
|
|
def cdn_certification(self):
|
|
|
|
|
"""
|
|
|
|
|
cdn 认证
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2019-09-01 04:41:25 +00:00
|
|
|
|
if TickerConfig.IS_CDN == 1:
|
2018-08-31 16:24:40 +00:00
|
|
|
|
CDN = CDNProxy()
|
2018-12-26 08:05:51 +00:00
|
|
|
|
all_cdn = CDN.open_cdn_file()
|
2018-08-31 16:24:40 +00:00
|
|
|
|
if all_cdn:
|
2018-12-26 08:05:51 +00:00
|
|
|
|
# print(u"由于12306网站策略调整,cdn功能暂时关闭。")
|
|
|
|
|
print(u"开启cdn查询")
|
|
|
|
|
print(u"本次待筛选cdn总数为{}, 筛选时间大约为5-10min".format(len(all_cdn)))
|
|
|
|
|
t = threading.Thread(target=self.cdn_req, args=(all_cdn,))
|
2018-12-26 10:09:30 +00:00
|
|
|
|
t.setDaemon(True)
|
2018-09-30 06:35:27 +00:00
|
|
|
|
# t2 = threading.Thread(target=self.set_cdn, args=())
|
2018-12-26 08:05:51 +00:00
|
|
|
|
t.start()
|
2018-09-30 06:35:27 +00:00
|
|
|
|
# t2.start()
|
2018-08-31 16:24:40 +00:00
|
|
|
|
else:
|
|
|
|
|
raise ticketConfigException(u"cdn列表为空,请先加载cdn")
|
|
|
|
|
|
2018-01-29 13:59:01 +00:00
|
|
|
|
def main(self):
|
2019-01-12 13:28:46 +00:00
|
|
|
|
self.cdn_certification()
|
|
|
|
|
l = liftTicketInit(self)
|
|
|
|
|
l.reqLiftTicketInit()
|
2019-09-03 06:54:01 +00:00
|
|
|
|
# getDrvicesID(self)
|
2019-01-12 13:28:46 +00:00
|
|
|
|
self.call_login()
|
|
|
|
|
check_user = checkUser(self)
|
|
|
|
|
t = threading.Thread(target=check_user.sendCheckUser)
|
|
|
|
|
t.setDaemon(True)
|
|
|
|
|
t.start()
|
2019-09-01 04:41:25 +00:00
|
|
|
|
from_station, to_station = self.station_table(TickerConfig.FROM_STATION, TickerConfig.TO_STATION)
|
2019-01-12 13:28:46 +00:00
|
|
|
|
num = 0
|
2019-09-01 04:41:25 +00:00
|
|
|
|
s = getPassengerDTOs(session=self, ticket_peoples=TickerConfig.TICKET_PEOPLES)
|
2019-01-23 04:28:41 +00:00
|
|
|
|
passenger = s.sendGetPassengerDTOs()
|
|
|
|
|
wrapcache.set("user_info", passenger, timeout=9999999)
|
2019-01-12 13:28:46 +00:00
|
|
|
|
while 1:
|
|
|
|
|
try:
|
|
|
|
|
num += 1
|
|
|
|
|
now = datetime.datetime.now() # 感谢群里大佬提供整点代码
|
2019-09-01 04:41:25 +00:00
|
|
|
|
configCommon.checkSleepTime(self) # 晚上到点休眠
|
|
|
|
|
if TickerConfig.ORDER_MODEL is 1:
|
2019-01-12 13:28:46 +00:00
|
|
|
|
sleep_time_s = 0.5
|
|
|
|
|
sleep_time_t = 0.6
|
|
|
|
|
# 测试了一下有微妙级的误差,应该不影响,测试结果:2019-01-02 22:30:00.004555,预售还是会受到前一次刷新的时间影响,暂时没想到好的解决方案
|
2019-09-01 04:41:25 +00:00
|
|
|
|
while not now.strftime("%H:%M:%S") == TickerConfig.OPEN_TIME:
|
2019-01-12 13:28:46 +00:00
|
|
|
|
now = datetime.datetime.now()
|
2019-09-01 04:41:25 +00:00
|
|
|
|
if now.strftime("%H:%M:%S") > TickerConfig.OPEN_TIME:
|
2019-01-12 13:28:46 +00:00
|
|
|
|
break
|
|
|
|
|
time.sleep(0.0001)
|
|
|
|
|
else:
|
|
|
|
|
sleep_time_s = 0.5
|
|
|
|
|
sleep_time_t = 3
|
|
|
|
|
q = query(session=self,
|
|
|
|
|
from_station=from_station,
|
|
|
|
|
to_station=to_station,
|
2019-09-01 04:41:25 +00:00
|
|
|
|
from_station_h=TickerConfig.FROM_STATION,
|
2019-09-02 03:21:04 +00:00
|
|
|
|
to_station_h=TickerConfig.TO_STATION,
|
2019-01-12 13:28:46 +00:00
|
|
|
|
_station_seat=self._station_seat,
|
2019-09-01 04:41:25 +00:00
|
|
|
|
station_trains=TickerConfig.STATION_TRAINS,
|
|
|
|
|
station_dates=TickerConfig.STATION_DATES,
|
|
|
|
|
ticke_peoples_num=len(TickerConfig.TICKET_PEOPLES),
|
2019-01-12 13:28:46 +00:00
|
|
|
|
)
|
|
|
|
|
queryResult = q.sendQuery()
|
|
|
|
|
# 查询接口
|
|
|
|
|
if queryResult.get("status", False):
|
|
|
|
|
train_no = queryResult.get("train_no", "")
|
|
|
|
|
train_date = queryResult.get("train_date", "")
|
|
|
|
|
stationTrainCode = queryResult.get("stationTrainCode", "")
|
|
|
|
|
secretStr = queryResult.get("secretStr", "")
|
2019-09-02 12:19:24 +00:00
|
|
|
|
secretList = queryResult.get("secretList", "")
|
2019-01-12 13:28:46 +00:00
|
|
|
|
seat = queryResult.get("seat", "")
|
|
|
|
|
leftTicket = queryResult.get("leftTicket", "")
|
|
|
|
|
query_from_station_name = queryResult.get("query_from_station_name", "")
|
|
|
|
|
query_to_station_name = queryResult.get("query_to_station_name", "")
|
2019-09-01 04:41:25 +00:00
|
|
|
|
is_more_ticket_num = queryResult.get("is_more_ticket_num", len(TickerConfig.TICKET_PEOPLES))
|
2019-01-12 13:28:46 +00:00
|
|
|
|
if wrapcache.get(train_no):
|
|
|
|
|
print(ticket.QUEUE_WARNING_MSG.format(train_no))
|
2019-01-12 07:26:02 +00:00
|
|
|
|
else:
|
2019-01-12 13:28:46 +00:00
|
|
|
|
# 获取联系人
|
2019-09-01 04:41:25 +00:00
|
|
|
|
s = getPassengerDTOs(session=self, ticket_peoples=TickerConfig.TICKET_PEOPLES,
|
|
|
|
|
set_type="" if isinstance(seat, list) else seat_conf_2[seat],
|
|
|
|
|
# 候补订单需要设置多个坐席
|
2019-01-12 13:28:46 +00:00
|
|
|
|
is_more_ticket_num=is_more_ticket_num)
|
2019-09-02 12:19:24 +00:00
|
|
|
|
getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr(secretStr, secretList)
|
2019-01-12 13:28:46 +00:00
|
|
|
|
if getPassengerDTOsResult.get("status", False):
|
|
|
|
|
self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "")
|
2019-09-01 04:41:25 +00:00
|
|
|
|
self.passengerTicketStrByAfterLate = getPassengerDTOsResult.get(
|
|
|
|
|
"passengerTicketStrByAfterLate", "")
|
2019-01-12 13:28:46 +00:00
|
|
|
|
self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "")
|
|
|
|
|
self.set_type = getPassengerDTOsResult.get("set_type", "")
|
|
|
|
|
# 提交订单
|
2019-09-01 04:41:25 +00:00
|
|
|
|
# 订单分为两种,一种为抢单,一种为候补订单
|
2019-09-02 12:19:24 +00:00
|
|
|
|
if secretStr: # 正常下单
|
2019-09-01 04:41:25 +00:00
|
|
|
|
if TickerConfig.ORDER_TYPE == 1: # 快速下单
|
|
|
|
|
a = autoSubmitOrderRequest(session=self,
|
|
|
|
|
secretStr=secretStr,
|
|
|
|
|
train_date=train_date,
|
|
|
|
|
passengerTicketStr=self.passengerTicketStrList,
|
|
|
|
|
oldPassengerStr=self.oldPassengerStr,
|
|
|
|
|
train_no=train_no,
|
|
|
|
|
stationTrainCode=stationTrainCode,
|
|
|
|
|
leftTicket=leftTicket,
|
|
|
|
|
set_type=self.set_type,
|
|
|
|
|
query_from_station_name=query_from_station_name,
|
|
|
|
|
query_to_station_name=query_to_station_name,
|
|
|
|
|
)
|
|
|
|
|
a.sendAutoSubmitOrderRequest()
|
|
|
|
|
elif TickerConfig.ORDER_TYPE == 2: # 普通下单
|
|
|
|
|
sor = submitOrderRequest(self, secretStr, from_station, to_station, train_no,
|
|
|
|
|
self.set_type,
|
|
|
|
|
self.passengerTicketStrList, self.oldPassengerStr, train_date,
|
|
|
|
|
TickerConfig.TICKET_PEOPLES)
|
|
|
|
|
sor.sendSubmitOrderRequest()
|
2019-09-02 12:19:24 +00:00
|
|
|
|
elif secretList: # 候补订单
|
|
|
|
|
c = chechFace(self, secretList)
|
2019-09-01 04:41:25 +00:00
|
|
|
|
c.sendChechFace()
|
2019-01-12 13:28:46 +00:00
|
|
|
|
else:
|
|
|
|
|
random_time = round(random.uniform(sleep_time_s, sleep_time_t), 2)
|
2019-09-03 06:54:01 +00:00
|
|
|
|
nateMsg = ' 无候补机会' if TickerConfig.ORDER_TYPE == 2 else ""
|
2019-09-03 01:38:14 +00:00
|
|
|
|
print(f"正在第{num}次查询 随机停留时长:{random_time} 乘车日期: {','.join(TickerConfig.STATION_DATES)} 车次:{'.'.join(TickerConfig.STATION_TRAINS)} 下单无票{nateMsg} 耗时:{(datetime.datetime.now() - now).microseconds / 1000}ms")
|
2019-01-12 13:28:46 +00:00
|
|
|
|
time.sleep(random_time)
|
|
|
|
|
except PassengerUserException as e:
|
|
|
|
|
print(e)
|
2019-01-14 01:46:33 +00:00
|
|
|
|
break
|
2019-01-12 13:28:46 +00:00
|
|
|
|
except ticketConfigException as e:
|
|
|
|
|
print(e)
|
2019-01-14 01:46:33 +00:00
|
|
|
|
break
|
2019-01-12 13:28:46 +00:00
|
|
|
|
except ticketIsExitsException as e:
|
|
|
|
|
print(e)
|
2019-01-14 01:46:33 +00:00
|
|
|
|
break
|
2019-01-12 13:28:46 +00:00
|
|
|
|
except ticketNumOutException as e:
|
|
|
|
|
print(e)
|
2019-01-14 01:46:33 +00:00
|
|
|
|
break
|
2019-01-12 13:28:46 +00:00
|
|
|
|
except UserPasswordException as e:
|
|
|
|
|
print(e)
|
2019-01-14 01:46:33 +00:00
|
|
|
|
break
|
2019-01-12 13:28:46 +00:00
|
|
|
|
except ValueError as e:
|
|
|
|
|
if e == "No JSON object could be decoded":
|
|
|
|
|
print(u"12306接口无响应,正在重试")
|
|
|
|
|
else:
|
|
|
|
|
print(e)
|
|
|
|
|
except KeyError as e:
|
|
|
|
|
print(e)
|
|
|
|
|
except TypeError as e:
|
|
|
|
|
print(u"12306接口无响应,正在重试 {0}".format(e))
|
|
|
|
|
except socket.error as e:
|
2019-01-04 01:38:40 +00:00
|
|
|
|
print(e)
|
2018-01-12 06:42:30 +00:00
|
|
|
|
|
|
|
|
|
|
2017-05-17 12:32:37 +00:00
|
|
|
|
if __name__ == '__main__':
|
2018-12-26 08:05:51 +00:00
|
|
|
|
s = select()
|
2019-01-16 03:19:32 +00:00
|
|
|
|
cdn = s.station_table("长沙", "深圳")
|