- 优化已知bug

- 开启cdn查询
- 自动识别查询接口
pull/66/head
wenxianping 2018-12-26 16:05:51 +08:00
parent 75f88a4c1a
commit cf2e8f8ef6
9 changed files with 28623 additions and 959 deletions

View File

@ -58,6 +58,9 @@
- 测试邮箱是否可用 - 测试邮箱是否可用
- 测试下单接口是否可用有两个下单接口随便用哪个都ok - 测试下单接口是否可用有两个下单接口随便用哪个都ok
- 如果下载验证码过期或者下载失败的问题应该是12306封ip的策略多重试几次12306现在封服务器(阿里云和腾讯云)ip比较严重尽量不要放在服务器里面 - 如果下载验证码过期或者下载失败的问题应该是12306封ip的策略多重试几次12306现在封服务器(阿里云和腾讯云)ip比较严重尽量不要放在服务器里面
- 感谢一下小伙伴对本项目提供的帮助
- @读,◢
- @才
- [更新日志](Update.md) - [更新日志](Update.md)

View File

@ -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查询
- 自动识别查询接口

View File

@ -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:
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()

29450
cdn_list Executable file → Normal file

File diff suppressed because one or more lines are too long

View File

@ -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 = {
"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",

View File

@ -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
@ -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:
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,10 +80,11 @@ 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" \
@ -128,24 +130,15 @@ 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:
if cdn[i].replace("\n", "") not in self.cdn_list: # 如果有重复的cdn则放弃加入
print("加入cdn {0}".format(cdn[i].replace("\n", ""))) print("加入cdn {0}".format(cdn[i].replace("\n", "")))
self.cdn_list.append(cdn[i].replace("\n", "")) self.cdn_list.append(cdn[i].replace("\n", ""))
print(u"所有cdn解析完成...") print(u"所有cdn解析完成...")
@ -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")
@ -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):
@ -257,7 +251,7 @@ class select:
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:
if __name__ == '__main__': if __name__ == '__main__':
pass s = select()
cdn = CDNProxy().open_cdn_file()
s.cdn_req(cdn)

View File

@ -1,5 +1,10 @@
# 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:
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:
查询 查询
: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:
"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()

View File

@ -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):
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(

BIN
tkcode

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB