Merge branch 'master' into dev
commit
b056211587
|
@ -1,3 +1,5 @@
|
||||||
*.html
|
*.html
|
||||||
*.pyc
|
*.pyc
|
||||||
*.yaml
|
*.yaml
|
||||||
|
*.log
|
||||||
|
idea/
|
||||||
|
|
22
README.md
22
README.md
|
@ -13,7 +13,10 @@
|
||||||
- 配置yaml文件的时候,需注意空格和遵循yaml语法格式,项目的yaml配置ex:
|
- 配置yaml文件的时候,需注意空格和遵循yaml语法格式,项目的yaml配置ex:
|
||||||
- ticket_config.yaml 配置说明
|
- ticket_config.yaml 配置说明
|
||||||
```
|
```
|
||||||
#station_date:出发日期,格式ex:2018-01-06
|
#station_date:出发日期改为多日期查询,格式ex:
|
||||||
|
- "2018-02-03"
|
||||||
|
- "2018-02-04"
|
||||||
|
- "2018-02-05"
|
||||||
#station_trains:过滤车次,格式ex:
|
#station_trains:过滤车次,格式ex:
|
||||||
# - "G1353"
|
# - "G1353"
|
||||||
# - "G1329"
|
# - "G1329"
|
||||||
|
@ -170,4 +173,21 @@
|
||||||
- 更新请求第三方库
|
- 更新请求第三方库
|
||||||
- 优化若干代码,小伙伴尽情的放肆起来
|
- 优化若干代码,小伙伴尽情的放肆起来
|
||||||
|
|
||||||
|
- 2018.1.21跟新
|
||||||
|
- 修复若干bug
|
||||||
|
- 合并dev
|
||||||
|
- 恢复之前因为12306改版引起的订票功能
|
||||||
|
- 增加派对失败自动取消订单功能
|
||||||
|
- 优化接口请求规范
|
||||||
|
- 增加多日期查询,请严格按照yaml格式添加 即可
|
||||||
|
- 注意:如果多日期查询的话,可能查询时间会比较长
|
||||||
|
- 增加如果排队时间超过一分钟,自动取消订单
|
||||||
|
|
||||||
|
- 2018.1.23更新
|
||||||
|
- 增加若快平台打码,yaml新增字段aotu_code_type,1=打码兔,2=若快 若快注册地址:http://www.ruokuai.com/client/index?6726
|
||||||
|
- 修改is_aotu_code字段为全部是否自动打码字段,也就是说字段为rue,则全部自动打码,为False全部手动打码,包括提交订单,注意centOs不可设置手动打码
|
||||||
|
- 修复bug
|
||||||
|
- 优化抢票功能
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
saleMinDelayDay = 0
|
||||||
|
saleMaxDelayDay = 59
|
||||||
|
saleStartTime = "06:00:00"
|
||||||
|
saleStopTime = "23:00:00"
|
||||||
|
rushRefreshMinTimeIntval = 2000
|
||||||
|
rushRefreshMaxTimeIntval = 3600000
|
||||||
|
rushRefreshTimeIntval = 100
|
||||||
|
|
||||||
|
RS_SUC = 0
|
||||||
|
RS_TIMEOUT = 1
|
||||||
|
RS_JSON_ERROR = 2
|
||||||
|
RS_OTHER_ERROR = 3
|
||||||
|
|
||||||
|
|
||||||
|
def getNowTimestamp():
|
||||||
|
return time.time()
|
||||||
|
|
||||||
|
|
||||||
|
def getMinimumDate():
|
||||||
|
return time.localtime(getNowTimestamp() + saleMinDelayDay * 24 * 3600)[:3]
|
||||||
|
|
||||||
|
|
||||||
|
def getMaximumDate():
|
||||||
|
return time.localtime(getNowTimestamp() + saleMaxDelayDay * 24 * 3600)[:3]
|
||||||
|
|
||||||
|
|
||||||
|
def getMinimumTime():
|
||||||
|
return [int(x) for x in saleStartTime.split(":")]
|
||||||
|
|
||||||
|
|
||||||
|
def getMaximumTime():
|
||||||
|
return [int(x) for x in saleStopTime.split(":")]
|
||||||
|
|
||||||
|
|
||||||
|
def decMakeDir(func):
|
||||||
|
def handleFunc(*args, **kwargs):
|
||||||
|
dirname = func(*args, **kwargs)
|
||||||
|
if not os.path.exists(dirname):
|
||||||
|
os.makedirs(dirname)
|
||||||
|
elif not os.path.isdir(dirname):
|
||||||
|
pass
|
||||||
|
|
||||||
|
return dirname
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
|
||||||
|
def getWorkDir():
|
||||||
|
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
|
@decMakeDir
|
||||||
|
def getTmpDir():
|
||||||
|
return os.path.join(getWorkDir(), "tmp")
|
||||||
|
|
||||||
|
|
||||||
|
@decMakeDir
|
||||||
|
def getLogDir():
|
||||||
|
return os.path.join(getTmpDir(), "log")
|
||||||
|
|
||||||
|
|
||||||
|
@decMakeDir
|
||||||
|
def getCacheDir():
|
||||||
|
return os.path.join(getTmpDir(), "cache")
|
||||||
|
|
||||||
|
|
||||||
|
@decMakeDir
|
||||||
|
def getVCodeDir():
|
||||||
|
return os.path.join(getTmpDir(), "vcode")
|
||||||
|
|
||||||
|
|
||||||
|
def getVCodeImageFile(imageName):
|
||||||
|
return os.path.join(getVCodeDir(), imageName + ".jpg")
|
||||||
|
|
||||||
|
|
||||||
|
def getCacheFile(cacheType):
|
||||||
|
return os.path.join(getCacheDir(), cacheType + ".cache")
|
|
@ -23,7 +23,7 @@ def sendEmail(msg):
|
||||||
host = email_conf["email_conf"]["host"]
|
host = email_conf["email_conf"]["host"]
|
||||||
s = "{0}".format(msg)
|
s = "{0}".format(msg)
|
||||||
|
|
||||||
msg = MIMEText(s, 'text', 'utf-8') # 中文需参数‘utf-8’,单字节字符不需要
|
msg = MIMEText(s, 'plain', 'utf-8') # 中文需参数‘utf-8’,单字节字符不需要
|
||||||
msg['Subject'] = Header(subject, 'utf-8')
|
msg['Subject'] = Header(subject, 'utf-8')
|
||||||
msg['From'] = sender
|
msg['From'] = sender
|
||||||
msg['To'] = receiver
|
msg['To'] = receiver
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#coding: utf-8
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from config import configCommon
|
||||||
|
|
||||||
|
logger = None
|
||||||
|
loggerHandler = None
|
||||||
|
dateStr = '' #默认拥有日期后缀
|
||||||
|
suffix = '' #除了日期外的后缀
|
||||||
|
|
||||||
|
def setSuffix(s):
|
||||||
|
global suffix
|
||||||
|
suffix = s
|
||||||
|
|
||||||
|
def getTodayDateStr():
|
||||||
|
return time.strftime("%Y-%m-%d", time.localtime(configCommon.getNowTimestamp()))
|
||||||
|
|
||||||
|
def setDateStr(s):
|
||||||
|
global dateStr
|
||||||
|
dateStr = s
|
||||||
|
|
||||||
|
def isAnotherDay(s):
|
||||||
|
global dateStr
|
||||||
|
return dateStr != s
|
||||||
|
|
||||||
|
def getLogFile():
|
||||||
|
global dateStr, suffix
|
||||||
|
rtn = os.path.join(configCommon.getLogDir(), dateStr)
|
||||||
|
if suffix:
|
||||||
|
rtn += "_" + suffix
|
||||||
|
return rtn + ".log"
|
||||||
|
|
||||||
|
def log(msg, func = "info"):
|
||||||
|
global logger
|
||||||
|
if not logger:
|
||||||
|
logger = logging.getLogger()
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
todayStr = getTodayDateStr()
|
||||||
|
if isAnotherDay(todayStr):
|
||||||
|
setDateStr(todayStr)
|
||||||
|
logger.removeHandler(loggerHandler)
|
||||||
|
|
||||||
|
fh = logging.FileHandler(getLogFile())
|
||||||
|
fm = logging.Formatter(u'[%(asctime)s][%(levelname)8s] --- %(message)s (%(filename)s:%(lineno)s)')
|
||||||
|
fh.setFormatter(fm)
|
||||||
|
|
||||||
|
logger.addHandler(fh)
|
||||||
|
|
||||||
|
levels = {
|
||||||
|
"debug": logger.debug,
|
||||||
|
"info": logger.info,
|
||||||
|
"warning": logger.warning,
|
||||||
|
"error": logger.error,
|
||||||
|
"critical": logger.critical
|
||||||
|
}
|
||||||
|
|
||||||
|
levels[func](msg)
|
|
@ -1,6 +1,5 @@
|
||||||
# -*- coding: utf8 -*-
|
# -*- coding: utf8 -*-
|
||||||
__author__ = 'MR.wen'
|
__author__ = 'MR.wen'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
import PyQt5
|
import PyQt5
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#ticke_peoples: 乘客
|
#ticke_peoples: 乘客
|
||||||
#damatu:打码兔账号,用于自动登录
|
#damatu:打码兔账号,用于自动登录
|
||||||
#is_aotu_code是否自动打码,如果选择Ture,则调用打码兔打码,默认不使用打码兔
|
#is_aotu_code是否自动打码,如果选择Ture,则调用打码兔打码,默认不使用打码兔
|
||||||
|
#aotu_code_type 1为打码兔,2为若快
|
||||||
#is_email: 是否需要邮件通知 ex: True or False 切记,邮箱加完一定到config目录下测试emailConf功能是否正常
|
#is_email: 是否需要邮件通知 ex: True or False 切记,邮箱加完一定到config目录下测试emailConf功能是否正常
|
||||||
|
|
||||||
#邮箱配置 列举163
|
#邮箱配置 列举163
|
||||||
|
@ -39,9 +40,22 @@
|
||||||
|
|
||||||
|
|
||||||
set:
|
set:
|
||||||
station_date: "2018-02-12"
|
station_dates:
|
||||||
|
# - "2018-01-27"
|
||||||
|
# - "2018-01-28"
|
||||||
|
- "2018-02-09"
|
||||||
|
- "2018-02-10"
|
||||||
|
# - "2018-02-09"
|
||||||
station_trains:
|
station_trains:
|
||||||
|
- "G4741"
|
||||||
|
- "G2365"
|
||||||
|
- "G1371"
|
||||||
|
- "G1337"
|
||||||
- "G1377"
|
- "G1377"
|
||||||
|
- "G1329"
|
||||||
|
# - "G1302"
|
||||||
|
# - "G1372"
|
||||||
|
# - "G1326"
|
||||||
# - "K4300"
|
# - "K4300"
|
||||||
# - "K5226"
|
# - "K5226"
|
||||||
# - "K7772"
|
# - "K7772"
|
||||||
|
@ -51,35 +65,36 @@ set:
|
||||||
# - "G1373"
|
# - "G1373"
|
||||||
# - "G1363"
|
# - "G1363"
|
||||||
# - "G4933"
|
# - "G4933"
|
||||||
from_station: "昆山"
|
from_station: "上海"
|
||||||
to_station: "长沙"
|
to_station: "邵阳"
|
||||||
set_type:
|
set_type:
|
||||||
- "二等座"
|
- "二等座"
|
||||||
is_more_ticket: True
|
is_more_ticket: True
|
||||||
ticke_peoples:
|
ticke_peoples:
|
||||||
- "宋倩倩"
|
- "文贤平"
|
||||||
# - "彭淑杰"
|
# - "彭淑杰"
|
||||||
12306count:
|
12306count:
|
||||||
# - uesr: ""
|
# - uesr: ""
|
||||||
# - pwd: "apple1995"
|
# - pwd: "apple1995"
|
||||||
- uesr: ""
|
- uesr: "931128603@qq.com"
|
||||||
- pwd: "songyu1995"
|
- pwd: "QWERTY"
|
||||||
|
|
||||||
select_refresh_interval: 0.1
|
select_refresh_interval: 0.5
|
||||||
expect_refresh_interval: 0.3
|
expect_refresh_interval: 0.1
|
||||||
ticket_black_list_time: 3
|
ticket_black_list_time: 3
|
||||||
is_aotu_code: False
|
is_aotu_code: True
|
||||||
|
aotu_code_type: 2
|
||||||
#enable_proxy: False
|
#enable_proxy: False
|
||||||
|
|
||||||
damatu:
|
damatu:
|
||||||
uesr: ""
|
uesr: "931128603"
|
||||||
pwd: "wen1995"
|
pwd: "qazWSX1995"
|
||||||
|
|
||||||
email_conf:
|
email_conf:
|
||||||
is_email: False
|
is_email: True
|
||||||
email: "@qq.com "
|
email: "931128603@qq.com "
|
||||||
notice_email_list: "@qq.com"
|
notice_email_list: "61995120@qq.com"
|
||||||
username: ""
|
username: "931128603"
|
||||||
password: "xwopwxbkupbqbfgb"
|
password: "xwopwxbkupbqbfgb"
|
||||||
host: "smtp.qq.com"
|
host: "smtp.qq.com"
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,11 @@ urls = {
|
||||||
"initNoCompleteUrl": {
|
"initNoCompleteUrl": {
|
||||||
"req_url": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
"req_url": "https://kyfw.12306.cn/otn/queryOrder/initNoComplete",
|
||||||
"req_type": "post"
|
"req_type": "post"
|
||||||
|
},
|
||||||
|
"cancelNoCompleteMyOrder": {
|
||||||
|
"req_url": "https://kyfw.12306.cn/otn/queryOrder/cancelNoCompleteMyOrder",
|
||||||
|
"req_type": "post"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ class DamatuApi():
|
||||||
KEY = 'ca9507e17e8d5ddf7c57cd18d8d33010'
|
KEY = 'ca9507e17e8d5ddf7c57cd18d8d33010'
|
||||||
HOST = 'http://api.dama2.com:7766/app/'
|
HOST = 'http://api.dama2.com:7766/app/'
|
||||||
|
|
||||||
def __init__(self, username, password, file_path):
|
def __init__(self, username, password, file_path=None):
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
self.password = password
|
||||||
self.file_path = file_path
|
self.file_path = file_path
|
||||||
|
@ -108,13 +108,10 @@ class DamatuApi():
|
||||||
return jres['ret']
|
return jres['ret']
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
balance = self.getBalance()
|
result = self.decode(287)
|
||||||
if int(balance) > 40:
|
img_code = result.replace('|', ',') if not isinstance(result, int) else ""
|
||||||
result = self.decode(287)
|
print("验证码识别坐标为{0}".format(img_code))
|
||||||
img_code = result.replace('|', ',') if not isinstance(result, int) else ""
|
return img_code
|
||||||
return img_code
|
|
||||||
else:
|
|
||||||
raise balanceException('余额不足,当前余额为: {}'.format(balance))
|
|
||||||
|
|
||||||
# # 调用类型实例:
|
# # 调用类型实例:
|
||||||
# # 1.实例化类型 参数是打码兔用户账号和密码
|
# # 1.实例化类型 参数是打码兔用户账号和密码
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
# coding:utf-8
|
||||||
|
import requests
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
|
|
||||||
|
class RClient(object):
|
||||||
|
|
||||||
|
def __init__(self, username, password):
|
||||||
|
self.username = username
|
||||||
|
self.password = md5(password).hexdigest()
|
||||||
|
self.soft_id = '96061'
|
||||||
|
self.soft_key = '6facb9da7bb645ad9c4a229464b2cf89'
|
||||||
|
self.base_params = {
|
||||||
|
'username': self.username,
|
||||||
|
'password': self.password,
|
||||||
|
'softid': self.soft_id,
|
||||||
|
'softkey': self.soft_key,
|
||||||
|
}
|
||||||
|
self.headers = {
|
||||||
|
'Connection': 'Keep-Alive',
|
||||||
|
'Expect': '100-continue',
|
||||||
|
'User-Agent': 'ben',
|
||||||
|
}
|
||||||
|
|
||||||
|
def rk_create(self, im, im_type, timeout=60):
|
||||||
|
"""
|
||||||
|
im: 图片字节
|
||||||
|
im_type: 题目类型
|
||||||
|
"""
|
||||||
|
params = {
|
||||||
|
'typeid': im_type,
|
||||||
|
'timeout': timeout,
|
||||||
|
}
|
||||||
|
params.update(self.base_params)
|
||||||
|
files = {'image': ('a.jpg', im)}
|
||||||
|
r = requests.post('http://api.ruokuai.com/create.json', data=params, files=files, headers=self.headers)
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
def rk_report_error(self, im_id):
|
||||||
|
"""
|
||||||
|
im_id:报错题目的ID
|
||||||
|
"""
|
||||||
|
params = {
|
||||||
|
'id': im_id,
|
||||||
|
}
|
||||||
|
params.update(self.base_params)
|
||||||
|
r = requests.post('http://api.ruokuai.com/reporterror.json', data=params, headers=self.headers)
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
rc = RClient('931128603', 'qazWSX1995',)
|
||||||
|
im = open('tkcode', 'rb').read()
|
||||||
|
print rc.rk_create(im, 6113)
|
||||||
|
|
|
@ -9,15 +9,19 @@ from time import sleep
|
||||||
from config.ticketConf import _get_yaml
|
from config.ticketConf import _get_yaml
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from damatuCode.damatuWeb import DamatuApi
|
from damatuCode.damatuWeb import DamatuApi
|
||||||
|
from damatuCode.ruokuai import RClient
|
||||||
from myException.UserPasswordException import UserPasswordException
|
from myException.UserPasswordException import UserPasswordException
|
||||||
|
from myException.balanceException import balanceException
|
||||||
from myUrllib import myurllib2
|
from myUrllib import myurllib2
|
||||||
|
|
||||||
|
|
||||||
class GoLogin:
|
class GoLogin:
|
||||||
def __init__(self, httpClint, urlConf):
|
def __init__(self, httpClint, urlConf, is_aotu_code, aotu_code_type):
|
||||||
self.httpClint = httpClint
|
self.httpClint = httpClint
|
||||||
self.randCode = ""
|
self.randCode = ""
|
||||||
self.urlConf = urlConf
|
self.urlConf = urlConf
|
||||||
|
self.is_aotu_code = is_aotu_code
|
||||||
|
self.aotu_code_type = aotu_code_type
|
||||||
|
|
||||||
def cookietp(self):
|
def cookietp(self):
|
||||||
print("正在获取cookie")
|
print("正在获取cookie")
|
||||||
|
@ -28,7 +32,7 @@ class GoLogin:
|
||||||
# for index, c in enumerate(myurllib2.cookiejar):
|
# for index, c in enumerate(myurllib2.cookiejar):
|
||||||
# stoidinput(c)
|
# stoidinput(c)
|
||||||
|
|
||||||
def readImg(self):
|
def readImg(self, code_url):
|
||||||
"""
|
"""
|
||||||
增加手动打码,只是登录接口,完全不用担心提交订单效率
|
增加手动打码,只是登录接口,完全不用担心提交订单效率
|
||||||
思路
|
思路
|
||||||
|
@ -38,28 +42,39 @@ class GoLogin:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
print ("下载验证码...")
|
print ("下载验证码...")
|
||||||
codeimgUrl = self.urlConf["getCodeImg"]["req_url"]
|
codeimgUrl = code_url
|
||||||
img_path = './tkcode'
|
img_path = './tkcode'
|
||||||
result = self.httpClint.send(codeimgUrl)
|
result = self.httpClint.send(codeimgUrl, is_logger=False)
|
||||||
try:
|
try:
|
||||||
open(img_path, 'wb').write(result)
|
open(img_path, 'wb').write(result)
|
||||||
if _get_yaml()["is_aotu_code"]:
|
if self.is_aotu_code:
|
||||||
self.randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main()
|
if self.aotu_code_type == 1:
|
||||||
|
return DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"], img_path).main()
|
||||||
|
elif self.aotu_code_type == 2:
|
||||||
|
rc = RClient(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"])
|
||||||
|
im = open('./tkcode', 'rb').read()
|
||||||
|
Result = rc.rk_create(im, 6113)
|
||||||
|
if "Result" in Result:
|
||||||
|
return self.codexy(Ofset=",".join(list(Result["Result"])), is_raw_input=False)
|
||||||
|
else:
|
||||||
|
if "Error" in Result and Result["Error"]:
|
||||||
|
print Result["Error"]
|
||||||
|
return ""
|
||||||
else:
|
else:
|
||||||
img = Image.open('./tkcode')
|
img = Image.open('./tkcode')
|
||||||
img.show()
|
img.show()
|
||||||
self.codexy()
|
return self.codexy()
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
print (e)
|
print (e)
|
||||||
pass
|
return ""
|
||||||
|
|
||||||
def codexy(self):
|
def codexy(self, Ofset=None, is_raw_input=True):
|
||||||
"""
|
"""
|
||||||
获取验证码
|
获取验证码
|
||||||
:return: str
|
:return: str
|
||||||
"""
|
"""
|
||||||
|
if is_raw_input:
|
||||||
Ofset = raw_input("请输入验证码: ")
|
Ofset = raw_input("请输入验证码: ")
|
||||||
select = Ofset.split(',')
|
select = Ofset.split(',')
|
||||||
post = []
|
post = []
|
||||||
offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题
|
offsetsX = 0 # 选择的答案的left值,通过浏览器点击8个小图的中点得到的,这样基本没问题
|
||||||
|
@ -93,7 +108,9 @@ class GoLogin:
|
||||||
pass
|
pass
|
||||||
post.append(offsetsX)
|
post.append(offsetsX)
|
||||||
post.append(offsetsY)
|
post.append(offsetsY)
|
||||||
self.randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '')
|
randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '')
|
||||||
|
print("验证码识别坐标为{0}".format(randCode))
|
||||||
|
return randCode
|
||||||
|
|
||||||
def auth(self):
|
def auth(self):
|
||||||
"""认证"""
|
"""认证"""
|
||||||
|
@ -149,7 +166,7 @@ class GoLogin:
|
||||||
if messages.find("密码输入错误") is not -1:
|
if messages.find("密码输入错误") is not -1:
|
||||||
raise UserPasswordException("{0}".format(messages))
|
raise UserPasswordException("{0}".format(messages))
|
||||||
else:
|
else:
|
||||||
print ("登录失败: {0}".format("".join(tresult)))
|
print ("登录失败: {0}".format(messages))
|
||||||
print ("尝试重新登陆")
|
print ("尝试重新登陆")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -166,11 +183,16 @@ class GoLogin:
|
||||||
uamauthclientUrl = self.urlConf["uamauthclient"]["req_url"]
|
uamauthclientUrl = self.urlConf["uamauthclient"]["req_url"]
|
||||||
data = {"tk": uamtk}
|
data = {"tk": uamtk}
|
||||||
uamauthclientResult = self.httpClint.send(uamauthclientUrl, data)
|
uamauthclientResult = self.httpClint.send(uamauthclientUrl, data)
|
||||||
if "result_code" in uamauthclientResult and uamauthclientResult["result_code"] == 0:
|
if uamauthclientResult:
|
||||||
print("欢迎 {} 登录".format(uamauthclientResult["username"]))
|
if "result_code" in uamauthclientResult and uamauthclientResult["result_code"] == 0:
|
||||||
return True
|
print("欢迎 {} 登录".format(uamauthclientResult["username"]))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
else:
|
else:
|
||||||
return False
|
self.httpClint.send(uamauthclientUrl, data)
|
||||||
|
url = self.urlConf["getUserInfo"]["req_url"]
|
||||||
|
self.httpClint.send(url)
|
||||||
|
|
||||||
def go_login(self):
|
def go_login(self):
|
||||||
"""
|
"""
|
||||||
|
@ -179,19 +201,25 @@ class GoLogin:
|
||||||
:param passwd: 密码
|
:param passwd: 密码
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
if self.is_aotu_code and self.aotu_code_type == 1:
|
||||||
|
balance = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"]).getBalance()
|
||||||
|
if int(balance) < 40:
|
||||||
|
raise balanceException('余额不足,当前余额为: {}'.format(balance))
|
||||||
user, passwd = _get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"]
|
user, passwd = _get_yaml()["set"]["12306count"][0]["uesr"], _get_yaml()["set"]["12306count"][1]["pwd"]
|
||||||
|
if not user or not passwd:
|
||||||
|
raise UserPasswordException("温馨提示: 用户名或者密码为空,请仔细检查")
|
||||||
login_num = 0
|
login_num = 0
|
||||||
while True:
|
while True:
|
||||||
self.cookietp()
|
self.cookietp()
|
||||||
self.httpClint.set_cookies(_jc_save_wfdc_flag="dc", _jc_save_fromStation="%u4E0A%u6D77%u8679%u6865%2CAOH", _jc_save_toStation="%u5170%u5DDE%u897F%2CLAJ", _jc_save_fromDate="2018-02-14", _jc_save_toDate="2018-01-16", RAIL_DEVICEID="EN_3_EGSe2GWGHXJeCkFQ52kHvNCrNlkz9n1GOqqQ1wR0i98WsD8Gj-a3YHZ-XYKeESWgCiJyyucgSwkFOzVHhHqfpidLPcm2vK9n83uzOPuShO3Pl4lCydAtQu4BdFqz-RVmiduNFixrcrN_Ny43135JiEtqLaI")
|
self.httpClint.set_cookies(_jc_save_wfdc_flag="dc", _jc_save_fromStation="%u4E0A%u6D77%u8679%u6865%2CAOH", _jc_save_toStation="%u5170%u5DDE%u897F%2CLAJ", _jc_save_fromDate="2018-02-14", _jc_save_toDate="2018-01-16", RAIL_DEVICEID="EN_3_EGSe2GWGHXJeCkFQ52kHvNCrNlkz9n1GOqqQ1wR0i98WsD8Gj-a3YHZ-XYKeESWgCiJyyucgSwkFOzVHhHqfpidLPcm2vK9n83uzOPuShO3Pl4lCydAtQu4BdFqz-RVmiduNFixrcrN_Ny43135JiEtqLaI")
|
||||||
self.readImg()
|
self.randCode = self.readImg(self.urlConf["getCodeImg"]["req_url"])
|
||||||
login_num += 1
|
login_num += 1
|
||||||
self.auth()
|
self.auth()
|
||||||
if self.codeCheck():
|
if self.codeCheck():
|
||||||
uamtk = self.baseLogin(user, passwd)
|
uamtk = self.baseLogin(user, passwd)
|
||||||
if uamtk:
|
if uamtk:
|
||||||
if self.getUserName(uamtk):
|
self.getUserName(uamtk)
|
||||||
break
|
break
|
||||||
|
|
||||||
def logout(self):
|
def logout(self):
|
||||||
url = 'https://kyfw.12306.cn/otn/login/loginOut'
|
url = 'https://kyfw.12306.cn/otn/login/loginOut'
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
# -*- coding=utf-8 -*-
|
# -*- coding=utf-8 -*-
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
import random
|
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import urllib
|
import urllib
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from config import urlConf
|
from config import urlConf
|
||||||
from init import login
|
from init import login
|
||||||
|
|
||||||
from config.emailConf import sendEmail
|
from config.emailConf import sendEmail
|
||||||
from config.ticketConf import _get_yaml
|
from config.ticketConf import _get_yaml
|
||||||
from damatuCode.damatuWeb import DamatuApi
|
from damatuCode.damatuWeb import DamatuApi
|
||||||
|
@ -29,7 +26,9 @@ sys.setdefaultencoding('utf-8')
|
||||||
|
|
||||||
class select:
|
class select:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.from_station, self.to_station, self.station_date, self._station_seat, self.is_more_ticket, self.ticke_peoples, self.select_refresh_interval, self.station_trains, self.expect_refresh_interval, self.ticket_black_list_time = self.get_ticket_info()
|
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.expect_refresh_interval, 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.order_request_params = {} # 订单提交时的参数
|
self.order_request_params = {} # 订单提交时的参数
|
||||||
self.ticketInfoForPassengerForm = {} # 初始化当前页面参数
|
self.ticketInfoForPassengerForm = {} # 初始化当前页面参数
|
||||||
self.current_seats = {} # 席别信息
|
self.current_seats = {} # 席别信息
|
||||||
|
@ -41,6 +40,7 @@ class select:
|
||||||
self.is_check_user = dict()
|
self.is_check_user = dict()
|
||||||
self.httpClint = HTTPClient()
|
self.httpClint = HTTPClient()
|
||||||
self.confUrl = urlConf.urls
|
self.confUrl = urlConf.urls
|
||||||
|
self.login = GoLogin(self.httpClint, self.confUrl, self.is_aotu_code, self.aotu_code_type)
|
||||||
|
|
||||||
def get_ticket_info(self):
|
def get_ticket_info(self):
|
||||||
"""
|
"""
|
||||||
|
@ -50,7 +50,7 @@ class select:
|
||||||
ticket_info_config = _get_yaml()
|
ticket_info_config = _get_yaml()
|
||||||
from_station = ticket_info_config["set"]["from_station"].encode("utf8")
|
from_station = ticket_info_config["set"]["from_station"].encode("utf8")
|
||||||
to_station = ticket_info_config["set"]["to_station"].encode("utf8")
|
to_station = ticket_info_config["set"]["to_station"].encode("utf8")
|
||||||
station_date = ticket_info_config["set"]["station_date"].encode("utf8")
|
station_dates = ticket_info_config["set"]["station_dates"]
|
||||||
set_type = ticket_info_config["set"]["set_type"]
|
set_type = ticket_info_config["set"]["set_type"]
|
||||||
is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
|
is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
|
||||||
ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
|
ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
|
||||||
|
@ -63,7 +63,7 @@ class select:
|
||||||
(
|
(
|
||||||
from_station,
|
from_station,
|
||||||
to_station,
|
to_station,
|
||||||
station_date,
|
station_dates,
|
||||||
",".join(set_type),
|
",".join(set_type),
|
||||||
is_more_ticket,
|
is_more_ticket,
|
||||||
",".join(ticke_peoples),
|
",".join(ticke_peoples),
|
||||||
|
@ -73,7 +73,7 @@ class select:
|
||||||
ticket_black_list_time,
|
ticket_black_list_time,
|
||||||
)
|
)
|
||||||
print "*"*20
|
print "*"*20
|
||||||
return from_station, to_station, station_date, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, expect_refresh_interval, ticket_black_list_time
|
return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, select_refresh_interval, station_trains, expect_refresh_interval, ticket_black_list_time
|
||||||
|
|
||||||
def get_order_request_params(self):
|
def get_order_request_params(self):
|
||||||
return self.order_request_params
|
return self.order_request_params
|
||||||
|
@ -141,7 +141,7 @@ class select:
|
||||||
获取提交车票请求token
|
获取提交车票请求token
|
||||||
:return: token
|
:return: token
|
||||||
"""
|
"""
|
||||||
initdc_url = self.confUrl["initdc_url"]["req+url"]
|
initdc_url = self.confUrl["initdc_url"]["req_url"]
|
||||||
initdc_result = self.httpClint.send(initdc_url)
|
initdc_result = self.httpClint.send(initdc_url)
|
||||||
token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'")
|
token_name = re.compile(r"var globalRepeatSubmitToken = '(\S+)'")
|
||||||
ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?')
|
ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?')
|
||||||
|
@ -173,7 +173,7 @@ class select:
|
||||||
'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]
|
||||||
return _normal_passenger if _normal_passenger else normal_passengers[0] # 如果配置乘车人没有在账号,则默认返回第一个用户
|
return _normal_passenger if _normal_passenger else [normal_passengers[0]] # 如果配置乘车人没有在账号,则默认返回第一个用户
|
||||||
else:
|
else:
|
||||||
if 'data' in jsonData and 'exMsg' in jsonData['data'] and jsonData['data']['exMsg']:
|
if 'data' in jsonData and 'exMsg' in jsonData['data'] and jsonData['data']['exMsg']:
|
||||||
print(jsonData['data']['exMsg'])
|
print(jsonData['data']['exMsg'])
|
||||||
|
@ -185,9 +185,9 @@ class select:
|
||||||
|
|
||||||
def submitOrderRequestFunc(self, from_station, to_station, station_date=None):
|
def submitOrderRequestFunc(self, from_station, to_station, station_date=None):
|
||||||
select_url = self.confUrl["select_url"]["req_url"].format(
|
select_url = self.confUrl["select_url"]["req_url"].format(
|
||||||
self.station_date if station_date is None else station_date, from_station, to_station)
|
station_date, from_station, to_station)
|
||||||
station_ticket = self.httpClint.send(select_url)
|
station_ticket = self.httpClint.send(select_url, is_logger=False)
|
||||||
return station_ticket
|
return json.loads(station_ticket)
|
||||||
|
|
||||||
def submitOrderRequestImplement(self, from_station, to_station,):
|
def submitOrderRequestImplement(self, from_station, to_station,):
|
||||||
"""
|
"""
|
||||||
|
@ -204,44 +204,45 @@ class select:
|
||||||
} 参照station_seat()方法
|
} 参照station_seat()方法
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
station_ticket = self.submitOrderRequestFunc(from_station, to_station)
|
station_tickets = [self.submitOrderRequestFunc(from_station, to_station, station_date) for station_date in self.station_dates]
|
||||||
value = station_ticket['data']
|
for station_ticket in station_tickets:
|
||||||
if not value:
|
value = station_ticket['data']
|
||||||
print ('{0}-{1} 车次坐席查询为空...'.format(self.from_station, self.to_station))
|
if not value:
|
||||||
else:
|
print ('{0}-{1} 车次坐席查询为空...'.format(self.from_station, self.to_station))
|
||||||
if value['result']:
|
|
||||||
for i in value['result']:
|
|
||||||
ticket_info = i.split('|')
|
|
||||||
if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订": # 筛选未在开始时间内的车次
|
|
||||||
for j in range(len(self._station_seat)):
|
|
||||||
is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))]
|
|
||||||
# print self._station_seat[j]
|
|
||||||
if is_ticket_pass != '' and is_ticket_pass != '无' and ticket_info[3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次
|
|
||||||
# tiket_values = [k for k in value['map'].values()]
|
|
||||||
self.secretStr = ticket_info[0]
|
|
||||||
train_no = ticket_info[3]
|
|
||||||
print ('车次: ' + train_no + ' 始发车站: ' + self.from_station + ' 终点站: ' +
|
|
||||||
self.to_station + ' ' + self._station_seat[j].encode("utf8") + ':' + ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))])
|
|
||||||
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("该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
print ('正在尝试提交订票...')
|
|
||||||
# self.submitOrderRequestFunc(from_station, to_station, self.time())
|
|
||||||
self.submit_station()
|
|
||||||
self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
|
|
||||||
self.getRepeatSubmitToken()
|
|
||||||
if not self.user_info: # 修改每次都调用用户接口导致用户接口不能用
|
|
||||||
self.user_info = self.getPassengerDTOs()
|
|
||||||
if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")):
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
time.sleep(self.expect_refresh_interval)
|
|
||||||
else:
|
else:
|
||||||
print "车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
|
if value['result']:
|
||||||
|
for i in value['result']:
|
||||||
|
ticket_info = i.split('|')
|
||||||
|
if ticket_info[11] == "Y" and ticket_info[1].encode("utf8") == "预订": # 筛选未在开始时间内的车次
|
||||||
|
for j in range(len(self._station_seat)):
|
||||||
|
is_ticket_pass = ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))]
|
||||||
|
# print self._station_seat[j]
|
||||||
|
if is_ticket_pass != '' and is_ticket_pass != '无' and ticket_info[3] in self.station_trains and is_ticket_pass != '*': # 过滤有效目标车次
|
||||||
|
# tiket_values = [k for k in value['map'].values()]
|
||||||
|
self.secretStr = ticket_info[0]
|
||||||
|
train_no = ticket_info[3]
|
||||||
|
print ('车次: ' + train_no + ' 始发车站: ' + self.from_station + ' 终点站: ' +
|
||||||
|
self.to_station + ' ' + self._station_seat[j].encode("utf8") + ':' + ticket_info[self.station_seat(self._station_seat[j].encode("utf8"))])
|
||||||
|
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("该车次{} 正在被关小黑屋,跳过此车次".format(train_no))
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print ('正在尝试提交订票...')
|
||||||
|
# self.submitOrderRequestFunc(from_station, to_station, self.time())
|
||||||
|
self.submit_station()
|
||||||
|
self.getPassengerTicketStr(self._station_seat[j].encode("utf8"))
|
||||||
|
self.getRepeatSubmitToken()
|
||||||
|
if not self.user_info: # 修改每次都调用用户接口导致用户接口不能用
|
||||||
|
self.user_info = self.getPassengerDTOs()
|
||||||
|
if self.checkOrderInfo(train_no, self._station_seat[j].encode("utf8")):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
time.sleep(self.expect_refresh_interval)
|
||||||
|
else:
|
||||||
|
print "车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
|
||||||
|
|
||||||
def check_user(self):
|
def check_user(self):
|
||||||
"""
|
"""
|
||||||
|
@ -249,11 +250,11 @@ class select:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
check_user_url = self.confUrl["check_user_url"]["req_url"]
|
check_user_url = self.confUrl["check_user_url"]["req_url"]
|
||||||
data = dict(_json_att=None)
|
data = {"_json_att": ""}
|
||||||
check_user = self.httpClint.send(check_user_url, data)
|
check_user = self.httpClint.send(check_user_url, data)
|
||||||
check_user_flag = check_user['data']['flag']
|
check_user_flag = check_user['data']['flag']
|
||||||
if check_user_flag is True:
|
if check_user_flag is True:
|
||||||
return True
|
self.is_check_user["user_time"] = datetime.datetime.now()
|
||||||
else:
|
else:
|
||||||
if check_user['messages']:
|
if check_user['messages']:
|
||||||
print ('用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0])
|
print ('用户检查失败:%s,可能未登录,可能session已经失效' % check_user['messages'][0])
|
||||||
|
@ -464,11 +465,7 @@ class select:
|
||||||
print("正在使用自动识别验证码功能")
|
print("正在使用自动识别验证码功能")
|
||||||
checkRandCodeAnsyn = self.confUrl["checkRandCodeAnsyn"]["req_url"]
|
checkRandCodeAnsyn = self.confUrl["checkRandCodeAnsyn"]["req_url"]
|
||||||
codeImgByOrder = self.confUrl["codeImgByOrder"]["req_url"]
|
codeImgByOrder = self.confUrl["codeImgByOrder"]["req_url"]
|
||||||
result = self.httpClint.send(codeImgByOrder)
|
randCode = self.login.readImg(codeImgByOrder)
|
||||||
img_path = './tkcode'
|
|
||||||
open(img_path, 'wb').write(result)
|
|
||||||
randCode = DamatuApi(_get_yaml()["damatu"]["uesr"], _get_yaml()["damatu"]["pwd"],
|
|
||||||
img_path).main()
|
|
||||||
randData = {
|
randData = {
|
||||||
"randCode": randCode,
|
"randCode": randCode,
|
||||||
"rand": "randp",
|
"rand": "randp",
|
||||||
|
@ -516,6 +513,9 @@ class select:
|
||||||
num += 1
|
num += 1
|
||||||
if num > 30:
|
if num > 30:
|
||||||
print("超出排队时间,自动放弃,正在重新刷票")
|
print("超出排队时间,自动放弃,正在重新刷票")
|
||||||
|
order_id = self.queryMyOrderNoComplete() # 排队失败,自动取消排队订单
|
||||||
|
if order_id:
|
||||||
|
self.cancelNoCompleteMyOrder(order_id)
|
||||||
break
|
break
|
||||||
try:
|
try:
|
||||||
data = {"random": _random, "tourFlag": "dc"}
|
data = {"random": _random, "tourFlag": "dc"}
|
||||||
|
@ -526,8 +526,8 @@ class select:
|
||||||
if queryOrderWaitTimeResult:
|
if queryOrderWaitTimeResult:
|
||||||
if "status" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["status"]:
|
if "status" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["status"]:
|
||||||
if "orderId" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["orderId"] is not None:
|
if "orderId" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["orderId"] is not None:
|
||||||
sendEmail("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!".format(queryOrderWaitTimeResult["data"]["orderId"]))
|
sendEmail("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!".format(queryOrderWaitTimeResult["data"]["orderId"]))
|
||||||
raise ticketIsExitsException("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!".format(queryOrderWaitTimeResult["data"]["orderId"]))
|
raise ticketIsExitsException("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!".format(queryOrderWaitTimeResult["data"]["orderId"]))
|
||||||
elif "msg" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["msg"]:
|
elif "msg" in queryOrderWaitTimeResult["data"] and queryOrderWaitTimeResult["data"]["msg"]:
|
||||||
print queryOrderWaitTimeResult["data"]["msg"]
|
print queryOrderWaitTimeResult["data"]["msg"]
|
||||||
break
|
break
|
||||||
|
@ -538,14 +538,10 @@ class select:
|
||||||
elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
|
elif "messages" in queryOrderWaitTimeResult and queryOrderWaitTimeResult["messages"]:
|
||||||
print("排队等待失败: " + queryOrderWaitTimeResult["messages"])
|
print("排队等待失败: " + queryOrderWaitTimeResult["messages"])
|
||||||
else:
|
else:
|
||||||
print("第{}次排队中,请耐心等待".format(num))
|
print("第{}次排队中,请耐心等待".format(num+1))
|
||||||
else:
|
else:
|
||||||
print("排队中")
|
print("排队中")
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
order_id = self.queryMyOrderNoComplete() # 尝试查看订单列表,如果有订单,则判断成功,不过一般可能性不大
|
|
||||||
if order_id:
|
|
||||||
sendEmail("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!".format(order_id))
|
|
||||||
raise ticketIsExitsException("恭喜您订票成功,订单号为:{0}, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!".format(order_id))
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print(ticketNumOutException("订单提交失败!,正在重新刷票"))
|
print(ticketNumOutException("订单提交失败!,正在重新刷票"))
|
||||||
|
@ -557,7 +553,7 @@ class select:
|
||||||
"""
|
"""
|
||||||
self.initNoComplete()
|
self.initNoComplete()
|
||||||
queryMyOrderNoCompleteUrl = self.confUrl["queryMyOrderNoCompleteUrl"]["req_url"]
|
queryMyOrderNoCompleteUrl = self.confUrl["queryMyOrderNoCompleteUrl"]["req_url"]
|
||||||
data = {"_json_att": None}
|
data = {"_json_att": ""}
|
||||||
try:
|
try:
|
||||||
queryMyOrderNoCompleteResult = self.httpClint.send(queryMyOrderNoCompleteUrl, data)
|
queryMyOrderNoCompleteResult = self.httpClint.send(queryMyOrderNoCompleteUrl, data)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -584,10 +580,31 @@ class select:
|
||||||
获取订单前需要进入订单列表页,获取订单列表页session
|
获取订单前需要进入订单列表页,获取订单列表页session
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
self.httpClint.set_cookies(acw_tc="AQAAAEnFJnekLwwAtGHjZZCr79B6dpXk", current_captcha_type="Z")
|
||||||
initNoCompleteUrl = self.confUrl["initNoCompleteUrl"]["req_url"]
|
initNoCompleteUrl = self.confUrl["initNoCompleteUrl"]["req_url"]
|
||||||
data = {"_json_att": None}
|
data = {"_json_att": ""}
|
||||||
self.httpClint.send(initNoCompleteUrl, data)
|
self.httpClint.send(initNoCompleteUrl, data)
|
||||||
|
|
||||||
|
def cancelNoCompleteMyOrder(self, sequence_no):
|
||||||
|
"""
|
||||||
|
取消订单
|
||||||
|
:param sequence_no: 订单编号
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
cancelNoCompleteMyOrderUrl = self.confUrl["cancelNoCompleteMyOrder"]["req_url"]
|
||||||
|
cancelNoCompleteMyOrderData = {
|
||||||
|
"sequence_no": sequence_no,
|
||||||
|
"cancel_flag": "cancel_order",
|
||||||
|
"_json_att": ""
|
||||||
|
}
|
||||||
|
cancelNoCompleteMyOrderResult = self.httpClint.send(cancelNoCompleteMyOrderUrl, cancelNoCompleteMyOrderData)
|
||||||
|
if "data" in cancelNoCompleteMyOrderResult and "existError" in cancelNoCompleteMyOrderResult["data"] and cancelNoCompleteMyOrderResult["data"]["existError"] == "N":
|
||||||
|
print("排队超时,已为您自动取消订单,订单编号: {0}".format(sequence_no))
|
||||||
|
time.sleep(2)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("排队超时,取消订单失败, 订单号{0}".format(sequence_no))
|
||||||
|
|
||||||
# def call_submit_ticket(self, function_name=None):
|
# def call_submit_ticket(self, function_name=None):
|
||||||
# """
|
# """
|
||||||
# 订票失败回调方法,默认执行submitOrderRequest()
|
# 订票失败回调方法,默认执行submitOrderRequest()
|
||||||
|
@ -600,21 +617,27 @@ class select:
|
||||||
# else:
|
# else:
|
||||||
# self.submitOrderRequest()
|
# self.submitOrderRequest()
|
||||||
|
|
||||||
def call_login(self):
|
def call_login(self, auth=False):
|
||||||
"""登录回调方法"""
|
"""
|
||||||
login = GoLogin(self.httpClint, self.confUrl)
|
登录回调方法
|
||||||
login.go_login()
|
:return:
|
||||||
|
"""
|
||||||
|
if auth:
|
||||||
|
return self.login.auth()
|
||||||
|
else:
|
||||||
|
self.login.go_login()
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
self.call_login()
|
self.call_login()
|
||||||
from_station, to_station = self.station_table(self.from_station, self.to_station)
|
from_station, to_station = self.station_table(self.from_station, self.to_station)
|
||||||
# if self.leftTicketLog(from_station, to_station):
|
self.check_user()
|
||||||
|
time.sleep(0.1)
|
||||||
num = 1
|
num = 1
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
num += 1
|
num += 1
|
||||||
if "user_time" in self.is_check_user and (datetime.datetime.now() - self.is_check_user["user_time"]).seconds/60 > 10:
|
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()
|
self.check_user()
|
||||||
time.sleep(self.select_refresh_interval)
|
time.sleep(self.select_refresh_interval)
|
||||||
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
|
if time.strftime('%H:%M:%S', time.localtime(time.time())) > "23:00:00":
|
||||||
|
@ -623,7 +646,7 @@ class select:
|
||||||
self.call_login()
|
self.call_login()
|
||||||
start_time = datetime.datetime.now()
|
start_time = datetime.datetime.now()
|
||||||
self.submitOrderRequestImplement(from_station, to_station)
|
self.submitOrderRequestImplement(from_station, to_station)
|
||||||
print "正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 代理设置 无 总耗时{3}ms".format(num, self.station_date, ",".join(self.station_trains), (datetime.datetime.now()-start_time).microseconds/1000)
|
print "正在第{0}次查询 乘车日期: {1} 车次{2} 查询无票 代理设置 无 总耗时{3}ms".format(num, ",".join(self.station_dates), ",".join(self.station_trains), (datetime.datetime.now()-start_time).microseconds/1000)
|
||||||
except PassengerUserException as e:
|
except PassengerUserException as e:
|
||||||
print e.message
|
print e.message
|
||||||
break
|
break
|
||||||
|
@ -647,13 +670,11 @@ class select:
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print(e.message)
|
print(e.message)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
print(e.message)
|
print("12306接口无响应,正在重试 {0}".format(e.message))
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
print(e.message)
|
print(e.message)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
login()
|
login()
|
||||||
# a = select('上海', '北京')
|
# a = select('上海', '北京')
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from config import logger
|
||||||
|
|
||||||
class HTTPClient(object):
|
class HTTPClient(object):
|
||||||
|
|
||||||
|
@ -57,6 +60,10 @@ class HTTPClient(object):
|
||||||
self._s.headers.update(headers)
|
self._s.headers.update(headers)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def resetHeaders(self):
|
||||||
|
self._s.headers.clear()
|
||||||
|
self._s.headers.update(self._set_header())
|
||||||
|
|
||||||
def getHeadersHost(self):
|
def getHeadersHost(self):
|
||||||
return self._s.headers["Host"]
|
return self._s.headers["Host"]
|
||||||
|
|
||||||
|
@ -71,26 +78,41 @@ class HTTPClient(object):
|
||||||
self._s.headers.update({"Referer": referer})
|
self._s.headers.update({"Referer": referer})
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def send(self, url, data=None, **kwargs):
|
def send(self, url, data=None, is_logger=True, **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."""
|
||||||
method = "post"if data else "get"
|
allow_redirects = False
|
||||||
response = self._s.request(method=method,
|
error_data = {"code": 99999, "message": "重试次数达到上限"}
|
||||||
url=url,
|
if data:
|
||||||
data=data,
|
method = "post"
|
||||||
**kwargs)
|
self.setHeaders({"Content-Length": "{0}".format(len(data))})
|
||||||
try:
|
else:
|
||||||
if response.content:
|
method = "get"
|
||||||
return json.loads(response.content) if method == "post" else response.content
|
self.resetHeaders()
|
||||||
else:
|
if is_logger:
|
||||||
return ""
|
logger.log(
|
||||||
except ValueError as e:
|
u"url: {0}\n入参: {1}\n请求方式: {2}\n".format(url,data,method,))
|
||||||
if e.message == "No JSON object could be decoded":
|
for i in range(10):
|
||||||
print("12306接口无响应,正在重试")
|
try:
|
||||||
else:
|
response = self._s.request(method=method,
|
||||||
print(e.message)
|
timeout=10,
|
||||||
except KeyError as e:
|
url=url,
|
||||||
print(e.message)
|
data=data,
|
||||||
except TypeError as e:
|
allow_redirects=allow_redirects,
|
||||||
print(e.message)
|
**kwargs)
|
||||||
except socket.error as e:
|
if response.status_code == 200:
|
||||||
print(e.message)
|
if response.content:
|
||||||
|
if is_logger:
|
||||||
|
logger.log(
|
||||||
|
u"出参:{0}".format(response.content))
|
||||||
|
return json.loads(response.content) if method == "post" else response.content
|
||||||
|
else:
|
||||||
|
logger.log(
|
||||||
|
u"url: {} 返回参数为空".format(url))
|
||||||
|
return error_data
|
||||||
|
else:
|
||||||
|
sleep(0.1)
|
||||||
|
except (requests.exceptions.Timeout, requests.exceptions.ReadTimeout, requests.exceptions.ConnectionError):
|
||||||
|
pass
|
||||||
|
except socket.error:
|
||||||
|
pass
|
||||||
|
return error_data
|
||||||
|
|
BIN
tkcode
BIN
tkcode
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Loading…
Reference in New Issue