"""
Train Ticket Query
Usage:
s5.py <from> <to> <from_date> [--con=1]
Options:
-h,--help 显示帮助菜单
--con=<kn> 连续查询天数 [default:1]
Example:
s5.py xian beijing 2018-01-01 --con=3
"""
import datetime#时间
import re#正则表达式
import requests#抓包
import sys
from docopt import docopt
from prettytable import PrettyTable
from stationapi1 import *
from colorama import Fore,Back,init,Style
from requests.packages.urllib3.exceptions import InsecureRequestWarning
#禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
#获取城市所有车站列表
url_station = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9037'
stations = get_stations(url_station)
#获取出发车站
def get_from_station(from_station,stations):
while True:
if station_valid(from_station,stations):
from_station = prase_station(from_station,stations)
return from_station
#else:
print('出发车站出错,请重新输入:')
from_station = input("出发车站出错,请重新输入:")
#获取到达车站
def get_to_station(from_station,to_station,stations):
while True:
if station_valid(to_station,stations):
to_station = prase_station(to_station,stations)
#检测出发车站与到达车站相同的情况,判断输入的车站信息是否重复,不重复继续,重复的话则从头开始
if from_station==to_station:
print("出发车站与到达车站相同")
continue
else:
return to_station
else:
to_station = input("请重新输入到达车站:")
#获取出发日期
def get_from_date(from_date):
while True:
rdate = re.match(r'^(\d{4})-(\d{2})-(\d{2})$',from_date)#正则表达式(输入日期的格式)
if rdate:
year = int(from_date[0:4])
month = int(from_date[5:7])
day = int(from_date[8:10])
try:
queryday = datetime.date(year,month,day)#整合成规定的日期格式,同事还进行了日期是否合规的判断
except ValueError:
from_date = input("输入的日期不存在,亲你穿越了,请重新输入:")
continue
lastday = datetime.date.today() + datetime.timedelta(days=15)#前后变化15天
#是否在这个范围内
if queryday >= datetime.date.today() and queryday <= lastday:
return from_date#结果
else:
from_date = input("输入日期范围有误,请重新输入:")
else:
from_date = input("输入日期格式有误,请重新输入:")
continue
#获取期望连续查询的天数
def get_days(from_date,mdays):
while True:
#mdays = input("请输入连续查询天数:")
from_day = datetime.date(int(from_date[:4]),int(from_date[5:7]),int(from_date[8:]))
lastday = datetime.date.today() + datetime.timedelta(days=15)
if from_day > lastday-datetime.timedelta(days=int(mdays)):
mdays = input("连续查询日期超出了所能查询的范围,请重新输入:")
else:
return int(mdays)
#执行查询过程,输入查询条件,得到车票信息列表
def query(condition):
url_ticket = "https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT".format(condition[2],condition[0],condition[1])
#尝试进行这个操作,如果失败则进行except
try:
tickethtml = requests.get(url_ticket)
ticket_list = tickethtml.json()['data']['result']#json格式的词典
return ticket_list
except:
print('网络已飞往月球,请稍后再试试哈~')
sys.exit()
return ticket_list
#分析每个车次中的座位情况,得出要显示的车票信息
def analyze(ticket_list,stations):
tickets=[]
for t in ticket_list:
ta = t.split('|')
if ta[0]=='null':
continue
train_no = ta[2]
checi = ta[3]
shifazhan = ta[4]
zhongdianzhan = ta[5]
chufazhan = ta[6]
daodazhan = ta[7]
chufashijian = ta[8]
daodashijian = ta[9]
lishi = ta[10]
facheriqi = ta[13]
from_station_no = ta[16]
to_station_no = ta[17]
shangwuzuo = ta[25] or ta[32]
yidengzuo = ta[31]
erdengzuo = ta[30]
ruanwo = ta[23]
yingwo = ta[28]
yingzuo = ta[29]
dongwo = ta[33]
seat_types = ta[35]
#出发、到达车站及出发、到达时间
station = '\n'.join([Fore.GREEN+stations[chufazhan][1]+Fore.RESET,Fore.RED+stations[daodazhan][1]+Fore.RESET])
qtime = '\n'.join([Fore.GREEN+chufashijian+Fore.RESET,Fore.RED+daodashijian+Fore.RESET])
tickets.append([checi,station,qtime,lishi,shangwuzuo,yidengzuo,erdengzuo,ruanwo,dongwo,yingwo,yingzuo])
return tickets
#显示查询结果
def display(tickets):
init(autoreset=True)
ptable = PrettyTable('车次 车站 时间 历时 商务座 一等座 二等座 软卧 动卧 硬卧 硬座'.split(' '))
for ticket in tickets:
ptable.add_row(ticket)
print(ptable)
#输入出发车站、到达车站和出发日期
def qin(arguments):
#车站仅限西安、北京(pinyin),能查询15天内的车次信息
print("*****贺永鲜(21409030318)**********")
print("——***欢迎使用火车票查询系统py2.0*——")
print("——***本系统只支持查询十五天内的火车票信息***——")
from_station = get_from_station(arguments['<from>'],stations)
to_station = get_to_station(from_station,arguments['<to>'],stations)
from_date = get_from_date(arguments['<from_date>'])
#需要查询的是几天内的车站信息
days = get_days(from_date,arguments['--con'])
require=[from_station,to_station,from_date,days]
return require
def cli():
arguments=docopt(__doc__)
print(arguments)
#将出发车站、到达车站、出发日期及查询天数打包为一个列表condition,输入查询条件
condition = qin(arguments)
mdate = datetime.date(int(condition[2][:4]),int(condition[2][5:7]),int(condition[2][8:]))
print(mdate)
for i in range(int(condition[3])):
#执行查询
ndate = mdate + datetime.timedelta(days=1)
condition[2] = str(ndate)
print(condition[2])#打印出来的日期
ticketinfo_list = query(condition)
tickets = analyze(ticketinfo_list,stations)
#输出查询结果
display(tickets)
if __name__ == '__main__':
cli()
python火车余票查询(s5)
最新推荐文章于 2022-10-11 20:02:00 发布