时间:2021-07-01 10:21:17 帮助过:242人阅读
首先我将最终结果给展示出来:
在cmd命令行执行:python tickets.py -dk shanghai chengdu 20161007 > result.txt
意思是:查询 上海--成都 2016.10.07 的D和K开头的列车信息,并保存到 result.txt文件中;下面就是result.txt文件中的结果:
下面的将是实现步骤:
1、安装第三方库 pip install 安装:requests,docopt,prettytable
2、docopt可以用来解析从命令行中输入的参数:
- """
- Usage:
- test [-gdtkz] <from> <to> <date>
- Options:
- -h,--help 显示帮助菜单
- -g 高铁
- -d 动车
- -t 特快
- -k 快速
- -z 直达
- Example:
- tickets -gdt beijing shanghai 2016-08-25
- """
- import docopt
- args = docopt.docopt(__doc__)
- print(args)
- # 上面 """ """ 包含中的:
- #Usage:
- # test [-gdtkz] <from> <to> <date>
- #是必须要的 test 是可以随便写的,不影响解析
最终打印的结果是一个字典,方便后面使用:
3、获取列车的信息
我们在12306的余票查询的接口:
url: 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8968'
方法为:get
传输的参数:queryDate:2016-10-05、from_station:CDW、to_station:SHH
其中城市对应简称是需要另外的接口查询得出
3.1 查询城市对应的简称:
这个接口的url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8968'
方法是get,对返回结果利用正则表达式,取出城市名和简称的值(返回的值类似:7@cqn|重庆南|CRW|chongqingnan|cqn|,我们需要的就是:CRW、chongqingnan),代码如下
parse_stations.py:
- #coding=utf-8
- from prettytable import PrettyTable
- class TrainCollection(object):
- """
- 解析列车信息
- """
- # 显示车次、出发/到达站、 出发/到达时间、历时、一等坐、二等坐、软卧、硬卧、硬座
- header = '序号 车次 出发站/到达站 出发时间/到达时间 历时 商务座 一等座 二等座 软卧 硬卧 硬座 无座'.split()
- def __init__(self,rows,traintypes):
- self.rows = rows
- self.traintypes = traintypes
- def _get_duration(self,row):
- """
- 获取车次运行的时间
- """
- duration = row.get('lishi').replace(':','小时') + '分'
- if duration.startswith('00'):
- return duration[4:]
- elif duration.startswith('0'):
- return duration[1:]
- return duration
- @property
- def trains(self):
- result = []
- flag = 0
- for row in self.rows:
- if row['station_train_code'][0] in self.traintypes:
- flag += 1
- train = [
- # 序号
- flag,
- # 车次
- row['station_train_code'],
- # 出发、到达站点
- '/'.join([row['from_station_name'],row['to_station_name']]),
- # 成功、到达时间
- '/'.join([row['start_time'],row['arrive_time']]),
- # duration 时间
- self._get_duration(row),
- # 商务座
- row['swz_num'],
- # 一等座
- row['zy_num'],
- # 二等座
- row['ze_num'],
- # 软卧
- row['rw_num'],
- # 硬卧
- row['yw_num'],
- # 硬座
- row['yz_num'],
- # 无座
- row['wz_num']
- ]
- result.append(train)
- return result
- def print_pretty(self):
- """打印列车信息"""
- pt = PrettyTable()
- pt._set_field_names(self.header)
- for train in self.trains:
- pt.add_row(train)
- print(pt)
- if __name__ == '__main__':
- t = TrainCollection()
其中pprint这个模块能是打印出来的信息,更加方便阅读:
在cmd中运行:python parse_stations.py > stations.py
就会在当前目录下得到stations.py文件,文件中就是站点名字和简称,在stations.py文件中加入"stations = "这样就是一个字典,方便后面的取值,下面就是stations.py文件的内容:
3.2 现在获取列车信息的参数已经准备齐了,接下来就是拿到列车的返回值,解析出自己需要的信息,比如:车次号,一等座的票数等等。。,myprettytable.py
- #coding=utf-8
- from prettytable import PrettyTable
- class TrainCollection(object):
- """
- 解析列车信息
- """
- # 显示车次、出发/到达站、 出发/到达时间、历时、一等坐、二等坐、软卧、硬卧、硬座
- header = '序号 车次 出发站/到达站 出发时间/到达时间 历时 商务座 一等座 二等座 软卧 硬卧 硬座 无座'.split()
- def __init__(self,rows,traintypes):
- self.rows = rows
- self.traintypes = traintypes
- def _get_duration(self,row):
- """
- 获取车次运行的时间
- """
- duration = row.get('lishi').replace(':','小时') + '分'
- if duration.startswith('00'):
- return duration[4:]
- elif duration.startswith('0'):
- return duration[1:]
- return duration
- @property
- def trains(self):
- result = []
- flag = 0
- for row in self.rows:
- if row['station_train_code'][0] in self.traintypes:
- flag += 1
- train = [
- # 序号
- flag,
- # 车次
- row['station_train_code'],
- # 出发、到达站点
- '/'.join([row['from_station_name'],row['to_station_name']]),
- # 成功、到达时间
- '/'.join([row['start_time'],row['arrive_time']]),
- # duration 时间
- self._get_duration(row),
- # 商务座
- row['swz_num'],
- # 一等座
- row['zy_num'],
- # 二等座
- row['ze_num'],
- # 软卧
- row['rw_num'],
- # 硬卧
- row['yw_num'],
- # 硬座
- row['yz_num'],
- # 无座
- row['wz_num']
- ]
- result.append(train)
- return result
- def print_pretty(self):
- """打印列车信息"""
- pt = PrettyTable()
- pt._set_field_names(self.header)
- for train in self.trains:
- pt.add_row(train)
- print(pt)
- if __name__ == '__main__':
- t = TrainCollection()
prettytable 这个库是能打印出类似mysql查询数据显示出来的格式,
4、接下来就是整合各个模块:tickets.py
- """Train tickets query via command-line.
- Usage:
- tickets [-gdtkz] <from> <to> <date>
- Options:
- -h,--help 显示帮助菜单
- -g 高铁
- -d 动车
- -t 特快
- -k 快速
- -z 直达
- Example:
- tickets -gdt beijing shanghai 2016-08-25
- """
- import requests
- from docopt import docopt
- from stations import stations
- # from pprint import pprint
- from myprettytable import TrainCollection
- class SelectTrain(object):
- def __init__(self):
- """
- 获取命令行输入的参数
- """
- self.args = docopt(__doc__)#这个是获取命令行的所有参数,返回的是一个字典
- def cli(self):
- """command-line interface"""
- # 获取 出发站点和目标站点
- from_station = stations.get(self.args['<from>']) #出发站点
- to_station = stations.get(self.args['<to>']) # 目的站点
- leave_time = self._get_leave_time()# 出发时间
- url = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={0}&from_station={1}&to_station={2}'.format(
- leave_time,from_station,to_station)# 拼接请求列车信息的Url
- # 获取列车查询结果
- r = requests.get(url,verify=False)
- traindatas = r.json()['data']['datas'] # 返回的结果,转化成json格式,取出datas,方便后面解析列车信息用
- # 解析列车信息
- traintypes = self._get_traintype()
- views = TrainCollection(traindatas,traintypes)
- views.print_pretty()
- def _get_traintype(self):
- """
- 获取列车型号,这个函数的作用是的目的是:当你输入 -g 是只是返回 高铁,输入 -gd 返回动车和高铁,当不输参数时,返回所有的列车信息
- """
- traintypes = ['-g','-d','-t','-k','-z']
- # result = []
- # for traintype in traintypes:
- # if self.args[traintype]:
- # result.append(traintype[-1].upper())
- trains = [traintype[-1].upper() for traintype in traintypes if self.args[traintype]]
- if trains:
- return trains
- else:
- return ['G','D','T','K','Z']
- def _get_leave_time(self):
- """
- 获取出发时间,这个函数的作用是为了:时间可以输入两种格式:2016-10-05、20161005
- """
- leave_time = self.args['<date>']
- if len(leave_time) == 8:
- return '{0}-{1}-{2}'.format(leave_time[:4],leave_time[4:6],leave_time[6:])
- if '-' in leave_time:
- return leave_time
- if __name__ == '__main__':
- cli = SelectTrain()
- cli.cli()
好了,基本上就结束了,按照开头的哪样,就能查询你想要的车次信息了
以上所述是小编给大家介绍的Python脚本实现12306火车票查询系统,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对PHP中文网的支持!
更多Python实现12306火车票查询系统相关文章请关注PHP中文网!