1、增加快速订票流程接口

2、尝试解决慢排队
pull/42/head
wenxianping 2018-06-11 23:03:23 +08:00
parent f86f7b9c33
commit b88d541f93
48 changed files with 1116 additions and 72 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
.idea/dictionaries/wenxianping.xml Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

0
__init__.py Normal file → Executable file
View File

0
agency/__init__.py Normal file → Executable file
View File

0
agency/agency_tools.py Normal file → Executable file
View File

0
agency/cdn_utils.py Normal file → Executable file
View File

0
cdn_list Normal file → Executable file
View File

35
config/TicketEnmu.py Normal file
View File

@ -0,0 +1,35 @@
# coding=utf-8
class ticket(object):
QUERY_C = u"查询到有余票,尝试提交订单"
QUERY_IN_BLACK_LIST = u"该车次{} 正在被关小黑屋,跳过此车次"
SUCCESS_CODE = 000000
FAIL_CODE = 999999
AUTO_SUBMIT_ORDER_REQUEST_C = u"提交订单成功"
AUTO_SUBMIT_ORDER_REQUEST_F = u"提交订单失败,重新刷票中"
AUTO_SUBMIT_NEED_CODE = u"需要验证码"
AUTO_SUBMIT_NOT_NEED_CODE = u"不需要验证码"
TICKET_BLACK_LIST_TIME = 5 # 加入小黑屋的等待时间默认5 min
DTO_NOT_FOUND = u"未查找到常用联系人"
DTO_NOT_IN_LIST = u"联系人不在列表中,请查证后添加"
QUEUE_TICKET_SHORT = u"当前余票数小于乘车人数,放弃订票"
QUEUE_TICKET_SUCCESS = u"排队成功, 当前余票还剩余: {0}"
QUEUE_JOIN_BLACK = u"排队发现未知错误{0},将此列车 {1}加入小黑屋"
QUEUE_WARNING_MSG = u"排队异常,错误信息:{0}, 将此列车 {1}加入小黑屋"
OUT_NUM = 30 # 排队请求12306的次数
WAIT_OUT_NUM = u"超出排队时间,自动放弃,正在重新刷票"
WAIT_ORDER_SUCCESS = u"恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306访问未完成订单在30分钟内完成支付!"
WAIT_ORDER_CONTINUE = u"排队等待时间预计还剩 {0} ms"
WAIT_ORDER_FAIL = u"排队等待失败,错误消息:{0}"
WAIT_ORDER_NUM = u"{0}次排队中,请耐心等待"
WAIT_ORDER_SUB_FAIL = u"订单提交失败!,正在重新刷票"
CANCEL_ORDER_SUCCESS = u"排队超时,已为您自动取消订单,订单编号: {0}"
CANCEL_ORDER_FAIL = u"排队超时,取消订单失败, 订单号{0}"

0
config/__init__.py Normal file → Executable file
View File

0
config/configCommon.py Normal file → Executable file
View File

0
config/emailConf.py Normal file → Executable file
View File

0
config/logger.py Normal file → Executable file
View File

0
config/ticketConf.py Normal file → Executable file
View File

8
config/ticket_config.yaml Normal file → Executable file
View File

@ -41,11 +41,11 @@
set:
station_dates:
- "2018-03-19"
# - "2018-02-21"
- "2018-06-21"
- "2018-06-22"
station_trains:
- "G4831"
- "G1321"
from_station: "上海"
to_station: "长沙"
@ -60,7 +60,7 @@ set:
12306count:
# - uesr: ""
# - pwd: "apple1995"
- uesr: "@qq.com"
- uesr: "931128603@qq.com"
- pwd: "QWERTY"
select_refresh_interval: 1

88
config/urlConf.py Normal file → Executable file
View File

@ -1,24 +1,27 @@
# coding=utf-8
import random
import time
urls = {
"auth": {
"auth": { # 登录接口
"req_url": "/passport/web/auth/uamtk",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": True,
"is_json": True,
},
"login": {
"login": { # 登录接口
"req_url": "/passport/web/login",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
@ -26,29 +29,44 @@ urls = {
"is_json": True,
},
"getCodeImg": {
"left_ticket_init": { # 登录接口
"req_url": "/otn/leftTicket/init",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": False,
"is_json": False,
},
"getCodeImg": { # 登录验证码
"req_url": "/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{0}",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": False,
"is_json": False,
},
"codeCheck": {
"codeCheck": { # 验证码校验
"req_url": "/passport/captcha/captcha-check",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": True,
"is_json": True,
},
"loginInit": {
"loginInit": { # 登录页面
"req_url": "/otn/login/init",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/index/init",
@ -59,7 +77,7 @@ urls = {
"is_logger": False,
"is_json": False,
},
"getUserInfo": {
"getUserInfo": { # 获取用户信息
"req_url": "/otn/index/initMy12306",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
@ -70,7 +88,7 @@ urls = {
"is_logger": False,
"is_json": False,
},
"userLogin": {
"userLogin": { # 用户登录
"req_url": "/otn/login/userLogin",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
@ -81,18 +99,19 @@ urls = {
"is_logger": True,
"is_json": True,
},
"uamauthclient": {
"uamauthclient": { # 登录
"req_url": "/otn/uamauthclient",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": True,
"is_json": True,
},
"initdc_url": {
"initdc_url": { # 生成订单页面
"req_url": "/otn/confirmPassenger/initDc",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
@ -103,7 +122,7 @@ urls = {
"is_logger": False,
"is_json": False,
},
"GetJS": {
"GetJS": { # 订单页面js
"req_url": "/otn/HttpZF/GetJS",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -114,7 +133,7 @@ urls = {
"is_logger": False,
"is_json": False,
},
"odxmfwg": {
"odxmfwg": { # 订单页面js
"req_url": "/otn/dynamicJs/odxmfwg",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -125,7 +144,7 @@ urls = {
"is_logger": False,
"is_json": False,
},
"get_passengerDTOs": {
"get_passengerDTOs": { # 获取乘车人
"req_url": "/otn/confirmPassenger/getPassengerDTOs",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -136,8 +155,8 @@ urls = {
"is_logger": True,
"is_json": True,
},
"select_url": {
"req_url": "/otn/leftTicket/queryO?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT",
"select_url": { # 查询余票
"req_url": "/otn/leftTicket/query?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Host": "kyfw.12306.cn",
@ -147,7 +166,7 @@ urls = {
"is_logger": False,
"is_json": True,
},
"check_user_url": {
"check_user_url": { # 检查用户登录
"req_url": "/otn/login/checkUser",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
@ -158,7 +177,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"submit_station_url": {
"submit_station_url": { # 提交订单
"req_url": "/otn/leftTicket/submitOrderRequest",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
@ -169,7 +188,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"checkOrderInfoUrl": {
"checkOrderInfoUrl": { # 检查订单信息规范
"req_url": "/otn/confirmPassenger/checkOrderInfo",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -180,7 +199,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"getQueueCountUrl": {
"getQueueCountUrl": { # 剩余余票数
"req_url": "/otn/confirmPassenger/getQueueCount",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -191,7 +210,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"checkQueueOrderUrl": {
"checkQueueOrderUrl": { # 订单队列排队
"req_url": "/otn/confirmPassenger/confirmSingleForQueue",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -202,7 +221,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"checkRandCodeAnsyn": {
"checkRandCodeAnsyn": { # 暂时没用到
"req_url": "/otn/passcodeNew/checkRandCodeAnsyn",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -213,7 +232,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"codeImgByOrder": {
"codeImgByOrder": { # 订单页面验证码
"req_url": "/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s" % random.random(),
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
@ -224,9 +243,9 @@ urls = {
"is_logger": False,
"is_json": False,
},
"queryOrderWaitTimeUrl": {
"req_url": "/otn/confirmPassenger/queryOrderWaitTime",
"req_type": "post",
"queryOrderWaitTimeUrl": { # 订单等待页面
"req_url": "/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
"Host": "kyfw.12306.cn",
"re_try": 10,
@ -235,7 +254,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"queryMyOrderNoCompleteUrl": {
"queryMyOrderNoCompleteUrl": { # 订单查询页面
"req_url": "/otn/queryOrder/queryMyOrderNoComplete",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
@ -246,7 +265,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"initNoCompleteUrl": {
"initNoCompleteUrl": { # 获取订单列表
"req_url": "/otn/queryOrder/initNoComplete",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
@ -257,7 +276,7 @@ urls = {
"is_logger": True,
"is_json": True,
},
"cancelNoCompleteMyOrder": {
"cancelNoCompleteMyOrder": { # 取消订单
"req_url": "/otn/queryOrder/cancelNoCompleteMyOrder",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
@ -268,32 +287,35 @@ urls = {
"is_logger": True,
"is_json": True,
},
"autoSubmitOrderRequest": {
"autoSubmitOrderRequest": { # 快速自动提交订单
"req_url": "/otn/confirmPassenger/autoSubmitOrderRequest",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": True,
"is_json": True,
},
"getQueueCountAsync": {
"getQueueCountAsync": { # 快速获取订单数据
"req_url": "/otn/confirmPassenger/getQueueCountAsync",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Host": "kyfw.12306.cn",
"Content-Type": 1,
"re_try": 10,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": True,
"is_json": True,
},
"confirmSingleForQueueAsys": {
"confirmSingleForQueueAsys": { # 快速订单排队
"req_url": "/otn/confirmPassenger/confirmSingleForQueueAsys",
"req_type": "post",
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Content-Type": 1,
"Host": "kyfw.12306.cn",
"re_try": 10,
"re_time": 0.1,

0
damatuCode/__init__.py Normal file → Executable file
View File

0
damatuCode/damatuWeb.py Normal file → Executable file
View File

0
damatuCode/ruokuai.py Normal file → Executable file
View File

293
init/SelectTicketInfoFast.py Executable file
View File

@ -0,0 +1,293 @@
# -*- coding=utf-8 -*-
import datetime
import json
import random
import re
import socket
import sys
import threading
import time
import urllib
from collections import OrderedDict
import collections
from agency.cdn_utils import CDNProxy
from config import urlConf
from config.emailConf import sendEmail
from config.ticketConf import _get_yaml
from init import login
from init.login import GoLogin
from inter.AutoSubmitOrderRequest import autoSubmitOrderRequest
from inter.ConfirmSingleForQueueAsys import confirmSingleForQueueAsys
from inter.GetPassengerDTOs import getPassengerDTOs
from inter.GetQueueCountAsync import getQueueCountAsync
from inter.LiftTicketInit import liftTicketInit
from inter.Query import query
from inter.QueryOrderWaitTime import queryOrderWaitTime
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.httpUtils import HTTPClient
reload(sys)
sys.setdefaultencoding('utf-8')
class selectFast:
"""
快速提交车票通道
"""
def __init__(self):
self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.ticket_black_list_time = self.get_ticket_info()
self.is_aotu_code = _get_yaml()["is_aotu_code"]
self.aotu_code_type = _get_yaml()["aotu_code_type"]
self.is_cdn = _get_yaml()["is_cdn"]
self.httpClint = HTTPClient()
self.urls = urlConf.urls
self.login = GoLogin(self.httpClint, self.urls, self.is_aotu_code, self.aotu_code_type)
self.is_download_img = False
self.cdn_list = []
self.is_check_user = dict()
self.ticket_black_list = dict()
self.black_train_no = ""
self.passengerTicketStrList = ""
self.oldPassengerStr = ""
def get_ticket_info(self):
"""
获取配置信息
:return:
"""
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_dates = ticket_info_config["set"]["station_dates"]
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"]
ticket_black_list_time = ticket_info_config["ticket_black_list_time"]
print u"*" * 20
print u"12306刷票小助手最后更新于2018.2.28请勿作为商业用途交流群号286271084"
print u"如果有好的margin请联系作者表示非常感激\n"
print u"当前配置:出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票自动提交:{4}\n乘车人:{5}\n刷新间隔:随机(1-4S)\n候选购买车次:{7}\n僵尸票关小黑屋时长:{8}\n".format \
(
from_station,
to_station,
station_dates,
",".join(set_type),
is_more_ticket,
",".join(ticke_peoples),
select_refresh_interval,
",".join(station_trains),
ticket_black_list_time,
)
print u"*" * 20
return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, ticket_black_list_time
def station_table(self, from_station, to_station):
"""
读取车站信息
:param station:
:return:
"""
result = open('station_name.txt')
info = result.read().split('=')[1].strip("'").split('@')
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]
from_station = station_name[from_station.encode("utf8")]
to_station = station_name[to_station.encode("utf8")]
return from_station, to_station
def call_login(self, auth=False):
"""
登录回调方法
:return:
"""
if auth:
return self.login.auth()
else:
self.login.go_login()
def check_user(self):
"""
检查用户是否达到订票条件
:return:
"""
check_user_url = self.urls["check_user_url"]
data = {"_json_att": ""}
check_user = self.httpClint.send(check_user_url, data)
check_user_flag = check_user['data']['flag']
if check_user_flag is True:
self.is_check_user["user_time"] = datetime.datetime.now()
else:
if check_user['messages']:
print (u'用户检查失败:%s可能未登录可能session已经失效' % check_user['messages'][0])
print (u'正在尝试重新登录')
self.call_login()
self.is_check_user["user_time"] = datetime.datetime.now()
else:
print (u'用户检查失败: %s可能未登录可能session已经失效' % check_user)
print (u'正在尝试重新登录')
self.call_login()
self.is_check_user["user_time"] = datetime.datetime.now()
def main(self):
l = liftTicketInit(session=self)
l.reqLiftTicketInit()
self.call_login()
self.check_user()
from_station, to_station = self.station_table(self.from_station, self.to_station)
passengerTicketStrList, oldPassengerStr, set_type = "", "", ""
num = 1
while 1:
try:
num += 1
if "user_time" in self.is_check_user and (
datetime.datetime.now() - self.is_check_user["user_time"]).seconds / 60 > 5:
# 5分钟检查一次用户是否登录
self.check_user()
time.sleep(self.select_refresh_interval)
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00" or time.strftime('%H:%M:%S',
time.localtime(
time.time())) < "06:00:00":
print(u"12306休息时间本程序自动停止,明天早上6点将自动运行")
while 1:
time.sleep(1)
if "06:00:00" < time.strftime('%H:%M:%S', time.localtime(time.time())) < "23:00:00":
print(u"休息时间已过,重新开启检票功能")
self.call_login()
break
start_time = datetime.datetime.now()
q = query(session=self,
from_station=from_station,
to_station=to_station,
from_station_h=self.from_station,
to_station_h=self.to_station,
_station_seat=self._station_seat,
station_trains=self.station_trains,
station_dates=self.station_dates,
black_train_no=self.black_train_no)
queryResult = q.sendQuery()
self.black_train_no = "" # 重置小黑屋名单
# 查询接口
if queryResult.get("status", False):
secretStr = queryResult.get("secretStr", "")
train_no = queryResult.get("train_no", "")
stationTrainCode = queryResult.get("stationTrainCode", "")
train_date = queryResult.get("train_date", "")
query_from_station_name = queryResult.get("query_from_station_name", "")
query_to_station_name = queryResult.get("query_to_station_name", "")
set_type = queryResult.get("set_type", "")
leftTicket = queryResult.get("leftTicket", "")
if self.ticket_black_list.has_key(train_no) and (
datetime.datetime.now() - self.ticket_black_list[train_no]).seconds / 60 < int(
self.ticket_black_list_time):
print(u"该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
else:
# 获取联系人
if not self.passengerTicketStrList and not self.oldPassengerStr:
s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=set_type)
getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr()
if getPassengerDTOsResult.get("status", False):
self.passengerTicketStrList = getPassengerDTOsResult.get("passengerTicketStrList", "")
self.oldPassengerStr = getPassengerDTOsResult.get("oldPassengerStr", "")
set_type = getPassengerDTOsResult.get("set_type", "")
# 提交订单
a = autoSubmitOrderRequest(session=self,
secretStr=secretStr,
train_date=train_date,
query_from_station_name=self.from_station,
query_to_station_name=self.to_station,
passengerTicketStr=self.passengerTicketStrList,
oldPassengerStr=self.oldPassengerStr
)
submitResult = a.sendAutoSubmitOrderRequest()
if submitResult.get("status", False):
result = submitResult.get("result", "")
# 订单排队
time.sleep(submitResult.get("ifShowPassCodeTime", 1))
g = getQueueCountAsync(session=self,
train_no=train_no,
stationTrainCode=stationTrainCode,
fromStationTelecode=query_from_station_name,
toStationTelecode=query_to_station_name,
leftTicket=leftTicket,
set_type=set_type,
users=len(self.ticke_peoples),
)
getQueueCountAsyncResult = g.sendGetQueueCountAsync()
time.sleep(submitResult.get("ifShowPassCodeTime", 1))
if getQueueCountAsyncResult.get("is_black", False):
self.black_train_no = getQueueCountAsyncResult.get("train_no", "")
if getQueueCountAsyncResult.get("status", False):
# 请求订单快读接口
c = confirmSingleForQueueAsys(session=self,
passengerTicketStr=self.passengerTicketStrList,
oldPassengerStr=self.oldPassengerStr,
result=result, )
confirmSingleForQueueAsysResult = c.sendConfirmSingleForQueueAsys()
# 排队
if confirmSingleForQueueAsysResult.get("status", False):
qwt = queryOrderWaitTime(session=self)
qwt.sendQueryOrderWaitTime()
else:
self.httpClint.del_cookies()
else:
s_time = random.randint(0, 4)
time.sleep(s_time)
print u"正在第{0}次查询 随机停留时长:{6} 乘车日期: {1} 车次:{2} 查询无票 cdn轮询IP{4}当前cdn总数{5} 总耗时:{3}ms".format(num,
",".join(
self.station_dates),
",".join(
self.station_trains),
(
datetime.datetime.now() - start_time).microseconds / 1000,
self.httpClint.cdn,
len(
self.cdn_list),
s_time)
except PassengerUserException as e:
print e.message
break
except ticketConfigException as e:
print e.message
break
except ticketIsExitsException as e:
print e.message
break
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(u"12306接口无响应正在重试")
else:
print(e.message)
except KeyError as e:
print(e.message)
# except TypeError as e:
# print(u"12306接口无响应正在重试 {0}".format(e.message))
except socket.error as e:
print(e.message)
if __name__ == '__main__':
s = selectFast()
s.main()
# a = select('上海', '北京')
# a.main()

0
init/__init__.py Normal file → Executable file
View File

12
init/login.py Normal file → Executable file
View File

@ -216,10 +216,14 @@ class GoLogin:
login_num = 0
while True:
self.cookietp()
self.httpClint.set_cookies(_jc_save_showIns="true",
_jc_save_wfdc_flag="dc",
_jc_save_fromDate=_get_yaml()["set"]["station_dates"][0],
_jc_save_toDate=_get_yaml()["set"]["station_dates"][0])
# self.httpClint.set_cookies(_jc_save_showIns="true",
# _jc_save_wfdc_flag="dc",
# _jc_save_toDate="2018-06-06",
# _jc_save_fromDate=_get_yaml()["set"]["station_dates"][0],
# RAIL_EXPIRATION="1528337042724",
# RAIL_DEVICEID="O6DFHLmFChFrZUI7QyY9xcqj94eZG9JH_kD3zSZt53tkCUq0uqdvlo1fm_CmNxr_QAnMOU79JmHI8jbtj2vaNUnOZKCqcsMNbhCaoDIB3vxgsyzMMGOZF-CknXKEFaCLPGyDNXEknPDs7xgSbanwKqsiSRT41xti",
#
# )
self.urlConf["getCodeImg"]["req_url"] = self.urlConf["getCodeImg"]["req_url"].format(random.random())
self.readImg(self.urlConf["getCodeImg"])
self.randCode = self.getRandCode()

8
init/select_ticket_info.py Normal file → Executable file
View File

@ -43,6 +43,7 @@ class select:
self.user_info = ""
self.secretStr = ""
self.ticket_black_list = dict()
self.ticket_black_list_time = dict()
self.is_check_user = dict()
self.httpClint = HTTPClient()
self.confUrl = urlConf.urls
@ -204,7 +205,7 @@ class select:
'REPEAT_SUBMIT_TOKEN': self.token
}
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 'l' in jsonData['data'] and 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]
@ -581,7 +582,7 @@ class select:
elif "waitTime"in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["waitTime"]:
print(u"排队等待时间预计还剩 {0} ms".format(0-queryOrderWaitTimeResult["data"]["waitTime"]))
else:
print ("正在等待中")
print (u"正在等待中")
elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
print(u"排队等待失败: " + queryOrderWaitTimeResult["messages"])
else:
@ -732,7 +733,8 @@ class select:
print u"正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 cdn轮询IP {4} 当前cdn总数{5} 总耗时{3}ms".format(num,
",".join(self.station_dates),
",".join(self.station_trains),
(datetime.datetime.now()-start_time).microseconds/1000, self.httpClint.cdn,
(datetime.datetime.now()-start_time).microseconds/1000,
self.httpClint.cdn,
len(self.cdn_list))
self.set_cdn()
except PassengerUserException as e:

View File

@ -0,0 +1,108 @@
# coding=utf-8
import urllib
from collections import OrderedDict
from config.TicketEnmu import ticket
class autoSubmitOrderRequest:
"""
快读提交订单通道
"""
def __init__(self, session,
secretStr,
train_date,
query_from_station_name,
query_to_station_name,
passengerTicketStr,
oldPassengerStr):
self.secretStr = urllib.unquote(secretStr)
self.train_date = train_date
self.query_from_station_name = query_from_station_name
self.query_to_station_name = query_to_station_name
self.passengerTicketStr = passengerTicketStr
self.oldPassengerStr = oldPassengerStr
self.session = session
def data_par(self):
"""
参数结构
自动提交代码接口-autoSubmitOrderRequest
- 字段说明
- secretStr 车票代码
- train_date 乘车日期
- tour_flag 乘车类型
- purpose_codes 学生还是成人
- query_from_station_name 起始车站
- query_to_station_name 结束车站
- cancel_flag 默认2我也不知道干嘛的
- bed_level_order_num 000000000000000000000000000000
- passengerTicketStr 乘客乘车代码
- oldPassengerStr 乘客编号代码
:return:
"""
data = OrderedDict()
data["secretStr"] = self.secretStr
data["train_date"] = self.train_date
data["tour_flag"] = "dc"
data["purpose_codes"] = "ADULT"
data["query_from_station_name"] = self.query_from_station_name
data["query_to_station_name"] = self.query_to_station_name
data["cancel_flag"] = 2
data["bed_level_order_num"] = "000000000000000000000000000000"
data["passengerTicketStr"] = self.passengerTicketStr
data["oldPassengerStr"] = self.oldPassengerStr
return data
def sendAutoSubmitOrderRequest(self):
"""
请求下单接口
:return:
"""
urls = self.session.urls["autoSubmitOrderRequest"]
data = self.data_par()
autoSubmitOrderRequestResult = self.session.httpClint.send(urls, data)
if autoSubmitOrderRequestResult and \
autoSubmitOrderRequestResult.get("status", False) and\
autoSubmitOrderRequestResult.get("httpstatus", False) == 200:
requestResultData = autoSubmitOrderRequestResult.get("data", {})
if requestResultData:
result = requestResultData.get("result", "")
ifShowPassCode = requestResultData.get("ifShowPassCode", "N")
print(ticket.AUTO_SUBMIT_ORDER_REQUEST_C)
if ifShowPassCode == "Y": # 如果需要验证码
print(ticket.AUTO_SUBMIT_NEED_CODE)
return {
"result": result,
"ifShowPassCode": ifShowPassCode,
"code": ticket.SUCCESS_CODE,
"ifShowPassCodeTime": requestResultData.get("requestResultData", 2000) / float(1000),
"status": True,
}
else:
print(ticket.AUTO_SUBMIT_NOT_NEED_CODE)
return {
"result": result,
"ifShowPassCode": ifShowPassCode,
"code": ticket.SUCCESS_CODE,
"ifShowPassCodeTime": requestResultData.get("requestResultData", 2000) / float(1000),
"status": True,
}
else:
print(ticket.AUTO_SUBMIT_ORDER_REQUEST_F)
if autoSubmitOrderRequestResult.get("messages", ""):
print(autoSubmitOrderRequestResult.get("messages", ""))
return {
"code": ticket.FAIL_CODE,
"status": False,
}
elif autoSubmitOrderRequestResult.get("validateMessages", ""):
print(autoSubmitOrderRequestResult.get("validateMessages", ""))
return {
"code": ticket.FAIL_CODE,
"status": False,
}

View File

@ -0,0 +1,78 @@
# coding=utf-8
import json
import urllib
from collections import OrderedDict
class confirmSingleForQueueAsys:
"""
订单快读排队
"""
def __init__(self,
session,
passengerTicketStr,
oldPassengerStr,
result,
randCode="",
):
self.session = session
self.passengerTicketStr = passengerTicketStr
self.oldPassengerStr = oldPassengerStr
self.result = result if isinstance(result, str) else str(result)
self.randCode = randCode
def data_par(self):
"""
字段说明
passengerTicketStr 乘客乘车代码
oldPassengerStr 乘客编号代码
randCode 填空
purpose_codes 学生还是成人
key_check_isChange autoSubmitOrderRequest返回的result字段做切割即可
leftTicketStr autoSubmitOrderRequest返回的result字段做切割即可
train_location autoSubmitOrderRequest返回的result字段做切割即可
choose_seats
seatDetailType
_json_att
:return:
"""
results = self.result.split("#")
key_check_isChange = results[1]
leftTicketStr = results[2]
train_location = results[0]
data = OrderedDict()
data["passengerTicketStr"] = self.passengerTicketStr
data["oldPassengerStr"] = self.oldPassengerStr
data["randCode"] = self.randCode
data["purpose_codes"] = "ADULT"
data["key_check_isChange"] = key_check_isChange
data["leftTicketStr"] = leftTicketStr
data["train_location"] = train_location
data["choose_seats"] = ""
data["seatDetailType"] = ""
data["_json_att"] = ""
return data
def sendConfirmSingleForQueueAsys(self):
"""
请求订单快读排队接口
:return:
"""
urls = self.session.urls["confirmSingleForQueueAsys"]
data = self.data_par()
confirmSingleForQueueAsysResult = self.session.httpClint.send(urls, data)
if confirmSingleForQueueAsysResult.get("status", False) and confirmSingleForQueueAsysResult.get("data", False):
queueData = confirmSingleForQueueAsysResult.get("data", {})
if queueData.get("submitStatus", False):
return {
"status": True
}
else:
print(queueData.get("errMsg", ""))
return {
"status": False
}
else:
return {
"status": False
}

92
inter/GetPassengerDTOs.py Normal file
View File

@ -0,0 +1,92 @@
# coding=utf-8
from config.TicketEnmu import ticket
from myException.PassengerUserException import PassengerUserException
class getPassengerDTOs:
"""
获取乘客信息
:return:
"""
def __init__(self, session, ticket_peoples, set_type):
"""
:param session: 登录实例
:param ticket_peoples: 乘客
:param set_type: 坐席
"""
self.session = session
self.ticket_peoples = ticket_peoples
self.set_type = set_type.encode("utf8")
def sendGetPassengerDTOs(self):
getPassengerDTOsResult = self.session.httpClint.send(self.session.urls["get_passengerDTOs"], {})
getPassengerDTOsResult["data"].get("normal_passengers", False)
if getPassengerDTOsResult.get("data", False) and getPassengerDTOsResult["data"].get("normal_passengers", False):
normal_passengers = getPassengerDTOsResult['data']['normal_passengers']
_normal_passenger = [normal_passengers[i] for i in range(len(normal_passengers)) if
normal_passengers[i]["passenger_name"] in self.ticket_peoples]
return _normal_passenger if _normal_passenger else [normal_passengers[0]] # 如果配置乘车人没有在账号,则默认返回第一个用户
else:
if getPassengerDTOsResult.get("data", False) and getPassengerDTOsResult['data'].get("exMsg", False):
print(getPassengerDTOsResult['data'].get("exMsg", False))
elif getPassengerDTOsResult.get('messages', False):
print(getPassengerDTOsResult.get('messages', False))
else:
raise PassengerUserException(ticket.DTO_NOT_FOUND)
def getPassengerTicketStr(self, set_type):
"""
获取getPassengerTicketStr 提交对应的代号码
:param str: 坐席
:return:
"""
passengerTicketStr = {
'一等座': 'M',
'特等座': 'P',
'二等座': 'O',
'商务座': 9,
'硬座': 1,
'无座': 1,
'软卧': 4,
'硬卧': 3,
}
return str(passengerTicketStr[set_type.replace(' ', '')])
def getPassengerTicketStrListAndOldPassengerStr(self):
"""
获取提交车次人内容格式
passengerTicketStr O,0,1,文贤平,1,43052419950223XXXX,15618715583,N_O,0,1,梁敏,1,43052719920118XXXX,,N
oldPassengerStr 文贤平,1,43052719920118XXXX,1_梁敏,1,43052719920118XXXX,1_
:return:
"""
passengerTicketStrList = []
oldPassengerStr = []
user_info = self.sendGetPassengerDTOs()
set_type = self.getPassengerTicketStr(self.set_type)
if not user_info:
raise PassengerUserException(ticket.DTO_NOT_IN_LIST)
if len(user_info) is 1:
passengerTicketStrList.append(
'0,' + user_info[0]['passenger_type'] + "," + user_info[0][
"passenger_name"] + "," +
user_info[0]['passenger_id_type_code'] + "," + user_info[0]['passenger_id_no'] + "," +
user_info[0]['mobile_no'] + ',N')
oldPassengerStr.append(
user_info[0]['passenger_name'] + "," + user_info[0]['passenger_id_type_code'] + "," +
user_info[0]['passenger_id_no'] + "," + user_info[0]['passenger_type'] + '_')
else:
for i in xrange(len(user_info)):
passengerTicketStrList.append(
'0,' + user_info[i]['passenger_type'] + "," + user_info[i][
"passenger_name"] + "," + user_info[i]['passenger_id_type_code'] + "," + user_info[i][
'passenger_id_no'] + "," + user_info[i]['mobile_no'] + ',N_' + set_type)
oldPassengerStr.append(
user_info[i]['passenger_name'] + "," + user_info[i]['passenger_id_type_code'] + "," +
user_info[i]['passenger_id_no'] + "," + user_info[i]['passenger_type'] + '_')
return {
"passengerTicketStrList": set_type + "," + ",".join(passengerTicketStrList),
"oldPassengerStr": "".join(oldPassengerStr),
"code": ticket.SUCCESS_CODE,
"set_type": set_type,
"status": True,
}

102
inter/GetQueueCountAsync.py Normal file
View File

@ -0,0 +1,102 @@
# coding=utf-8
import time
from collections import OrderedDict
from config.TicketEnmu import ticket
class getQueueCountAsync:
"""
排队
"""
def __init__(self,
session,
train_no,
stationTrainCode,
fromStationTelecode,
toStationTelecode,
leftTicket,
set_type,
users,):
self.train_no = train_no
self.session = session
self.stationTrainCode = stationTrainCode
self.fromStationTelecode = fromStationTelecode
self.toStationTelecode = toStationTelecode
self.set_type = set_type
self.leftTicket = leftTicket
self.users = users
def data_par(self):
"""
- 字段说明
- train_date 时间
- train_no 列车编号,查询代码里面返回
- stationTrainCode 列车编号
- seatType 对应坐席
- fromStationTelecode 起始城市
- toStationTelecode 到达城市
- leftTicket 查询代码里面返回
- purpose_codes 学生还是成人
- _json_att 没啥卵用还是带上吧
:return:
"""
l_time = time.localtime(time.time())
new_train_date = time.strftime("%b %d %Y %H:%M:%S", l_time)
data = OrderedDict()
# data["train_date"] = "Fri " + str(new_train_date) + " GMT+0800 (CST)"
data["train_date"] = "Fri Jun 21 2018 18:23:54 GMT+0800 (CST)"
data["train_no"] = self.train_no
data["stationTrainCode"] = self.stationTrainCode
data["seatType"] = self.set_type
data["fromStationTelecode"] = self.fromStationTelecode
data["toStationTelecode"] = self.toStationTelecode
data["leftTicket"] = self.leftTicket
data["purpose_codes"] = "ADULT"
data["_json_att"] = ""
return data
def conversion_int(self, str):
return int(str)
def sendGetQueueCountAsync(self):
"""
请求排队接口
:return:
"""
urls = self.session.urls["getQueueCountAsync"]
data = self.data_par()
getQueueCountAsyncResult = self.session.httpClint.send(urls, data)
if getQueueCountAsyncResult.get("status", False) and getQueueCountAsyncResult.get("data", False):
if "status" in getQueueCountAsyncResult and getQueueCountAsyncResult["status"] is True:
if "countT" in getQueueCountAsyncResult["data"]:
ticket_data = getQueueCountAsyncResult["data"]["ticket"]
ticket_split = sum(map(self.conversion_int, ticket_data.split(","))) if ticket_data.find(
",") != -1 else ticket_data
countT = getQueueCountAsyncResult["data"]["countT"]
if int(countT) is 0:
if int(ticket_split) < self.users:
print(ticket.QUEUE_TICKET_SHORT)
return {"status": False, "is_black": False}
else:
print(ticket.QUEUE_TICKET_SUCCESS.format(ticket_split))
return {"status": True, "is_black": False}
else:
return {"status": False, "is_black": True}
else:
print(ticket.QUEUE_JOIN_BLACK.format(getQueueCountAsyncResult, self.train_no))
return {"status": False, "is_black": True, "train_no": self.train_no}
elif "messages" in getQueueCountAsyncResult and getQueueCountAsyncResult["messages"]:
print(ticket.QUEUE_WARNING_MSG.format(getQueueCountAsyncResult["messages"][0], self.train_no))
return {"status": False, "is_black": True, "train_no": self.train_no}
else:
if "validateMessages" in getQueueCountAsyncResult and getQueueCountAsyncResult["validateMessages"]:
print(str(getQueueCountAsyncResult["validateMessages"]))
return {"status": False, "is_black": False}
else:
return {"status": False, "is_black": False}
else:
return {"status": False, "is_black": False}

17
inter/LiftTicketInit.py Normal file
View File

@ -0,0 +1,17 @@
# coding=utf-8
class liftTicketInit:
def __init__(self, session):
self.session = session
def reqLiftTicketInit(self):
"""
请求抢票页面
:return:
"""
urls = self.session.urls["left_ticket_init"]
self.session.httpClint.send(urls)
return {
"status": True
}

119
inter/Query.py Normal file
View File

@ -0,0 +1,119 @@
# coding=utf-8
import copy
import datetime
import random
import time
from config.TicketEnmu import ticket
class query:
"""
查询接口
"""
def __init__(self, session, from_station, to_station, from_station_h, to_station_h, _station_seat, station_trains,
black_train_no, station_dates=None, ):
self.session = session
self.from_station = from_station
self.to_station = to_station
self.from_station_h = from_station_h
self.to_station_h = to_station_h
self.station_trains = station_trains
self._station_seat = _station_seat if isinstance(_station_seat, list) else list(_station_seat)
self.station_dates = station_dates if isinstance(station_dates, list) else list(station_dates)
self.ticket_black_list = dict()
self.black_train_no = black_train_no
def station_seat(self, index):
"""
获取车票对应坐席
:return:
"""
seat = {'商务座': 32,
'一等座': 31,
'二等座': 30,
'特等座': 25,
'软卧': 23,
'硬卧': 28,
'硬座': 29,
'无座': 26,
}
return seat[index]
def sendQuery(self):
"""
查询
:return:
"""
if self.black_train_no:
self.ticket_black_list[self.black_train_no] = datetime.datetime.now()
for station_date in self.station_dates:
select_url = copy.copy(self.session.urls["select_url"])
select_url["req_url"] = select_url["req_url"].format(
station_date, self.from_station, self.to_station)
station_ticket = self.session.httpClint.send(select_url)
value = station_ticket.get("data", "")
if not value:
print (u'{0}-{1} 车次坐席查询为空'.format(self.from_station, self.to_station))
else:
result = value.get('result', [])
if result:
for i in value['result']:
ticket_info = i.split('|')
if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订": # 筛选未在开始时间内的车次
for j in xrange(len(self._station_seat)):
is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))]
if is_ticket_pass != '' and is_ticket_pass != '' and ticket_info[
3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次
secretStr = ticket_info[0]
train_no = ticket_info[2]
query_from_station_name = ticket_info[6]
query_to_station_name = ticket_info[7]
train_location = ticket_info[15]
stationTrainCode = ticket_info[3]
train_date = station_date
leftTicket = ticket_info[12]
set_type = self._station_seat[j]
print (u'车次: {0} 始发车站: {1} 终点站: {2} {3}: {4}'.format(train_no,
self.from_station_h,
self.to_station_h,
self._station_seat[j].encode(
"utf8"),
ticket_info[self.station_seat(
self._station_seat[
j].encode("utf8"))]
))
if "train_no" in self.ticket_black_list and (
datetime.datetime.now() - self.ticket_black_list[
train_no]).seconds / 60 < int(ticket.TICKET_BLACK_LIST_TIME):
print(ticket.QUERY_IN_BLACK_LIST.format(train_no))
break
else:
print (ticket.QUERY_C)
# self.buy_ticket_time = datetime.datetime.now()
return {
"secretStr": secretStr,
"train_no": train_no,
"stationTrainCode": stationTrainCode,
"train_date": train_date,
"query_from_station_name": query_from_station_name,
"query_to_station_name": query_to_station_name,
# "buy_ticket_time": self.buy_ticket_time,
"set_type": set_type,
"leftTicket": leftTicket,
"train_location": train_location,
"code": ticket.SUCCESS_CODE,
"status": True,
}
else:
pass
else:
pass
else:
print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
return {"code": ticket.FAIL_CODE, "status": False}
if __name__ == "__main__":
q = query()

123
inter/QueryOrderWaitTime.py Normal file
View File

@ -0,0 +1,123 @@
# coding=utf-8
import copy
import time
from config.TicketEnmu import ticket
from config.emailConf import sendEmail
from myException.ticketIsExitsException import ticketIsExitsException
from myException.ticketNumOutException import ticketNumOutException
class queryOrderWaitTime:
"""
排队
"""
def __init__(self, session):
self.session = session
def sendQueryOrderWaitTime(self):
"""
排队获取订单等待信息,每隔3秒请求一次最高请求次数为20次
:return:
"""
num = 1
while True:
num += 1
if num > ticket.OUT_NUM:
print(ticket.WAIT_OUT_NUM)
order_id = self.queryMyOrderNoComplete() # 排队失败,自动取消排队订单
if order_id:
self.cancelNoCompleteMyOrder(order_id)
break
try:
queryOrderWaitTimeUrl = copy.deepcopy(self.session.urls["queryOrderWaitTimeUrl"])
queryOrderWaitTimeUrl["req_url"] = queryOrderWaitTimeUrl["req_url"].format(int(round(time.time() * 1000)))
queryOrderWaitTimeResult = self.session.httpClint.send(queryOrderWaitTimeUrl)
except ValueError:
queryOrderWaitTimeResult = {}
if queryOrderWaitTimeResult:
if queryOrderWaitTimeResult.get("status", False):
data = queryOrderWaitTimeResult.get("data", False)
if data and data.get("orderId", ""):
sendEmail(ticket.WAIT_ORDER_SUCCESS.format(
data.get("orderId", "")))
raise ticketIsExitsException(ticket.WAIT_ORDER_SUCCESS.format(
data.get("orderId")))
elif data.get("msg", False):
print data.get("msg", "")
break
elif data.get("waitTime", False):
print(ticket.WAIT_ORDER_CONTINUE.format(0 - data.get("waitTime", False)))
else:
pass
elif queryOrderWaitTimeResult.get("messages", False):
print(ticket.WAIT_ORDER_FAIL.format(queryOrderWaitTimeResult.get("messages", "")))
else:
print(ticket.WAIT_ORDER_NUM.format(num + 1))
else:
pass
time.sleep(2)
else:
print(ticketNumOutException(ticket.WAIT_ORDER_SUB_FAIL))
def queryMyOrderNoComplete(self):
"""
获取订单列表信息
:return:
"""
self.initNoComplete()
queryMyOrderNoCompleteUrl = self.session.urls["queryMyOrderNoCompleteUrl"]
data = {"_json_att": ""}
try:
queryMyOrderNoCompleteResult = self.session.httpClint.send(queryMyOrderNoCompleteUrl, data)
except ValueError:
queryMyOrderNoCompleteResult = {}
if queryMyOrderNoCompleteResult:
if queryMyOrderNoCompleteResult.get("data", False) and queryMyOrderNoCompleteResult["data"].get("orderDBList", False):
orderId = queryMyOrderNoCompleteResult["data"]["orderDBList"][0]["sequence_no"]
return orderId
elif queryMyOrderNoCompleteResult.get("data", False) and queryMyOrderNoCompleteResult["data"].get("orderCacheDTO", False):
if queryMyOrderNoCompleteResult["data"]["orderCacheDTO"].get("message", False):
print(queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
raise ticketNumOutException(
queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
else:
if queryMyOrderNoCompleteResult.get("message", False):
print queryMyOrderNoCompleteResult.get("message", False)
return False
else:
return False
else:
print(u"接口 {} 无响应".format(queryMyOrderNoCompleteUrl))
def initNoComplete(self):
"""
获取订单前需要进入订单列表页获取订单列表页session
:return:
"""
self.session.httpClint.set_cookies(acw_tc="AQAAAEnFJnekLwwAtGHjZZCr79B6dpXk", current_captcha_type="Z")
initNoCompleteUrl = self.session.urls["initNoCompleteUrl"]
data = {"_json_att": ""}
self.session.httpClint.send(initNoCompleteUrl, data)
def cancelNoCompleteMyOrder(self, sequence_no):
"""
取消订单
:param sequence_no: 订单编号
:return:
"""
cancelNoCompleteMyOrderUrl = self.session.urls["cancelNoCompleteMyOrder"]
cancelNoCompleteMyOrderData = {
"sequence_no": sequence_no,
"cancel_flag": "cancel_order",
"_json_att": ""
}
cancelNoCompleteMyOrderResult = self.session.httpClint.send(cancelNoCompleteMyOrderUrl,
cancelNoCompleteMyOrderData)
if cancelNoCompleteMyOrderResult.get("data", False) and cancelNoCompleteMyOrderResult["data"].get("existError", "N"):
print(ticket.CANCEL_ORDER_SUCCESS.format(sequence_no))
time.sleep(2)
return True
else:
print(ticket.CANCEL_ORDER_FAIL.format(sequence_no))

0
inter/__init__.py Normal file
View File

0
myException/PassengerUserException.py Normal file → Executable file
View File

0
myException/UserPasswordException.py Normal file → Executable file
View File

0
myException/__init__.py Normal file → Executable file
View File

0
myException/balanceException.py Normal file → Executable file
View File

0
myException/ticketConfigException.py Normal file → Executable file
View File

0
myException/ticketIsExitsException.py Normal file → Executable file
View File

0
myException/ticketNumOutException.py Normal file → Executable file
View File

0
myUrllib/__init__.py Normal file → Executable file
View File

98
myUrllib/httpUtils.py Normal file → Executable file
View File

@ -1,6 +1,8 @@
# -*- coding: utf8 -*-
import json
import socket
import urllib
from collections import OrderedDict
from time import sleep
import requests
@ -8,6 +10,51 @@ import requests
from config import logger
def _set_header_default():
header_dict = OrderedDict()
header_dict["Host"] = "kyfw.12306.cn"
header_dict["Connection"] = "keep-alive"
header_dict["Accept"] = "application/json, text/javascript, */*; q=0.01"
header_dict["Origin"] = "https://kyfw.12306.cn"
header_dict["X-Requested-With"] = "XMLHttpRequest"
header_dict[
"User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
header_dict["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"
header_dict["Referer"] = "https://kyfw.12306.cn/otn/leftTicket/init"
header_dict["Accept-Encoding"] = "gzip, deflate, br"
header_dict["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8"
return header_dict
def _set_header_j():
"""设置header"""
return {
"Content-Type": "application/json; charset=UTF-8",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Origin": "https://kyfw.12306.cn",
"Connection": "keep-alive",
}
def _set_header_x():
"""设置header"""
return {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Origin": "https://kyfw.12306.cn",
"Connection": "keep-alive",
}
class HTTPClient(object):
def __init__(self):
@ -20,7 +67,7 @@ class HTTPClient(object):
def initS(self):
self._s = requests.Session()
self._s.headers.update(self._set_header())
self._s.headers.update(_set_header_j())
return self
def set_cookies(self, **kwargs):
@ -46,27 +93,16 @@ class HTTPClient(object):
"""
self._s.cookies.set(key, None)
def _set_header(self):
"""设置header"""
return {
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"X-Requested-With": "application/json, text/javascript, */*; q=0.01",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5",
"Referer": "https://kyfw.12306.cn/otn/login/init",
"Accept": "*/*",
"Accept-Encoding": "br, gzip, deflate",
"Origin": "https://kyfw.12306.cn",
"Accept-Language": "zh-cn",
"Connection": "keep-alive",
}
def setHeaders(self, headers):
self._s.headers.update(headers)
return self
def resetHeaders(self):
def resetHeaders(self, header_type):
self._s.headers.clear()
self._s.headers.update(self._set_header())
if header_type == 1:
self._s.headers.update(_set_header_x())
else:
self._s.headers.update(_set_header_j())
def getHeadersHost(self):
return self._s.headers["Host"]
@ -101,31 +137,43 @@ class HTTPClient(object):
def send(self, urls, data=None, **kwargs):
"""send request to url.If response 200,return response, else return None."""
allow_redirects = False
is_logger = urls["is_logger"]
is_logger = urls.get("is_logger", False)
req_url = urls.get("req_url", "")
re_try = urls.get("re_try", 0)
s_time = urls.get("s_time", 0)
contentType = urls.get("Content-Type", 0)
error_data = {"code": 99999, "message": u"重试次数达到上限"}
self.setHeadersReferer(urls["Referer"])
if data:
method = "post"
self.setHeaders({"Content-Length": "{0}".format(len(data))})
else:
method = "get"
self.resetHeaders()
self.resetHeaders(contentType)
self.setHeadersReferer(urls["Referer"])
if is_logger:
logger.log(
u"url: {0}\n入参: {1}\n请求方式: {2}\n".format(urls["req_url"],data,method,))
u"url: {0}\n入参: {1}\n请求方式: {2}\n".format(req_url, data, method, ))
self.setHeadersHost(urls["Host"])
if self.cdn:
url_host = self.cdn
else:
url_host = urls["Host"]
for i in range(urls["re_try"]):
if contentType == 1:
# 普通from表单
self.resetHeaders(contentType)
if method == "post":
pass
data = urllib.urlencode(data)
elif contentType == 0:
self.resetHeaders(contentType)
for i in range(re_try):
try:
# sleep(urls["s_time"]) if "s_time" in urls else sleep(0.001)
sleep(urls.get("s_time", 0.001))
sleep(s_time)
requests.packages.urllib3.disable_warnings()
response = self._s.request(method=method,
timeout=2,
url="https://" + url_host + urls["req_url"],
url="https://" + url_host + req_url,
data=data,
allow_redirects=allow_redirects,
verify=False,
@ -135,7 +183,7 @@ class HTTPClient(object):
if is_logger:
logger.log(
u"出参:{0}".format(response.content))
return json.loads(response.content) if method == "post" else response.content
return json.loads(response.content) if urls["is_json"] else response.content
else:
logger.log(
u"url: {} 返回参数为空".format(urls["req_url"]))

0
myUrllib/myurllib2.py Normal file → Executable file
View File

0
requirements.txt Normal file → Executable file
View File

5
run.py Normal file → Executable file
View File

@ -1,10 +1,11 @@
# -*- coding=utf-8 -*-
from init import login, select_ticket_info
from init import login, select_ticket_info, SelectTicketInfoFast
def run():
# login.main()
select_ticket_info.select().main()
SelectTicketInfoFast.selectFast().main()
# select_ticket_info.select().main()
if __name__ == '__main__':

0
station_name.txt Normal file → Executable file
View File

BIN
tkcode Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 12 KiB

0
tmp/__init__.py Normal file → Executable file
View File

0
tmp/log/__init__.py Normal file → Executable file
View File

0
uml/uml.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB