火车票命令查看器
Posted by pg 2018-01-11
环境配置
1.系统环境:win7 64位
2.编译环境:Python3.4
3.依赖库: docopt requests prettytable colorama
4.其他工具:浏览器
使用方式
serachTicket [-gdtkz] <from> <to> <date>
- <>内必填
- []内选填,不填默认全部
- 原文出处是在github上down下来的,不过已经失效,对应的座位信息已改变顺序,稍加修改便可以使用,下面是修改正确的部分,认识到代码的时效性,尤其是爬虫之类的,随着网站更新换代,代码也要随之改变。
demo:
#-*- coding:utf-8 -*-
"""命令行火车票查看器
Usage:
serachTicket [-gdtkz] <from> <to> <date>
"""
from docopt import docopt
from stations import stations
import requests
from prettytable import PrettyTable
from colorama import init, Fore
init()
class TrainsCollection:
header = '车次 车站 时间 历时 商务特等 一等 二等 高级软卧 软卧 硬卧 硬座 无座'.split()
def __init__(self, available_trains,available_place, options):
"""查询的火车班次集合
:param available_trains: 一个列表, 包含可获得的火车班次, 每个
火车班次是一个字典
:param options: 查询的选项, 如高铁, 动车, etc...
"""
self.available_trains = available_trains
self.available_place = available_place
self.options = options
@property
def trains(self):
for raw_train in self.available_trains:
raw_train_list = raw_train.split('|')
train_no = raw_train_list[3]
initial = train_no[0].lower()
duration = raw_train_list[10]
if initial in self.options:
train = [
train_no,
'\n'.join([Fore.LIGHTGREEN_EX + self.available_place[raw_train_list[6]] + Fore.RESET,
Fore.LIGHTRED_EX + self.available_place[raw_train_list[7]] + Fore.RESET]),
'\n'.join([Fore.LIGHTGREEN_EX + raw_train_list[8] + Fore.RESET,
Fore.LIGHTRED_EX + raw_train_list[9] + Fore.RESET]),
duration,
raw_train_list[-5] if raw_train_list[-5] else '--',
raw_train_list[-6] if raw_train_list[-6] else '--',
raw_train_list[-7] if raw_train_list[-7] else '--',
raw_train_list[-16] if raw_train_list[-16] else '--',
raw_train_list[-14] if raw_train_list[-14] else '--',
raw_train_list[-9] if raw_train_list[-9] else '--',
raw_train_list[-8] if raw_train_list[-8] else '--',
raw_train_list[-11] if raw_train_list[-11] else '--',
]
yield train
else:
train = [
train_no,
'\n'.join([Fore.LIGHTGREEN_EX + self.available_place[raw_train_list[6]] + Fore.RESET,
Fore.LIGHTRED_EX + self.available_place[raw_train_list[7]] + Fore.RESET]),
'\n'.join([Fore.LIGHTGREEN_EX + raw_train_list[8] + Fore.RESET,
Fore.LIGHTRED_EX + raw_train_list[9] + Fore.RESET]),
duration,
raw_train_list[-5] if raw_train_list[-5] else '--',
raw_train_list[-6] if raw_train_list[-6] else '--',
raw_train_list[-7] if raw_train_list[-7] else '--',
raw_train_list[-16] if raw_train_list[-16] else '--',
raw_train_list[-14] if raw_train_list[-14] else '--',
raw_train_list[-9] if raw_train_list[-9] else '--',
raw_train_list[-8] if raw_train_list[-8] else '--',
raw_train_list[-11] if raw_train_list[-11] else '--',
]
yield train
def pretty_print(self):
pt = PrettyTable()
pt._set_field_names(self.header)
for train in self.trains:
pt.add_row(train)
print(pt)
def cli():
"""command-line interface"""
arguments = docopt(__doc__)
from_station = stations.get(arguments['<from>'])
to_station = stations.get(arguments['<to>'])
date = arguments['<date>']
url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(date,from_station,to_station)
r = requests.get(url, verify=False)
available_trains = r.json()['data']['result']
available_place = r.json()['data']['map']
options = ''.join([
key for key, value in arguments.items() if value is True
])
TrainsCollection(available_trains,available_place, options).pretty_print()
if __name__ == '__main__':
cli()