前几天看了一个爬取12306来获得火车票信息的教程,发现12306官网的存储车票信息的 Json 数据格式已经变了,导致这篇教程的代码已经没法继续使用了,因此我针对新的格式重新进行了解析,最后达到了目的。在此记录一下整个过程。
01/11/2018 更新:12306 更改了保存着余票信息的网址,有同学反映之前的代码运行会出错,于是我修改了一下代码,现在可以正常运行了。最新的代码在 GitHub 上,地址在文末倒数第二行。
先看一下最终效果吧
最终效果
只需要输入查询细节,就可以输出你想查询的车票信息,而且界面一目了然。
接口设计
用户在使用这个工具的时候,需要输入1.车次类型2.始发站3.终点站以及4.日期。火车有很多类型,可以大致分为如下几种:
-g 高铁
-d 动车
-t 特快
-k 快车
-z 直达
我们需要的接口就是刚刚提到的 4 种,因此接口看起来应该是这个样子
$ python tickets.py [-gdtkz] from to date
其中,tickets.py 是这个程序的名字,-gdtkz 是车次类型,from 是始发站,to 是终点站,date 是日期,用户在使用时需要填入这几个信息。
需要的库
requests 使用 Python 访问 HTTP 资源
docopt Python3 命令行解析工具
prettytable 格式化信息打印工具,见过过 MySQL 打印数据的界面吧
colorama 命令行着色工具
最方便的下载方式还是pip,如果觉得pip的下载速度太慢可以参考这篇文章解决:更换 pip 源
解析参数
# coding: utf-8
"""命令行火车票查看器
Usage:
tickets [-gdtkz]
Options:
-h,--help 显示帮助菜单
-g 高铁
-d 动车
-t 特快
-k 快速
-z 直达
Example:
tickets 武汉 上海 2017-11-20
tickets -dg 北京 南京 2017-11-20
"""
from docopt import docopt
def cli():
"""command-line interface"""
arguments = docopt(__doc__)
print(arguments)
if __name__ == '__main__':
cli()
上面的程序中,docopt会根据我们在程序开头定义的格式自动解析出参数并返回一个字典,也就是arguments,然后打印出这个字典的内容。
运行一下这个程序,比如查询一下11月20号从武汉到十堰的动车和快车,可以得到解析的结果如下所示,这和我们的接口是对应的
演示
获取数据
整个过程的关键是从 12306 获取数据和解析数据。
打开 12306 官网