mirror of https://github.com/testerSunshine/12306
parent
f86f7b9c33
commit
b88d541f93
|
@ -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}"
|
||||||
|
|
|
@ -41,11 +41,11 @@
|
||||||
|
|
||||||
set:
|
set:
|
||||||
station_dates:
|
station_dates:
|
||||||
- "2018-03-19"
|
- "2018-06-21"
|
||||||
# - "2018-02-21"
|
- "2018-06-22"
|
||||||
|
|
||||||
station_trains:
|
station_trains:
|
||||||
- "G4831"
|
- "G1321"
|
||||||
|
|
||||||
from_station: "上海"
|
from_station: "上海"
|
||||||
to_station: "长沙"
|
to_station: "长沙"
|
||||||
|
@ -60,7 +60,7 @@ set:
|
||||||
12306count:
|
12306count:
|
||||||
# - uesr: ""
|
# - uesr: ""
|
||||||
# - pwd: "apple1995"
|
# - pwd: "apple1995"
|
||||||
- uesr: "@qq.com"
|
- uesr: "931128603@qq.com"
|
||||||
- pwd: "QWERTY"
|
- pwd: "QWERTY"
|
||||||
|
|
||||||
select_refresh_interval: 1
|
select_refresh_interval: 1
|
||||||
|
|
|
@ -1,24 +1,27 @@
|
||||||
|
# coding=utf-8
|
||||||
import random
|
import random
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
urls = {
|
urls = {
|
||||||
"auth": {
|
"auth": { # 登录接口
|
||||||
"req_url": "/passport/web/auth/uamtk",
|
"req_url": "/passport/web/auth/uamtk",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
"Content-Type": 1,
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
"s_time": 0.1,
|
"s_time": 0.1,
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"login": {
|
"login": { # 登录接口
|
||||||
"req_url": "/passport/web/login",
|
"req_url": "/passport/web/login",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/login/init",
|
"Referer": "https://kyfw.12306.cn/otn/login/init",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
"Content-Type": 1,
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
"s_time": 0.1,
|
"s_time": 0.1,
|
||||||
|
@ -26,29 +29,44 @@ urls = {
|
||||||
"is_json": True,
|
"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_url": "/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{0}",
|
||||||
"req_type": "get",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/login/init",
|
"Referer": "https://kyfw.12306.cn/otn/login/init",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
"Content-Type": 1,
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
"s_time": 0.1,
|
"s_time": 0.1,
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": False,
|
"is_json": False,
|
||||||
},
|
},
|
||||||
"codeCheck": {
|
"codeCheck": { # 验证码校验
|
||||||
"req_url": "/passport/captcha/captcha-check",
|
"req_url": "/passport/captcha/captcha-check",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/login/init",
|
"Referer": "https://kyfw.12306.cn/otn/login/init",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
"Content-Type": 1,
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
"s_time": 0.1,
|
"s_time": 0.1,
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"loginInit": {
|
"loginInit": { # 登录页面
|
||||||
"req_url": "/otn/login/init",
|
"req_url": "/otn/login/init",
|
||||||
"req_type": "get",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/index/init",
|
"Referer": "https://kyfw.12306.cn/otn/index/init",
|
||||||
|
@ -59,7 +77,7 @@ urls = {
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": False,
|
"is_json": False,
|
||||||
},
|
},
|
||||||
"getUserInfo": {
|
"getUserInfo": { # 获取用户信息
|
||||||
"req_url": "/otn/index/initMy12306",
|
"req_url": "/otn/index/initMy12306",
|
||||||
"req_type": "get",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
||||||
|
@ -70,7 +88,7 @@ urls = {
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": False,
|
"is_json": False,
|
||||||
},
|
},
|
||||||
"userLogin": {
|
"userLogin": { # 用户登录
|
||||||
"req_url": "/otn/login/userLogin",
|
"req_url": "/otn/login/userLogin",
|
||||||
"req_type": "get",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
||||||
|
@ -81,18 +99,19 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"uamauthclient": {
|
"uamauthclient": { # 登录
|
||||||
"req_url": "/otn/uamauthclient",
|
"req_url": "/otn/uamauthclient",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
"Referer": "https://kyfw.12306.cn/otn/passport?redirect=/otn/login/userLogin",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
"Content-Type": 1,
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
"s_time": 0.1,
|
"s_time": 0.1,
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"initdc_url": {
|
"initdc_url": { # 生成订单页面
|
||||||
"req_url": "/otn/confirmPassenger/initDc",
|
"req_url": "/otn/confirmPassenger/initDc",
|
||||||
"req_type": "get",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
||||||
|
@ -103,7 +122,7 @@ urls = {
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": False,
|
"is_json": False,
|
||||||
},
|
},
|
||||||
"GetJS": {
|
"GetJS": { # 订单页面js
|
||||||
"req_url": "/otn/HttpZF/GetJS",
|
"req_url": "/otn/HttpZF/GetJS",
|
||||||
"req_type": "get",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -114,7 +133,7 @@ urls = {
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": False,
|
"is_json": False,
|
||||||
},
|
},
|
||||||
"odxmfwg": {
|
"odxmfwg": { # 订单页面js
|
||||||
"req_url": "/otn/dynamicJs/odxmfwg",
|
"req_url": "/otn/dynamicJs/odxmfwg",
|
||||||
"req_type": "get",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -125,7 +144,7 @@ urls = {
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": False,
|
"is_json": False,
|
||||||
},
|
},
|
||||||
"get_passengerDTOs": {
|
"get_passengerDTOs": { # 获取乘车人
|
||||||
"req_url": "/otn/confirmPassenger/getPassengerDTOs",
|
"req_url": "/otn/confirmPassenger/getPassengerDTOs",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -136,8 +155,8 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"select_url": {
|
"select_url": { # 查询余票
|
||||||
"req_url": "/otn/leftTicket/queryO?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT",
|
"req_url": "/otn/leftTicket/query?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
@ -147,7 +166,7 @@ urls = {
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"check_user_url": {
|
"check_user_url": { # 检查用户登录
|
||||||
"req_url": "/otn/login/checkUser",
|
"req_url": "/otn/login/checkUser",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
||||||
|
@ -158,7 +177,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"submit_station_url": {
|
"submit_station_url": { # 提交订单
|
||||||
"req_url": "/otn/leftTicket/submitOrderRequest",
|
"req_url": "/otn/leftTicket/submitOrderRequest",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
||||||
|
@ -169,7 +188,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"checkOrderInfoUrl": {
|
"checkOrderInfoUrl": { # 检查订单信息规范
|
||||||
"req_url": "/otn/confirmPassenger/checkOrderInfo",
|
"req_url": "/otn/confirmPassenger/checkOrderInfo",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -180,7 +199,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"getQueueCountUrl": {
|
"getQueueCountUrl": { # 剩余余票数
|
||||||
"req_url": "/otn/confirmPassenger/getQueueCount",
|
"req_url": "/otn/confirmPassenger/getQueueCount",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -191,7 +210,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"checkQueueOrderUrl": {
|
"checkQueueOrderUrl": { # 订单队列排队
|
||||||
"req_url": "/otn/confirmPassenger/confirmSingleForQueue",
|
"req_url": "/otn/confirmPassenger/confirmSingleForQueue",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -202,7 +221,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"checkRandCodeAnsyn": {
|
"checkRandCodeAnsyn": { # 暂时没用到
|
||||||
"req_url": "/otn/passcodeNew/checkRandCodeAnsyn",
|
"req_url": "/otn/passcodeNew/checkRandCodeAnsyn",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -213,7 +232,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"codeImgByOrder": {
|
"codeImgByOrder": { # 订单页面验证码
|
||||||
"req_url": "/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s" % random.random(),
|
"req_url": "/otn/passcodeNew/getPassCodeNew?module=passenger&rand=randp&%s" % random.random(),
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
|
@ -224,9 +243,9 @@ urls = {
|
||||||
"is_logger": False,
|
"is_logger": False,
|
||||||
"is_json": False,
|
"is_json": False,
|
||||||
},
|
},
|
||||||
"queryOrderWaitTimeUrl": {
|
"queryOrderWaitTimeUrl": { # 订单等待页面
|
||||||
"req_url": "/otn/confirmPassenger/queryOrderWaitTime",
|
"req_url": "/otn/confirmPassenger/queryOrderWaitTime?random={0}&tourFlag=dc&_json_att=",
|
||||||
"req_type": "post",
|
"req_type": "get",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
"Referer": "https://kyfw.12306.cn/otn/confirmPassenger/initDc",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
|
@ -235,7 +254,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"queryMyOrderNoCompleteUrl": {
|
"queryMyOrderNoCompleteUrl": { # 订单查询页面
|
||||||
"req_url": "/otn/queryOrder/queryMyOrderNoComplete",
|
"req_url": "/otn/queryOrder/queryMyOrderNoComplete",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
||||||
|
@ -246,7 +265,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"initNoCompleteUrl": {
|
"initNoCompleteUrl": { # 获取订单列表
|
||||||
"req_url": "/otn/queryOrder/initNoComplete",
|
"req_url": "/otn/queryOrder/initNoComplete",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
||||||
|
@ -257,7 +276,7 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"cancelNoCompleteMyOrder": {
|
"cancelNoCompleteMyOrder": { # 取消订单
|
||||||
"req_url": "/otn/queryOrder/cancelNoCompleteMyOrder",
|
"req_url": "/otn/queryOrder/cancelNoCompleteMyOrder",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
||||||
|
@ -268,32 +287,35 @@ urls = {
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"autoSubmitOrderRequest": {
|
"autoSubmitOrderRequest": { # 快速自动提交订单
|
||||||
"req_url": "/otn/confirmPassenger/autoSubmitOrderRequest",
|
"req_url": "/otn/confirmPassenger/autoSubmitOrderRequest",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
"Content-Type": 1,
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
"s_time": 0.1,
|
"s_time": 0.1,
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"getQueueCountAsync": {
|
"getQueueCountAsync": { # 快速获取订单数据
|
||||||
"req_url": "/otn/confirmPassenger/getQueueCountAsync",
|
"req_url": "/otn/confirmPassenger/getQueueCountAsync",
|
||||||
"req_type": "post",
|
"req_type": "post",
|
||||||
"Referer": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
|
||||||
"Host": "kyfw.12306.cn",
|
"Host": "kyfw.12306.cn",
|
||||||
|
"Content-Type": 1,
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
"s_time": 0.1,
|
"s_time": 0.1,
|
||||||
"is_logger": True,
|
"is_logger": True,
|
||||||
"is_json": True,
|
"is_json": True,
|
||||||
},
|
},
|
||||||
"confirmSingleForQueueAsys": {
|
"confirmSingleForQueueAsys": { # 快速订单排队
|
||||||
"req_url": "/otn/confirmPassenger/confirmSingleForQueueAsys",
|
"req_url": "/otn/confirmPassenger/confirmSingleForQueueAsys",
|
||||||
"req_type": "post",
|
"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",
|
"Host": "kyfw.12306.cn",
|
||||||
"re_try": 10,
|
"re_try": 10,
|
||||||
"re_time": 0.1,
|
"re_time": 0.1,
|
||||||
|
|
|
@ -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()
|
|
@ -216,10 +216,14 @@ class GoLogin:
|
||||||
login_num = 0
|
login_num = 0
|
||||||
while True:
|
while True:
|
||||||
self.cookietp()
|
self.cookietp()
|
||||||
self.httpClint.set_cookies(_jc_save_showIns="true",
|
# self.httpClint.set_cookies(_jc_save_showIns="true",
|
||||||
_jc_save_wfdc_flag="dc",
|
# _jc_save_wfdc_flag="dc",
|
||||||
_jc_save_fromDate=_get_yaml()["set"]["station_dates"][0],
|
# _jc_save_toDate="2018-06-06",
|
||||||
_jc_save_toDate=_get_yaml()["set"]["station_dates"][0])
|
# _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.urlConf["getCodeImg"]["req_url"] = self.urlConf["getCodeImg"]["req_url"].format(random.random())
|
||||||
self.readImg(self.urlConf["getCodeImg"])
|
self.readImg(self.urlConf["getCodeImg"])
|
||||||
self.randCode = self.getRandCode()
|
self.randCode = self.getRandCode()
|
||||||
|
|
|
@ -43,6 +43,7 @@ class select:
|
||||||
self.user_info = ""
|
self.user_info = ""
|
||||||
self.secretStr = ""
|
self.secretStr = ""
|
||||||
self.ticket_black_list = dict()
|
self.ticket_black_list = dict()
|
||||||
|
self.ticket_black_list_time = dict()
|
||||||
self.is_check_user = dict()
|
self.is_check_user = dict()
|
||||||
self.httpClint = HTTPClient()
|
self.httpClint = HTTPClient()
|
||||||
self.confUrl = urlConf.urls
|
self.confUrl = urlConf.urls
|
||||||
|
@ -204,7 +205,7 @@ class select:
|
||||||
'REPEAT_SUBMIT_TOKEN': self.token
|
'REPEAT_SUBMIT_TOKEN': self.token
|
||||||
}
|
}
|
||||||
jsonData = self.httpClint.send(get_passengerDTOs, get_data)
|
jsonData = self.httpClint.send(get_passengerDTOs, get_data)
|
||||||
if 'data' in jsonData and jsonData['data'] and 'normal_passengers' in jsonData['data'] and jsonData['data'][
|
if 'data' in jsonData and jsonData['data'] and 'l' in jsonData['data'] and jsonData['data'][
|
||||||
'normal_passengers']:
|
'normal_passengers']:
|
||||||
normal_passengers = jsonData['data']['normal_passengers']
|
normal_passengers = jsonData['data']['normal_passengers']
|
||||||
_normal_passenger = [normal_passengers[i] for i in range(len(normal_passengers))if normal_passengers[i]["passenger_name"] in self.ticke_peoples]
|
_normal_passenger = [normal_passengers[i] for i in range(len(normal_passengers))if normal_passengers[i]["passenger_name"] in self.ticke_peoples]
|
||||||
|
@ -337,7 +338,7 @@ class select:
|
||||||
"""
|
"""
|
||||||
获取getPassengerTicketStr 提交对应的代号码
|
获取getPassengerTicketStr 提交对应的代号码
|
||||||
:param str: 坐席
|
:param str: 坐席
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
passengerTicketStr = {
|
passengerTicketStr = {
|
||||||
'一等座': 'M',
|
'一等座': 'M',
|
||||||
|
@ -581,7 +582,7 @@ class select:
|
||||||
elif "waitTime"in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["waitTime"]:
|
elif "waitTime"in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["waitTime"]:
|
||||||
print(u"排队等待时间预计还剩 {0} ms".format(0-queryOrderWaitTimeResult["data"]["waitTime"]))
|
print(u"排队等待时间预计还剩 {0} ms".format(0-queryOrderWaitTimeResult["data"]["waitTime"]))
|
||||||
else:
|
else:
|
||||||
print ("正在等待中")
|
print (u"正在等待中")
|
||||||
elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
|
elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
|
||||||
print(u"排队等待失败: " + queryOrderWaitTimeResult["messages"])
|
print(u"排队等待失败: " + queryOrderWaitTimeResult["messages"])
|
||||||
else:
|
else:
|
||||||
|
@ -732,7 +733,8 @@ class select:
|
||||||
print u"正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 cdn轮询IP {4} 当前cdn总数{5} 总耗时{3}ms".format(num,
|
print u"正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 cdn轮询IP {4} 当前cdn总数{5} 总耗时{3}ms".format(num,
|
||||||
",".join(self.station_dates),
|
",".join(self.station_dates),
|
||||||
",".join(self.station_trains),
|
",".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))
|
len(self.cdn_list))
|
||||||
self.set_cdn()
|
self.set_cdn()
|
||||||
except PassengerUserException as e:
|
except PassengerUserException as e:
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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,
|
||||||
|
}
|
|
@ -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}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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()
|
|
@ -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))
|
|
@ -1,6 +1,8 @@
|
||||||
# -*- coding: utf8 -*-
|
# -*- coding: utf8 -*-
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
import urllib
|
||||||
|
from collections import OrderedDict
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
@ -8,6 +10,51 @@ import requests
|
||||||
from config import logger
|
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):
|
class HTTPClient(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -20,7 +67,7 @@ class HTTPClient(object):
|
||||||
|
|
||||||
def initS(self):
|
def initS(self):
|
||||||
self._s = requests.Session()
|
self._s = requests.Session()
|
||||||
self._s.headers.update(self._set_header())
|
self._s.headers.update(_set_header_j())
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def set_cookies(self, **kwargs):
|
def set_cookies(self, **kwargs):
|
||||||
|
@ -46,27 +93,16 @@ class HTTPClient(object):
|
||||||
"""
|
"""
|
||||||
self._s.cookies.set(key, None)
|
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):
|
def setHeaders(self, headers):
|
||||||
self._s.headers.update(headers)
|
self._s.headers.update(headers)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def resetHeaders(self):
|
def resetHeaders(self, header_type):
|
||||||
self._s.headers.clear()
|
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):
|
def getHeadersHost(self):
|
||||||
return self._s.headers["Host"]
|
return self._s.headers["Host"]
|
||||||
|
@ -101,31 +137,43 @@ class HTTPClient(object):
|
||||||
def send(self, urls, data=None, **kwargs):
|
def send(self, urls, data=None, **kwargs):
|
||||||
"""send request to url.If response 200,return response, else return None."""
|
"""send request to url.If response 200,return response, else return None."""
|
||||||
allow_redirects = False
|
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"重试次数达到上限"}
|
error_data = {"code": 99999, "message": u"重试次数达到上限"}
|
||||||
self.setHeadersReferer(urls["Referer"])
|
|
||||||
if data:
|
if data:
|
||||||
method = "post"
|
method = "post"
|
||||||
self.setHeaders({"Content-Length": "{0}".format(len(data))})
|
self.setHeaders({"Content-Length": "{0}".format(len(data))})
|
||||||
else:
|
else:
|
||||||
method = "get"
|
method = "get"
|
||||||
self.resetHeaders()
|
self.resetHeaders(contentType)
|
||||||
|
self.setHeadersReferer(urls["Referer"])
|
||||||
if is_logger:
|
if is_logger:
|
||||||
logger.log(
|
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"])
|
self.setHeadersHost(urls["Host"])
|
||||||
if self.cdn:
|
if self.cdn:
|
||||||
url_host = self.cdn
|
url_host = self.cdn
|
||||||
else:
|
else:
|
||||||
url_host = urls["Host"]
|
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:
|
try:
|
||||||
# sleep(urls["s_time"]) if "s_time" in urls else sleep(0.001)
|
# 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()
|
requests.packages.urllib3.disable_warnings()
|
||||||
response = self._s.request(method=method,
|
response = self._s.request(method=method,
|
||||||
timeout=2,
|
timeout=2,
|
||||||
url="https://" + url_host + urls["req_url"],
|
url="https://" + url_host + req_url,
|
||||||
data=data,
|
data=data,
|
||||||
allow_redirects=allow_redirects,
|
allow_redirects=allow_redirects,
|
||||||
verify=False,
|
verify=False,
|
||||||
|
@ -135,7 +183,7 @@ class HTTPClient(object):
|
||||||
if is_logger:
|
if is_logger:
|
||||||
logger.log(
|
logger.log(
|
||||||
u"出参:{0}".format(response.content))
|
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:
|
else:
|
||||||
logger.log(
|
logger.log(
|
||||||
u"url: {} 返回参数为空".format(urls["req_url"]))
|
u"url: {} 返回参数为空".format(urls["req_url"]))
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
# -*- coding=utf-8 -*-
|
# -*- coding=utf-8 -*-
|
||||||
from init import login, select_ticket_info
|
from init import login, select_ticket_info, SelectTicketInfoFast
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
# login.main()
|
# login.main()
|
||||||
select_ticket_info.select().main()
|
SelectTicketInfoFast.selectFast().main()
|
||||||
|
# select_ticket_info.select().main()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
Loading…
Reference in New Issue