python火车余票查询(s5)

"""
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() 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值