提交 cf2e8f8e 编写于 作者: W wenxianping

- 优化已知bug

- 开启cdn查询
- 自动识别查询接口
上级 75f88a4c
...@@ -58,6 +58,9 @@ ...@@ -58,6 +58,9 @@
- 测试邮箱是否可用 - 测试邮箱是否可用
- 测试下单接口是否可用,有两个下单接口,随便用哪个都ok - 测试下单接口是否可用,有两个下单接口,随便用哪个都ok
- 如果下载验证码过期或者下载失败的问题,应该是12306封ip的策略,多重试几次,12306现在封服务器(阿里云和腾讯云)ip比较严重,尽量不要放在服务器里面 - 如果下载验证码过期或者下载失败的问题,应该是12306封ip的策略,多重试几次,12306现在封服务器(阿里云和腾讯云)ip比较严重,尽量不要放在服务器里面
- 感谢一下小伙伴对本项目提供的帮助
- @读,◢
- @才
- [更新日志](Update.md) - [更新日志](Update.md)
...@@ -123,3 +123,8 @@ ...@@ -123,3 +123,8 @@
- 优化随机查询1-3秒,经测试很稳定,不会封ip - 优化随机查询1-3秒,经测试很稳定,不会封ip
- 增加余票不足优先提交功能(当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交) - 增加余票不足优先提交功能(当余票小于乘车人,如果选择优先提交,则删减联系人和余票数一致在提交)
- 开关为ticket_config.yaml配置文件中is_more_ticket参数 - 开关为ticket_config.yaml配置文件中is_more_ticket参数
- 2018.12.26更新
- 优化已知bug
- 开启cdn查询
- 自动识别查询接口
...@@ -50,8 +50,15 @@ class CDNProxy: ...@@ -50,8 +50,15 @@ class CDNProxy:
pass pass
def open_cdn_file(self): def open_cdn_file(self):
f = open("./cdn_list", "a+") cdn = []
return f cdn_re = re.compile("CONNECT (\S+) HTTP/1.1")
with open("./cdn_list", "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])
return cdn
def get_cdn_list(self): def get_cdn_list(self):
""" """
...@@ -101,9 +108,6 @@ class CDNProxy: ...@@ -101,9 +108,6 @@ class CDNProxy:
print(cdn_ip[0]) print(cdn_ip[0])
if __name__ == '__main__': if __name__ == '__main__':
cdn = CDNProxy() cdn = CDNProxy()
cdn.get_cdn_list() cdn.open_cdn_file()
此差异已折叠。
...@@ -77,6 +77,18 @@ urls = { ...@@ -77,6 +77,18 @@ urls = {
"is_logger": False, "is_logger": False,
"is_json": False, "is_json": False,
}, },
"loginInitCdn": { # 登录页面
"req_url": "/otn/login/init",
"req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/index/init",
"Host": "kyfw.12306.cn",
"re_try": 1,
"re_time": 0.1,
"s_time": 0.1,
"is_logger": False,
"is_test_cdn": True,
"is_json": False,
},
"getUserInfo": { # 获取用户信息 "getUserInfo": { # 获取用户信息
"req_url": "/otn/index/initMy12306", "req_url": "/otn/index/initMy12306",
"req_type": "get", "req_type": "get",
...@@ -156,7 +168,7 @@ urls = { ...@@ -156,7 +168,7 @@ urls = {
"is_json": True, "is_json": True,
}, },
"select_url": { # 查询余票 "select_url": { # 查询余票
"req_url": "/otn/leftTicket/queryX?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT", "req_url": "/otn/{3}?leftTicketDTO.train_date={0}&leftTicketDTO.from_station={1}&leftTicketDTO.to_station={2}&purpose_codes=ADULT",
"req_type": "get", "req_type": "get",
"Referer": "https://kyfw.12306.cn/otn/leftTicket/init", "Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
"Host": "kyfw.12306.cn", "Host": "kyfw.12306.cn",
......
...@@ -3,6 +3,7 @@ import datetime ...@@ -3,6 +3,7 @@ import datetime
import random import random
import socket import socket
import sys import sys
import threading
import time import time
import wrapcache import wrapcache
...@@ -26,7 +27,7 @@ from myException.ticketConfigException import ticketConfigException ...@@ -26,7 +27,7 @@ from myException.ticketConfigException import ticketConfigException
from myException.ticketIsExitsException import ticketIsExitsException from myException.ticketIsExitsException import ticketIsExitsException
from myException.ticketNumOutException import ticketNumOutException from myException.ticketNumOutException import ticketNumOutException
from myUrllib.httpUtils import HTTPClient from myUrllib.httpUtils import HTTPClient
from utils.timeUtil import time_to_minutes,minutes_to_time from utils.timeUtil import time_to_minutes, minutes_to_time
reload(sys) reload(sys)
sys.setdefaultencoding('utf-8') sys.setdefaultencoding('utf-8')
...@@ -42,7 +43,6 @@ class select: ...@@ -42,7 +43,6 @@ class select:
self.ticke_peoples, self.station_trains, self.ticket_black_list_time, \ 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.order_type, self.is_by_time, self.train_types, self.departure_time, \
self.arrival_time, self.take_time = self.get_ticket_info() self.arrival_time, self.take_time = self.get_ticket_info()
self.is_auto_code = _get_yaml()["is_auto_code"] self.is_auto_code = _get_yaml()["is_auto_code"]
self.auto_code_type = _get_yaml()["auto_code_type"] self.auto_code_type = _get_yaml()["auto_code_type"]
self.is_cdn = _get_yaml()["is_cdn"] self.is_cdn = _get_yaml()["is_cdn"]
...@@ -50,6 +50,7 @@ class select: ...@@ -50,6 +50,7 @@ class select:
self.urls = urlConf.urls self.urls = urlConf.urls
self.login = GoLogin(self, self.is_auto_code, self.auto_code_type) self.login = GoLogin(self, self.is_auto_code, self.auto_code_type)
self.cdn_list = [] self.cdn_list = []
self.queryUrl = "leftTicket/queryX"
self.passengerTicketStrList = "" self.passengerTicketStrList = ""
self.oldPassengerStr = "" self.oldPassengerStr = ""
self.set_type = "" self.set_type = ""
...@@ -79,12 +80,13 @@ class select: ...@@ -79,12 +80,13 @@ class select:
take_time = time_to_minutes(ticket_info_config["set"]["take_time"]) take_time = time_to_minutes(ticket_info_config["set"]["take_time"])
print u"*" * 20 print u"*" * 20
print u"12306刷票小助手,最后更新于2018.9.21,请勿作为商业用途,交流群号:286271084" print u"12306刷票小助手,最后更新于2018.12.26,请勿作为商业用途,交流群号:286271084"
if is_by_time: if is_by_time:
method_notie="购票方式:根据时间区间购票\n可接受最早出发时间:{0}\n可接受最晚抵达时间:{1}\n可接受最长旅途时间:{2}\n可接受列车类型:{3}\n"\ method_notie = "购票方式:根据时间区间购票\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)) .format(minutes_to_time(departure_time), minutes_to_time(arrival_time), minutes_to_time(take_time),
" , ".join(train_types))
else: else:
method_notie="购票方式:根据候选车次购买\n候选购买车次:{0}".format(",".join(station_trains)) method_notie = "购票方式:根据候选车次购买\n候选购买车次:{0}".format(",".join(station_trains))
print u"当前配置:\n出发站:{0}\n到达站:{1}\n乘车日期:{2}\n坐席:{3}\n是否有票优先提交:{4}\n乘车人:{5}\n" \ 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".format \ u"刷新间隔:随机(1-3S)\n{6}\n僵尸票关小黑屋时长:{7}\n 下单接口:{8}\n".format \
( (
...@@ -128,26 +130,17 @@ class select: ...@@ -128,26 +130,17 @@ class select:
else: else:
self.login.go_login() self.login.go_login()
def set_cdn(self):
"""
设置cdn
:return:
"""
if self.is_cdn == 1:
while True:
if self.cdn_list:
self.httpClint.cdn = self.cdn_list[random.randint(0, len(self.cdn_list) - 1)]
def cdn_req(self, cdn): def cdn_req(self, cdn):
for i in range(len(cdn) - 1): for i in range(len(cdn) - 1):
http = HTTPClient() http = HTTPClient()
urls = self.urls["loginInit"] urls = self.urls["loginInitCdn"]
http.cdn = cdn[i].replace("\n", "") http._cdn = cdn[i].replace("\n", "")
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
rep = http.send(urls) rep = http.send(urls)
if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 500: if rep and "message" not in rep and (datetime.datetime.now() - start_time).microseconds / 1000 < 500:
print("加入cdn {0}".format(cdn[i].replace("\n", ""))) if cdn[i].replace("\n", "") not in self.cdn_list: # 如果有重复的cdn,则放弃加入
self.cdn_list.append(cdn[i].replace("\n", "")) print("加入cdn {0}".format(cdn[i].replace("\n", "")))
self.cdn_list.append(cdn[i].replace("\n", ""))
print(u"所有cdn解析完成...") print(u"所有cdn解析完成...")
def cdn_certification(self): def cdn_certification(self):
...@@ -157,14 +150,14 @@ class select: ...@@ -157,14 +150,14 @@ class select:
""" """
if self.is_cdn == 1: if self.is_cdn == 1:
CDN = CDNProxy() CDN = CDNProxy()
all_cdn = CDN.all_cdn() all_cdn = CDN.open_cdn_file()
if all_cdn: if all_cdn:
print(u"由于12306网站策略调整,cdn功能暂时关闭。") # print(u"由于12306网站策略调整,cdn功能暂时关闭。")
# print(u"开启cdn查询") print(u"开启cdn查询")
# print(u"本次待筛选cdn总数为{}, 筛选时间大约为5-10min".format(len(all_cdn))) print(u"本次待筛选cdn总数为{}, 筛选时间大约为5-10min".format(len(all_cdn)))
# t = threading.Thread(target=self.cdn_req, args=(all_cdn,)) t = threading.Thread(target=self.cdn_req, args=(all_cdn,))
# t2 = threading.Thread(target=self.set_cdn, args=()) # t2 = threading.Thread(target=self.set_cdn, args=())
# t.start() t.start()
# t2.start() # t2.start()
else: else:
raise ticketConfigException(u"cdn列表为空,请先加载cdn") raise ticketConfigException(u"cdn列表为空,请先加载cdn")
...@@ -174,7 +167,7 @@ class select: ...@@ -174,7 +167,7 @@ class select:
l = liftTicketInit(self) l = liftTicketInit(self)
l.reqLiftTicketInit() l.reqLiftTicketInit()
self.call_login() self.call_login()
check_user = checkUser(self) check_user = checkUser(self)
check_user.sendCheckUser() check_user.sendCheckUser()
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)
num = 0 num = 0
...@@ -220,7 +213,8 @@ class select: ...@@ -220,7 +213,8 @@ class select:
print(ticket.QUEUE_WARNING_MSG.format(train_no)) print(ticket.QUEUE_WARNING_MSG.format(train_no))
else: else:
# 获取联系人 # 获取联系人
s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples, set_type=seat_conf_2[seat], s = getPassengerDTOs(session=self, ticket_peoples=self.ticke_peoples,
set_type=seat_conf_2[seat],
is_more_ticket_num=is_more_ticket_num) is_more_ticket_num=is_more_ticket_num)
getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr() getPassengerDTOsResult = s.getPassengerTicketStrListAndOldPassengerStr()
if getPassengerDTOsResult.get("status", False): if getPassengerDTOsResult.get("status", False):
...@@ -256,8 +250,8 @@ class select: ...@@ -256,8 +250,8 @@ class select:
",".join( ",".join(
self.station_trains), self.station_trains),
( (
datetime.datetime.now() - start_time).microseconds / 1000, datetime.datetime.now() - start_time).microseconds / 1000,
wrapcache.get("cdn"), queryResult.get("cdn", None),
len( len(
self.cdn_list), self.cdn_list),
random_time) random_time)
...@@ -290,4 +284,6 @@ class select: ...@@ -290,4 +284,6 @@ class select:
if __name__ == '__main__': if __name__ == '__main__':
pass s = select()
cdn = CDNProxy().open_cdn_file()
s.cdn_req(cdn)
# coding=utf-8 # coding=utf-8
import copy import copy
import threading
import time
import random
import wrapcache import wrapcache
from config import urlConf from config import urlConf
from config.TicketEnmu import ticket from config.TicketEnmu import ticket
...@@ -27,7 +32,6 @@ class query: ...@@ -27,7 +32,6 @@ class query:
self.station_dates = station_dates if isinstance(station_dates, list) else list(station_dates) self.station_dates = station_dates if isinstance(station_dates, list) else list(station_dates)
self.ticket_black_list = dict() self.ticket_black_list = dict()
self.ticke_peoples_num = ticke_peoples_num self.ticke_peoples_num = ticke_peoples_num
# by time # by time
self.is_by_time = session.is_by_time self.is_by_time = session.is_by_time
self.train_types = session.train_types self.train_types = session.train_types
...@@ -76,13 +80,19 @@ class query: ...@@ -76,13 +80,19 @@ class query:
查询 查询
:return: :return:
""" """
t1 = threading.Thread(target=self.set_cdn, args=())
t1.start()
for station_date in self.station_dates: for station_date in self.station_dates:
select_url = copy.copy(self.urls["select_url"]) select_url = copy.copy(self.urls["select_url"])
select_url["req_url"] = select_url["req_url"].format(station_date, self.from_station, self.to_station) select_url["req_url"] = select_url["req_url"].format(station_date, self.from_station, self.to_station, self.session.queryUrl)
station_ticket = self.httpClint.send(select_url) station_ticket = self.httpClint.send(select_url)
if station_ticket.get("c_url", ""):
print(station_ticket.get("c_url", ""))
self.session.queryUrl = station_ticket.get("c_url", "") # 重设查询接口
continue
value = station_ticket.get("data", "") value = station_ticket.get("data", "")
if not value: if not value:
print (u'{0}-{1} 车次坐席查询为空'.format(self.from_station_h, self.to_station_h)) print (u'{0}-{1} 车次坐席查询为空, 查询url: https://kyfw.12306.cn{2}, 可以手动查询是否有票'.format(self.from_station_h, self.to_station_h, select_url["req_url"]))
else: else:
result = value.get('result', []) result = value.get('result', [])
if result: if result:
...@@ -142,12 +152,25 @@ class query: ...@@ -142,12 +152,25 @@ class query:
"train_location": train_location, "train_location": train_location,
"code": ticket.SUCCESS_CODE, "code": ticket.SUCCESS_CODE,
"is_more_ticket_num": is_more_ticket_num, "is_more_ticket_num": is_more_ticket_num,
"cdn": self.httpClint.cdn,
"status": True, "status": True,
} }
else: else:
print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket) print u"车次配置信息有误,或者返回数据异常,请检查 {}".format(station_ticket)
return {"code": ticket.FAIL_CODE, "status": False} return {"code": ticket.FAIL_CODE, "status": False}
def set_cdn(self):
"""
设置cdn
:return:
"""
if self.session.is_cdn == 1:
while True:
if self.session.cdn_list:
self.httpClint.cdn = self.session.cdn_list[random.randint(0, len(self.session.cdn_list) - 1)]
else:
time.sleep(0.05)
if __name__ == "__main__": if __name__ == "__main__":
q = query() q = query()
...@@ -117,9 +117,8 @@ class HTTPClient(object): ...@@ -117,9 +117,8 @@ class HTTPClient(object):
if is_test_cdn: if is_test_cdn:
url_host = self._cdn url_host = self._cdn
elif is_cdn: elif is_cdn:
cdn = wrapcache.get("cdn") if self._cdn:
if cdn: url_host = self._cdn
url_host = cdn
else: else:
url_host = urls["Host"] url_host = urls["Host"]
else: else:
...@@ -136,7 +135,7 @@ class HTTPClient(object): ...@@ -136,7 +135,7 @@ class HTTPClient(object):
allow_redirects=allow_redirects, allow_redirects=allow_redirects,
verify=False, verify=False,
**kwargs) **kwargs)
if response.status_code == 200: if response.status_code == 200 or response.status_code == 302:
if response.content: if response.content:
if is_logger: if is_logger:
logger.log( logger.log(
......
无法预览此类型文件
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册