mirror of https://github.com/testerSunshine/12306
commit
99ec619f2c
|
@ -10,4 +10,5 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|||
#EXPOSE 5010
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
CMD [ "python", "run.py" ]
|
||||
#CMD [ "python", "run.py" ]
|
||||
ENTRYPOINT [ "python", "run.py" ]
|
||||
|
|
17
README.md
17
README.md
|
@ -19,8 +19,9 @@
|
|||
- 由于新增对时功能,请务必用sudo,sudo,sudo 执行,否则会报权限错误,windows打开ide或者cmd请用管理员身份执行python run.py,不需要加sudo
|
||||
- 如果你的服务器安装了docker,那么就可以docker启动
|
||||
- 1、docker build -t dockerticket .
|
||||
- 2、docker run dockerticket python run.py &
|
||||
- 3、本来是可以直接Dockerfile启动的,不知道为毛启动不了,如果有大佬看到问题所在,欢迎提出
|
||||
- 2、~~docker run dockerticket python run.py &~~
|
||||
- 3、~~本来是可以直接Dockerfile启动的,不知道为毛启动不了,如果有大佬看到问题所在,欢迎提出~~
|
||||
- 4、docker run -d --name 12306-ticket dockerticket
|
||||
|
||||
- 目录对应说明
|
||||
- agency - cdn代理
|
||||
|
@ -34,7 +35,8 @@
|
|||

|
||||
|
||||
- 项目声明:
|
||||
- 本软件只供学习交流使用,务作为商业用途,交流群号:286271084(已满), 请加2群:649992274
|
||||
- 本软件只供学习交流使用,务作为商业用途,交流群号:286271084(已满), 2群:649992274(已满),请加3群, 群号:632501142,
|
||||
- **进群先看公告!!!进群先看公告!!!进群先看公告!!! 重要的事情说三遍**
|
||||
- 能为你抢到一张回家的票,是我最大的心愿
|
||||
|
||||
- 成功log,如果是购票失败的,请带上失败的log给我,我尽力帮你调,也可加群一起交流,程序只是加速买票的过程,并不一定能买到票
|
||||
|
@ -56,15 +58,20 @@
|
|||
恭喜您订票成功,订单号为:EB52743573, 请立即打开浏览器登录12306,访问‘未完成订单’,在30分钟内完成支付!
|
||||
```
|
||||
- 使用帮助:
|
||||
- 测试邮箱是否可用
|
||||
- 测试邮箱是否可用 [邮箱配置问题看issues](https://github.com/testerSunshine/12306/issues/107)
|
||||
- 学生票issues [学生票修改](https://github.com/testerSunshine/12306/issues/47)
|
||||
- 依赖安装不对的问题(ImportError)[requirements.txt问题](https://github.com/testerSunshine/12306/issues/91)
|
||||
- 若快豆子疑问 [点我](https://github.com/testerSunshine/12306/issues/67)
|
||||
|
||||
- 测试下单接口是否可用,有两个下单接口,随便用哪个都ok
|
||||
- 如果下载验证码过期或者下载失败的问题,应该是12306封ip的策略,多重试几次,12306现在封服务器(阿里云和腾讯云)ip比较严重,尽量不要放在服务器里面
|
||||
- 感谢一下小伙伴对本项目提供的帮助
|
||||
- @ sun7127@126.com
|
||||
- @才
|
||||
- 以及所有为此项目提供pr的同学
|
||||
- [更新日志](Update.md)
|
||||
|
||||
- 如果觉得项目还不错,可以考虑打赏一波,哈哈
|
||||
- 如果觉得项目还不错,可以考虑打赏一波
|
||||
-
|
||||

|
||||

|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
# encoding=utf8
|
||||
import collections
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import csv
|
||||
import requests
|
||||
from config import urlConf
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
|
||||
try:
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
class CDNProxy:
|
||||
def __init__(self, host=None):
|
||||
|
@ -42,7 +46,7 @@ class CDNProxy:
|
|||
city_re = re.compile(r"<li id=\"(\S+)\" class=\"PingListCent PingRLlist")
|
||||
self.city_list = re.findall(city_re, rep.content)
|
||||
if self.city_list:
|
||||
print self.city_list
|
||||
print(self.city_list)
|
||||
break
|
||||
else:
|
||||
pass
|
||||
|
@ -51,62 +55,24 @@ class CDNProxy:
|
|||
|
||||
def open_cdn_file(self):
|
||||
cdn = []
|
||||
cdn_re = re.compile("CONNECT (\S+) HTTP/1.1")
|
||||
with open("./cdn_list", "r") as f:
|
||||
# cdn_re = re.compile("CONNECT (\S+) HTTP/1.1")
|
||||
# path = os.path.join(os.path.dirname(__file__), '../cdn_list')
|
||||
# with open(path, "r") as f:
|
||||
# for i in f.readlines():
|
||||
# # print(i.replace("\n", ""))
|
||||
# cdn_list = re.findall(cdn_re, i)
|
||||
# if cdn_list and "kyfw.12306.cn:443" not in cdn_list:
|
||||
# print(cdn_list[0].split(":")[0])
|
||||
# cdn.append(cdn_list[0].split(":")[0])
|
||||
# return cdn
|
||||
path = os.path.join(os.path.dirname(__file__), '../cdn_list')
|
||||
with open(path, "r") as f:
|
||||
for i in f.readlines():
|
||||
# print(i.replace("\n", ""))
|
||||
cdn_list = re.findall(cdn_re, i)
|
||||
if cdn_list and "kyfw.12306.cn:443" not in cdn_list:
|
||||
cdn.append(cdn_list[0].split(":")[0])
|
||||
if i and "kyfw.12306.cn:443" not in i:
|
||||
cdn.append(i.replace("\n", ""))
|
||||
return cdn
|
||||
|
||||
def get_cdn_list(self):
|
||||
"""
|
||||
筛选代理
|
||||
:return:
|
||||
"""
|
||||
f = self.open_cdn_file()
|
||||
url = self.urlConf["cdn_list"]["req_url"]
|
||||
num = 1
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
for guid in self.city_list:
|
||||
data = {"guid": guid,
|
||||
"host": "kyfw.12306.cn",
|
||||
"ishost": 0,
|
||||
"encode": "HJXhdRqjh5yCF6G/AZ6EDk9faB1oSk5r",
|
||||
"checktype": 0}
|
||||
try:
|
||||
cdn_info = self.httpClint.post(url, data, headers=self._set_header(), timeout=self.timeout).content
|
||||
print(cdn_info)
|
||||
if cdn_info:
|
||||
split_cdn = cdn_info.split("(")[1].rstrip(")").replace("{", "").replace("}", "").split(",")
|
||||
local_dict = collections.OrderedDict()
|
||||
for i in split_cdn:
|
||||
splits = i.split(":")
|
||||
local_dict[splits[0]] = splits[2] if splits[0] == "result" else splits[1]
|
||||
if local_dict and "state" in local_dict and local_dict["state"] == "1":
|
||||
if "responsetime" in local_dict and local_dict["responsetime"].find("毫秒") != -1 and int(filter(str.isdigit, local_dict["responsetime"])) < 100:
|
||||
f.write(json.dumps(local_dict)+"\n")
|
||||
num += 1
|
||||
except Exception as e:
|
||||
print(e.message)
|
||||
print(u"本次cdn获取完成,总个数{0}".format(num))
|
||||
|
||||
def all_cdn(self):
|
||||
"""获取cdn列表"""
|
||||
with open('cdn_list', 'r') as f:
|
||||
cdn = f.readlines()
|
||||
return cdn
|
||||
|
||||
def par_csv(self):
|
||||
cdn_csv = csv.reader(open("../cdn1.csv", "r"))
|
||||
for c in cdn_csv:
|
||||
cdn_re = re.compile(r'https://(\S+)/otn/index/init')
|
||||
cdn_ip = re.findall(cdn_re, c[0])
|
||||
if cdn_ip and c[2] == "200":
|
||||
print(cdn_ip[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cdn = CDNProxy()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
saleMinDelayDay = 0
|
||||
|
@ -17,15 +18,20 @@ RS_JSON_ERROR = 2
|
|||
RS_OTHER_ERROR = 3
|
||||
|
||||
seat_conf = {'商务座': 32,
|
||||
'一等座': 31,
|
||||
'二等座': 30,
|
||||
'特等座': 25,
|
||||
'软卧': 23,
|
||||
'硬卧': 28,
|
||||
'硬座': 29,
|
||||
'无座': 26,
|
||||
}
|
||||
seat_conf_2 = dict([(v,k) for (k,v) in seat_conf.iteritems()])
|
||||
'一等座': 31,
|
||||
'二等座': 30,
|
||||
'特等座': 25,
|
||||
'软卧': 23,
|
||||
'硬卧': 28,
|
||||
'软座': 24,
|
||||
'硬座': 29,
|
||||
'无座': 26,
|
||||
}
|
||||
if sys.version_info.major == 2:
|
||||
seat_conf_2 = dict([(v, k) for (k, v) in seat_conf.iteritems()])
|
||||
else:
|
||||
seat_conf_2 = dict([(v, k) for (k, v) in seat_conf.items()])
|
||||
|
||||
|
||||
def getNowTimestamp():
|
||||
return time.time()
|
||||
|
@ -90,3 +96,14 @@ def getVCodeImageFile(imageName):
|
|||
|
||||
def getCacheFile(cacheType):
|
||||
return os.path.join(getCacheDir(), cacheType + ".cache")
|
||||
|
||||
|
||||
def checkSleepTime(session):
|
||||
now = datetime.datetime.now()
|
||||
if now.hour >= 23 or now.hour < 6:
|
||||
print(u"12306休息时间,本程序自动停止,明天早上七点将自动运行")
|
||||
open_time = datetime.datetime(now.year, now.month, now.day, 6)
|
||||
if open_time < now:
|
||||
open_time += datetime.timedelta(1)
|
||||
time.sleep((open_time - now).seconds)
|
||||
session.call_login()
|
||||
|
|
|
@ -13,4 +13,8 @@ def _get_yaml():
|
|||
f = open(path)
|
||||
s = yaml.load(f)
|
||||
f.close()
|
||||
return s
|
||||
return s.decode() if isinstance(s, bytes) else s
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(_get_yaml())
|
|
@ -5,8 +5,7 @@ set:
|
|||
# - 2018-01-06
|
||||
# - 2018-01-07
|
||||
station_dates:
|
||||
- "2019-01-27"
|
||||
- "2019-01-26"
|
||||
- "2019-02-02"
|
||||
|
||||
# 是否根据时间范围 和 乘车类型 购票
|
||||
# 否则将需要手动填写车次
|
||||
|
@ -46,15 +45,18 @@ set:
|
|||
# - "G1021"
|
||||
# - "G99"
|
||||
# - "G6011"
|
||||
- "D2972"
|
||||
- "D1874"
|
||||
- "D2834"
|
||||
# - "D2972"
|
||||
# - "D1874"
|
||||
# - "D2834"
|
||||
- "G6172"
|
||||
- "G6186"
|
||||
- "G6154"
|
||||
|
||||
# 出发城市,比如深圳北,就填深圳就搜得到
|
||||
from_station: "广州南"
|
||||
|
||||
# 到达城市 比如深圳北,就填深圳就搜得到
|
||||
to_station: "三江南"
|
||||
to_station: "邵阳"
|
||||
|
||||
# 座位(list) 多个座位ex:
|
||||
# - "二等座"
|
||||
|
@ -69,8 +71,9 @@ set:
|
|||
# - "张三"
|
||||
# - "李四"
|
||||
ticke_peoples:
|
||||
# - "文贤平"
|
||||
- "梁敏"
|
||||
- "文贤平"
|
||||
- "李梦云"
|
||||
# - "梁敏"
|
||||
# 12306登录账号(list)
|
||||
12306account:
|
||||
- user: "931128603@qq.com"
|
||||
|
@ -80,7 +83,7 @@ set:
|
|||
ticket_black_list_time: 5
|
||||
|
||||
# 自动打码
|
||||
is_auto_code: True
|
||||
is_auto_code: False
|
||||
|
||||
# 打码平台, 2 为若快平台(目前只支持若快平台打码,打码兔已经关闭), 若快注册地址:http://www.ruokuai.com/client/index?6726
|
||||
auto_code_type: 2
|
||||
|
@ -119,7 +122,10 @@ order_type: 2
|
|||
|
||||
# 下单模式 1 为预售,整点刷新,刷新间隔0.1-0.5S, 然后会校验时间,比如12点的预售,那脚本就会在12.00整检票,刷新订单
|
||||
# 2 是捡漏,捡漏的刷新间隔时间为0.5-3秒,时间间隔长,不容易封ip
|
||||
order_model: 1
|
||||
order_model: 2
|
||||
|
||||
# 预售放票时间, 如果是捡漏模式,可以忽略此操作
|
||||
open_time: '13:00:00'
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ urls = {
|
|||
"s_time": 0.1,
|
||||
"is_logger": False,
|
||||
"is_json": False,
|
||||
"not_decode": True,
|
||||
},
|
||||
"codeCheck": { # 验证码校验
|
||||
"req_url": "/passport/captcha/captcha-check",
|
||||
|
|
|
@ -52,5 +52,5 @@ class RClient(object):
|
|||
if __name__ == '__main__':
|
||||
rc = RClient('931128603', '',)
|
||||
im = open('tkcode', 'rb').read()
|
||||
print rc.rk_create(im, 6113)
|
||||
print(rc.rk_create(im, 6113))
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ from inter.GetPassCodeNewOrderAndLogin import getPassCodeNewOrderAndLogin
|
|||
from inter.GetRandCode import getRandCode
|
||||
from myException.UserPasswordException import UserPasswordException
|
||||
from myException.balanceException import balanceException
|
||||
from myUrllib import myurllib2
|
||||
|
||||
|
||||
class GoLogin:
|
||||
|
@ -127,15 +126,6 @@ class GoLogin:
|
|||
self.getUserName(uamtk)
|
||||
break
|
||||
|
||||
def logout(self):
|
||||
url = 'https://kyfw.12306.cn/otn/login/loginOut'
|
||||
result = myurllib2.get(url)
|
||||
if result:
|
||||
print (u"已退出")
|
||||
else:
|
||||
print (u"退出失败")
|
||||
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# # main()
|
||||
# # logout()
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding=utf-8 -*-
|
||||
import datetime
|
||||
import random
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import threading
|
||||
|
@ -9,7 +10,7 @@ import time
|
|||
import wrapcache
|
||||
|
||||
from agency.cdn_utils import CDNProxy
|
||||
from config import urlConf
|
||||
from config import urlConf, configCommon
|
||||
from config.AutoSynchroTime import autoSynchroTime
|
||||
from config.TicketEnmu import ticket
|
||||
from config.configCommon import seat_conf
|
||||
|
@ -30,8 +31,11 @@ from myException.ticketNumOutException import ticketNumOutException
|
|||
from myUrllib.httpUtils import HTTPClient
|
||||
from utils.timeUtil import time_to_minutes, minutes_to_time
|
||||
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
try:
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
|
||||
class select:
|
||||
|
@ -43,7 +47,7 @@ class select:
|
|||
self.from_station, self.to_station, self.station_dates, self._station_seat, self.is_more_ticket, \
|
||||
self.ticke_peoples, self.station_trains, self.ticket_black_list_time, \
|
||||
self.order_type, self.is_by_time, self.train_types, self.departure_time, \
|
||||
self.arrival_time, self.take_time, self.order_model = self.get_ticket_info()
|
||||
self.arrival_time, self.take_time, self.order_model, self.open_time = self.get_ticket_info()
|
||||
self.is_auto_code = _get_yaml()["is_auto_code"]
|
||||
self.auto_code_type = _get_yaml()["auto_code_type"]
|
||||
self.is_cdn = _get_yaml()["is_cdn"]
|
||||
|
@ -51,7 +55,7 @@ class select:
|
|||
self.urls = urlConf.urls
|
||||
self.login = GoLogin(self, self.is_auto_code, self.auto_code_type)
|
||||
self.cdn_list = []
|
||||
self.queryUrl = "leftTicket/queryX"
|
||||
self.queryUrl = "leftTicket/queryZ"
|
||||
self.passengerTicketStrList = ""
|
||||
self.oldPassengerStr = ""
|
||||
self.set_type = ""
|
||||
|
@ -62,11 +66,11 @@ class select:
|
|||
: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")
|
||||
from_station = ticket_info_config["set"]["from_station"]
|
||||
to_station = ticket_info_config["set"]["to_station"]
|
||||
station_dates = ticket_info_config["set"]["station_dates"]
|
||||
set_names = ticket_info_config["set"]["set_type"]
|
||||
set_type = [seat_conf[x.encode("utf8")] for x in ticket_info_config["set"]["set_type"]]
|
||||
set_type = [seat_conf[x.encode("utf-8")] for x in ticket_info_config["set"]["set_type"]]
|
||||
is_more_ticket = ticket_info_config["set"]["is_more_ticket"]
|
||||
ticke_peoples = ticket_info_config["set"]["ticke_peoples"]
|
||||
station_trains = ticket_info_config["set"]["station_trains"]
|
||||
|
@ -82,17 +86,18 @@ class select:
|
|||
|
||||
# 下单模式
|
||||
order_model = ticket_info_config["order_model"]
|
||||
open_time = ticket_info_config["open_time"]
|
||||
|
||||
print u"*" * 20
|
||||
print u"12306刷票小助手,最后更新于2019.01.02,请勿作为商业用途,交流群号:286271084(已满), 请加2群:649992274"
|
||||
print(u"*" * 50)
|
||||
print(u"12306刷票小助手,最后更新于2019.01.07,请勿作为商业用途,交流群号:286271084(已满), 2群:649992274(已满),请加3群,群号:632501142")
|
||||
if is_by_time:
|
||||
method_notie = u"购票方式:根据时间区间购票\n可接受最早出发时间:{0}\n可接受最晚抵达时间:{1}\n可接受最长旅途时间:{2}\n可接受列车类型:{3}\n" \
|
||||
.format(minutes_to_time(departure_time), minutes_to_time(arrival_time), minutes_to_time(take_time),
|
||||
" , ".join(train_types))
|
||||
else:
|
||||
method_notie = u"购票方式:根据候选车次购买\n候选购买车次:{0}".format(",".join(station_trains))
|
||||
print u"当前配置:\n出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票优先提交:{4}\n乘车人:{5}\n" \
|
||||
u"刷新间隔:随机(1-3S)\n{6}\n僵尸票关小黑屋时长:{7}\n 下单接口:{8}\n 下单模式:{9}\n".format \
|
||||
print (u"当前配置:\n出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票优先提交:{4}\n乘车人:{5}\n" \
|
||||
u"刷新间隔: 随机(1-3S)\n{6}\n僵尸票关小黑屋时长: {7}\n下单接口: {8}\n下单模式: {9}\n预售踩点时间:{10} ".format \
|
||||
(
|
||||
from_station,
|
||||
to_station,
|
||||
|
@ -103,12 +108,13 @@ class select:
|
|||
method_notie,
|
||||
ticket_black_list_time,
|
||||
order_type,
|
||||
order_model
|
||||
)
|
||||
print u"*" * 20
|
||||
order_model,
|
||||
open_time,
|
||||
))
|
||||
print (u"*" * 50)
|
||||
return from_station, to_station, station_dates, set_type, is_more_ticket, ticke_peoples, station_trains, \
|
||||
ticket_black_list_time, order_type, is_by_time, train_types, departure_time, arrival_time, take_time, \
|
||||
order_model
|
||||
order_model, open_time
|
||||
|
||||
def station_table(self, from_station, to_station):
|
||||
"""
|
||||
|
@ -116,7 +122,8 @@ class select:
|
|||
:param station:
|
||||
:return:
|
||||
"""
|
||||
result = open('station_name.txt')
|
||||
path = os.path.join(os.path.dirname(__file__), '../station_name.txt')
|
||||
result = open(path)
|
||||
info = result.read().split('=')[1].strip("'").split('@')
|
||||
del info[0]
|
||||
station_name = {}
|
||||
|
@ -146,7 +153,7 @@ class select:
|
|||
rep = http.send(urls)
|
||||
if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 500:
|
||||
if cdn[i].replace("\n", "") not in self.cdn_list: # 如果有重复的cdn,则放弃加入
|
||||
print("加入cdn {0}".format(cdn[i].replace("\n", "")))
|
||||
# print(u"加入cdn {0}".format(cdn[i].replace("\n", "")))
|
||||
self.cdn_list.append(cdn[i].replace("\n", ""))
|
||||
print(u"所有cdn解析完成...")
|
||||
|
||||
|
@ -177,30 +184,25 @@ class select:
|
|||
l.reqLiftTicketInit()
|
||||
self.call_login()
|
||||
check_user = checkUser(self)
|
||||
check_user.sendCheckUser()
|
||||
t = threading.Thread(target=check_user.sendCheckUser)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
from_station, to_station = self.station_table(self.from_station, self.to_station)
|
||||
num = 0
|
||||
# isAutoSynchroTime = False
|
||||
while 1:
|
||||
try:
|
||||
num += 1
|
||||
check_user.sendCheckUser()
|
||||
now = datetime.datetime.now() # 感谢群里大佬提供整点代码
|
||||
if now.hour >= 23 or now.hour < 6:
|
||||
print(u"12306休息时间,本程序自动停止,明天早上七点将自动运行")
|
||||
open_time = datetime.datetime(now.year, now.month, now.day, 6)
|
||||
if open_time < now:
|
||||
open_time += datetime.timedelta(1)
|
||||
time.sleep((open_time - now).seconds)
|
||||
self.call_login()
|
||||
configCommon.checkSleepTime(self) # 晚上到点休眠
|
||||
if self.order_model is 1:
|
||||
sleep_time_s = 0.1
|
||||
sleep_time_t = 0.5
|
||||
sleep_time_s = 0.5
|
||||
sleep_time_t = 0.6
|
||||
# 测试了一下有微妙级的误差,应该不影响,测试结果:2019-01-02 22:30:00.004555,预售还是会受到前一次刷新的时间影响,暂时没想到好的解决方案
|
||||
if now.strftime("%M:%S") == "29:55" or now.strftime("%M:%S") == "59:55":
|
||||
print(u"预售整点模式卡点中")
|
||||
time.sleep(5)
|
||||
print(u"预售模式执行")
|
||||
while not now.strftime("%H:%M:%S") == self.open_time:
|
||||
now = datetime.datetime.now()
|
||||
if now.strftime("%H:%M:%S") > self.open_time:
|
||||
break
|
||||
time.sleep(0.0001)
|
||||
else:
|
||||
sleep_time_s = 0.5
|
||||
sleep_time_t = 3
|
||||
|
@ -275,31 +277,31 @@ class select:
|
|||
random_time))
|
||||
time.sleep(random_time)
|
||||
except PassengerUserException as e:
|
||||
print e.message
|
||||
print(e)
|
||||
break
|
||||
except ticketConfigException as e:
|
||||
print e.message
|
||||
print(e)
|
||||
break
|
||||
except ticketIsExitsException as e:
|
||||
print e.message
|
||||
print(e)
|
||||
break
|
||||
except ticketNumOutException as e:
|
||||
print e.message
|
||||
print(e)
|
||||
break
|
||||
except UserPasswordException as e:
|
||||
print e.message
|
||||
print(e)
|
||||
break
|
||||
except ValueError as e:
|
||||
if e.message == "No JSON object could be decoded":
|
||||
if e == "No JSON object could be decoded":
|
||||
print(u"12306接口无响应,正在重试")
|
||||
else:
|
||||
print(e.message)
|
||||
print(e)
|
||||
except KeyError as e:
|
||||
print(e.message)
|
||||
print(e)
|
||||
except TypeError as e:
|
||||
print(u"12306接口无响应,正在重试 {0}".format(e.message))
|
||||
print(u"12306接口无响应,正在重试 {0}".format(e))
|
||||
except socket.error as e:
|
||||
print(e.message)
|
||||
print(e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -68,7 +68,7 @@ class checkOrderInfo:
|
|||
self.passengerTicketStrList,
|
||||
)
|
||||
QueueCount.sendGetQueueCount()
|
||||
elif "errMsg" in checkOrderInfoRep['data'] and checkOrderInfoRep['data']["errMsg"]:
|
||||
print checkOrderInfoRep['data']["errMsg"]
|
||||
elif "errMsg" in data and data["errMsg"]:
|
||||
print(checkOrderInfoRep['data']["errMsg"])
|
||||
elif 'messages' in checkOrderInfoRep and checkOrderInfoRep['messages']:
|
||||
print (checkOrderInfoRep['messages'][0])
|
|
@ -1,7 +1,8 @@
|
|||
# coding=utf-8
|
||||
import datetime
|
||||
import time
|
||||
import wrapcache
|
||||
|
||||
from config import configCommon
|
||||
from config.TicketEnmu import ticket
|
||||
|
||||
|
||||
|
@ -15,20 +16,23 @@ class checkUser:
|
|||
:return:
|
||||
"""
|
||||
CHENK_TIME = 0.3
|
||||
if wrapcache.get("user_time") is None:
|
||||
check_user_url = self.session.urls["check_user_url"]
|
||||
data = {"_json_att": ""}
|
||||
check_user = self.session.httpClint.send(check_user_url, data)
|
||||
if check_user.get("data", False):
|
||||
check_user_flag = check_user["data"]["flag"]
|
||||
if check_user_flag is True:
|
||||
wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * CHENK_TIME)
|
||||
else:
|
||||
if check_user['messages']:
|
||||
print (ticket.LOGIN_SESSION_FAIL.format(check_user['messages']))
|
||||
self.session.call_login()
|
||||
while 1:
|
||||
time.sleep(0.1) # 防止cpu占用过高
|
||||
configCommon.checkSleepTime(self.session) # 修复晚上查询线程休眠时,检查登录线程为休眠,造成快豆迅速消耗
|
||||
if wrapcache.get("user_time") is None:
|
||||
check_user_url = self.session.urls["check_user_url"]
|
||||
data = {"_json_att": ""}
|
||||
check_user = self.session.httpClint.send(check_user_url, data)
|
||||
if check_user.get("data", False):
|
||||
check_user_flag = check_user["data"]["flag"]
|
||||
if check_user_flag is True:
|
||||
wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * CHENK_TIME)
|
||||
else:
|
||||
print (ticket.LOGIN_SESSION_FAIL.format(check_user['messages']))
|
||||
self.session.call_login()
|
||||
wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * CHENK_TIME)
|
||||
if check_user['messages']:
|
||||
print (ticket.LOGIN_SESSION_FAIL.format(check_user['messages']))
|
||||
self.session.call_login()
|
||||
wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * CHENK_TIME)
|
||||
else:
|
||||
print (ticket.LOGIN_SESSION_FAIL.format(check_user['messages']))
|
||||
self.session.call_login()
|
||||
wrapcache.set("user_time", datetime.datetime.now(), timeout=60 * CHENK_TIME)
|
|
@ -18,11 +18,11 @@ def getPassCodeNewOrderAndLogin(session, imgType):
|
|||
codeImgUrl = copy.deepcopy(session.urls["codeImgByOrder"])
|
||||
codeImgUrl["req_url"] = codeImgUrl["req_url"].format(random.random())
|
||||
print (u"下载验证码...")
|
||||
img_path = './tkcode'
|
||||
img_path = './tkcode.png'
|
||||
result = session.httpClint.send(codeImgUrl)
|
||||
try:
|
||||
if isinstance(result, dict):
|
||||
print(u"下载验证码失败, 请手动检查是否ip被封,或者重试,请求地址:{}".format(codeImgUrl.get("req_url")))
|
||||
print(u"下载验证码失败, 请手动检查是否ip被封,或者重试,请求地址:https://kyfw.12306.cn/{}".format(codeImgUrl.get("req_url")))
|
||||
return False
|
||||
else:
|
||||
print(u"下载验证码成功")
|
||||
|
|
|
@ -3,6 +3,11 @@ from config.TicketEnmu import ticket
|
|||
from myException.PassengerUserException import PassengerUserException
|
||||
import wrapcache
|
||||
|
||||
try:
|
||||
xrange # Python 2
|
||||
except NameError:
|
||||
xrange = range # Python 3
|
||||
|
||||
|
||||
class getPassengerDTOs:
|
||||
"""
|
||||
|
@ -48,6 +53,7 @@ class getPassengerDTOs:
|
|||
'商务座': 9,
|
||||
'硬座': 1,
|
||||
'无座': 1,
|
||||
'软座': 2,
|
||||
'软卧': 4,
|
||||
'硬卧': 3,
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ from PIL import Image
|
|||
from config.ticketConf import _get_yaml
|
||||
from damatuCode.ruokuai import RClient
|
||||
|
||||
try:
|
||||
raw_input # Python 2
|
||||
except NameError: # Python 3
|
||||
raw_input = input
|
||||
|
||||
|
||||
def getRandCode(is_auto_code, auto_code_type, result):
|
||||
"""
|
||||
|
@ -23,10 +28,10 @@ def getRandCode(is_auto_code, auto_code_type, result):
|
|||
return codexy(Ofset=",".join(list(Result["Result"])), is_raw_input=False)
|
||||
else:
|
||||
if "Error" in Result and Result["Error"]:
|
||||
print u"打码平台错误: {0}, 请登录打码平台查看-http://www.ruokuai.com/client/index?6726".format(Result["Error"])
|
||||
print(u"打码平台错误: {0}, 请登录打码平台查看-http://www.ruokuai.com/client/index?6726".format(Result["Error"]))
|
||||
return ""
|
||||
else:
|
||||
img = Image.open('./tkcode')
|
||||
img = Image.open('./tkcode.png')
|
||||
img.show()
|
||||
return codexy()
|
||||
except Exception as e:
|
||||
|
@ -46,7 +51,8 @@ def codexy(Ofset=None, is_raw_input=True):
|
|||
| 5 | 6 | 7 | 8 |
|
||||
*****************
|
||||
""")
|
||||
print(u"验证码分为8个,对应上面数字,例如第一和第二张,输入1, 2")
|
||||
print(u"验证码分为8个,对应上面数字,例如第一和第二张,输入1, 2 如果开启cdn查询的话,会冲掉提示,直接鼠标点击命令行获取焦点,输入即可,不要输入空格")
|
||||
print(u"如果是linux无图形界面,请使用自动打码,is_auto_code: True")
|
||||
Ofset = raw_input(u"输入对应的验证码: ")
|
||||
Ofset = Ofset.replace(",", ",")
|
||||
select = Ofset.split(',')
|
||||
|
@ -55,29 +61,29 @@ def codexy(Ofset=None, is_raw_input=True):
|
|||
offsetsY = 0 # 选择的答案的top值
|
||||
for ofset in select:
|
||||
if ofset == '1':
|
||||
offsetsY = 46
|
||||
offsetsX = 42
|
||||
offsetsY = 77
|
||||
offsetsX = 40
|
||||
elif ofset == '2':
|
||||
offsetsY = 46
|
||||
offsetsX = 105
|
||||
offsetsY = 77
|
||||
offsetsX = 112
|
||||
elif ofset == '3':
|
||||
offsetsY = 45
|
||||
offsetsY = 77
|
||||
offsetsX = 184
|
||||
elif ofset == '4':
|
||||
offsetsY = 48
|
||||
offsetsY = 77
|
||||
offsetsX = 256
|
||||
elif ofset == '5':
|
||||
offsetsY = 36
|
||||
offsetsX = 117
|
||||
offsetsY = 149
|
||||
offsetsX = 40
|
||||
elif ofset == '6':
|
||||
offsetsY = 112
|
||||
offsetsX = 115
|
||||
offsetsY = 149
|
||||
offsetsX = 112
|
||||
elif ofset == '7':
|
||||
offsetsY = 114
|
||||
offsetsX = 181
|
||||
offsetsY = 149
|
||||
offsetsX = 184
|
||||
elif ofset == '8':
|
||||
offsetsY = 111
|
||||
offsetsX = 252
|
||||
offsetsY = 149
|
||||
offsetsX = 256
|
||||
else:
|
||||
pass
|
||||
post.append(offsetsX)
|
||||
|
|
|
@ -117,7 +117,7 @@ class query:
|
|||
start_time = ticket_info[8]
|
||||
arrival_time = ticket_info[9]
|
||||
distance_time = ticket_info[10]
|
||||
print start_time, arrival_time, distance_time
|
||||
print(start_time, arrival_time, distance_time)
|
||||
seat = j
|
||||
try:
|
||||
ticket_num = int(ticket_info[j])
|
||||
|
@ -160,8 +160,8 @@ class query:
|
|||
"status": True,
|
||||
}
|
||||
else:
|
||||
print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
|
||||
return {"code": ticket.FAIL_CODE, "status": False}
|
||||
print(u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket))
|
||||
return {"code": ticket.FAIL_CODE, "status": False, "cdn": self.httpClint.cdn,}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -45,7 +45,7 @@ class queryOrderWaitTime:
|
|||
raise ticketIsExitsException(ticket.WAIT_ORDER_SUCCESS.format(
|
||||
data.get("orderId")))
|
||||
elif data.get("msg", False):
|
||||
print data.get("msg", "")
|
||||
print(data.get("msg", ""))
|
||||
break
|
||||
elif data.get("waitTime", False):
|
||||
print(ticket.WAIT_ORDER_CONTINUE.format(0 - data.get("waitTime", False)))
|
||||
|
@ -83,7 +83,7 @@ class queryOrderWaitTime:
|
|||
queryMyOrderNoCompleteResult["data"]["orderCacheDTO"]["message"]["message"])
|
||||
else:
|
||||
if queryMyOrderNoCompleteResult.get("message", False):
|
||||
print queryMyOrderNoCompleteResult.get("message", False)
|
||||
print(queryMyOrderNoCompleteResult.get("message", False))
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -5,7 +5,6 @@ from collections import OrderedDict
|
|||
from time import sleep
|
||||
import requests
|
||||
from config import logger
|
||||
import wrapcache
|
||||
|
||||
|
||||
def _set_header_default():
|
||||
|
@ -27,6 +26,7 @@ class HTTPClient(object):
|
|||
"""
|
||||
self.initS()
|
||||
self._cdn = None
|
||||
self._proxies = None
|
||||
|
||||
def initS(self):
|
||||
self._s = requests.Session()
|
||||
|
@ -118,7 +118,7 @@ class HTTPClient(object):
|
|||
url_host = self._cdn
|
||||
elif is_cdn:
|
||||
if self._cdn:
|
||||
print(u"当前请求cdn为{}".format(self._cdn))
|
||||
# print(u"当前请求cdn为{}".format(self._cdn))
|
||||
url_host = self._cdn
|
||||
else:
|
||||
url_host = urls["Host"]
|
||||
|
@ -128,7 +128,10 @@ class HTTPClient(object):
|
|||
try:
|
||||
# sleep(urls["s_time"]) if "s_time" in urls else sleep(0.001)
|
||||
sleep(s_time)
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
try:
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
except:
|
||||
pass
|
||||
response = self._s.request(method=method,
|
||||
timeout=2,
|
||||
url="https://" + url_host + req_url,
|
||||
|
@ -137,11 +140,16 @@ class HTTPClient(object):
|
|||
verify=False,
|
||||
**kwargs)
|
||||
if response.status_code == 200 or response.status_code == 302:
|
||||
if urls.get("not_decode", False):
|
||||
return response.content
|
||||
if response.content:
|
||||
if is_logger:
|
||||
logger.log(
|
||||
u"出参:{0}".format(response.content))
|
||||
return json.loads(response.content) if urls["is_json"] else response.content
|
||||
if urls["is_json"]:
|
||||
return json.loads(response.content.decode() if isinstance(response.content, bytes) else response.content)
|
||||
else:
|
||||
return response.content.decode("utf8", "ignore") if isinstance(response.content, bytes) else response.content
|
||||
else:
|
||||
logger.log(
|
||||
u"url: {} 返回参数为空".format(urls["req_url"]))
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
# -*- coding=utf-8 -*-
|
||||
import httplib
|
||||
import ssl
|
||||
import urllib
|
||||
import urllib2
|
||||
import sys
|
||||
from cookielib import LWPCookieJar
|
||||
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('UTF8')
|
||||
cookiejar = LWPCookieJar()
|
||||
cookiesuppor = urllib2.HTTPCookieProcessor(cookiejar)
|
||||
opener = urllib2.build_opener(cookiesuppor, urllib2.HTTPHandler)
|
||||
urllib2.install_opener(opener)
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
|
||||
def get(url):
|
||||
try:
|
||||
request = urllib2.Request(url=url)
|
||||
request.add_header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
|
||||
request.add_header('X-Requested-With', 'xmlHttpRequest')
|
||||
request.add_header('User-Agent', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
|
||||
)
|
||||
request.add_header('Referer', 'https://kyfw.12306.cn/otn/confirmPassenger/initDc')
|
||||
request.add_header('Accept', '*/*')
|
||||
result = urllib2.urlopen(request).read()
|
||||
assert isinstance(result, object)
|
||||
return result
|
||||
except httplib.error as e:
|
||||
print e
|
||||
pass
|
||||
except urllib2.URLError as e:
|
||||
print e
|
||||
pass
|
||||
except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError:
|
||||
pass
|
||||
|
||||
|
||||
def Post(url, data):
|
||||
try:
|
||||
request = urllib2.Request(url=url, data=urllib.urlencode(data))
|
||||
# req.add_header('User-Agent', 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0')
|
||||
# request = urllib2Post.Request(ajax_url, urllib.urlencode(dc))
|
||||
request.add_header("Content-Type", "application/x-www-form-urlencoded;application/json;charset=utf-8")
|
||||
request.add_header('X-Requested-With', 'xmlHttpRequest')
|
||||
request.add_header('User-Agent', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
|
||||
)
|
||||
request.add_header('Referer', 'https://kyfw.12306.cn/otn/confirmPassenger/initDc')
|
||||
request.add_header('Accept', '*/*')
|
||||
# request.add_header('Accept-Encoding', 'gzip, deflate')
|
||||
for i in range(3):
|
||||
result = urllib2.urlopen(request).read()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
print("返回结果为空,正在第{0}重试".format(i))
|
||||
except httplib.error as e:
|
||||
return e
|
||||
except urllib2.URLError as e:
|
||||
return e
|
||||
except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError:
|
||||
return ('error')
|
Loading…
Reference in New Issue