Python脚本实现12306火车票查询系统


Posted in Python onSeptember 30, 2016

最近我看到看到使用python实现火车票查询,我自己也实现了,感觉收获蛮多的,下面我就把每一步骤都详细给分享出来。(注意使用的是python3)

首先我将最终结果给展示出来:

在cmd命令行执行:python tickets.py -dk shanghai chengdu 20161007 > result.txt

Python脚本实现12306火车票查询系统

意思是:查询 上海--成都 2016.10.07 的D和K开头的列车信息,并保存到 result.txt文件中;下面就是result.txt文件中的结果:

Python脚本实现12306火车票查询系统

下面的将是实现步骤:

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 是可以随便写的,不影响解析

最终打印的结果是一个字典,方便后面使用:

Python脚本实现12306火车票查询系统

3、获取列车的信息

我们在12306的余票查询的接口:

url:https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2016-10-05&from_station=CDW&to_station=SHH

方法为: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文件的内容:

Python脚本实现12306火车票查询系统

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火车票查询系统,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python中转换角度为弧度的radians()方法
May 18 Python
浅析Python中的join()方法的使用
May 19 Python
在CentOS上配置Nginx+Gunicorn+Python+Flask环境的教程
Jun 07 Python
python读取txt文件中特定位置字符的方法
Dec 24 Python
Python设计模式之原型模式实例详解
Jan 18 Python
Python求一批字符串的最长公共前缀算法示例
Mar 02 Python
关于Python3 类方法、静态方法新解
Aug 30 Python
使用python3批量下载rbsp数据的示例代码
Dec 20 Python
Python3 解决读取中文文件txt编码的问题
Dec 20 Python
PyCharm 在Windows的有用快捷键详解
Apr 07 Python
python Matplotlib基础--如何添加文本和标注
Jan 26 Python
Pygame Draw绘图函数的具体使用
Nov 17 Python
Python ldap实现登录实例代码
Sep 30 #Python
python之Socket网络编程详解
Sep 29 #Python
python 排序算法总结及实例详解
Sep 28 #Python
一些常用的Python爬虫技巧汇总
Sep 28 #Python
Python三级目录展示的实现方法
Sep 28 #Python
Python黑帽编程 3.4 跨越VLAN详解
Sep 28 #Python
python 采集中文乱码问题的完美解决方法
Sep 27 #Python
You might like
生成ubuntu自动切换壁纸xml文件的php代码
2010/07/17 PHP
php实现图片添加描边字和马赛克的方法
2014/12/10 PHP
PHP面向对象程序设计组合模式与装饰模式详解
2016/12/02 PHP
PHP简单实现合并2个数字键数组值的方法
2017/05/30 PHP
laravel 框架结合关联查询 when()用法分析
2019/11/22 PHP
Yii框架小部件(Widgets)用法实例详解
2020/05/15 PHP
在IE模态窗口中自由查看HTML源码的方法
2007/03/08 Javascript
javascript下阻止表单重复提交、防刷新、防后退
2007/08/17 Javascript
jQuery中val()方法用法实例
2014/12/25 Javascript
JS导出PDF插件的方法(支持中文、图片使用路径)
2016/07/12 Javascript
JS判断输入字符串长度实例代码(汉字算两个字符,字母数字算一个)
2016/08/02 Javascript
jQuery实现ToolTip元素定位显示功能示例
2016/11/23 Javascript
了解VUE的render函数的使用
2017/06/08 Javascript
详解vuejs之v-for列表渲染
2017/06/22 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
vue组件实现文字居中对齐的方法
2017/08/23 Javascript
详解wow.js中各种特效对应的类名
2017/09/13 Javascript
详解Javascript中new()到底做了些什么?
2018/03/29 Javascript
vue2.0使用v-for循环制作多级嵌套菜单栏
2018/06/25 Javascript
JavaScript内置对象math,global功能与用法实例分析
2019/06/10 Javascript
[43:51]2014 DOTA2国际邀请赛中国区预选赛 Dream Times VS TongFu
2014/05/22 DOTA
Python中的类学习笔记
2014/09/23 Python
使用Python中的tkinter模块作图的方法
2017/02/07 Python
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
django框架模板中定义变量(set variable in django template)的方法分析
2019/06/24 Python
Python bisect模块原理及常见实例
2020/06/17 Python
详解Django中的FBV和CBV对比分析
2021/03/01 Python
美国二手复古奢侈品包包购物网站:LXRandCo
2019/06/18 全球购物
Clos19英国:高档香槟、葡萄酒和烈酒在线购物平台
2020/07/10 全球购物
Linux操作面试题
2012/05/16 面试题
飞越疯人院观后感
2015/06/09 职场文书
个人催款函范文
2015/06/23 职场文书
读《工匠精神》有感:热爱工作,精益求精
2019/12/28 职场文书
css3应用示例:新增的选择器
2022/03/16 HTML / CSS
特别篇动画《总之就是非常可爱 ~制服~》PV公开,2022年夏季播出
2022/04/04 日漫
centos7安装mysql5.7经验记录
2022/05/02 Servers