为方便查询12306的火车票信息,在此用python写了一个小工具,主要用到了docopt、requests、re、prettytable几个模块。其中:
docopt模块作用是创建一个简洁漂亮的命令行交互界面,区别于sys.argv;
requests模块作用是实现http请求,区别于urllib、urllib2等模块;
re模块作用是正则表达匹配,用于匹配中文字符;
prettytable模块作用是创建一个简单直视的表格,用于打印火车票信息。

1.docopt命令行交互

"""
Usage:12306.py <from> <to> <date>12306.py (-h|--help)Options:-h,--help            show this helpExample:12306.py 青岛 苏州北 2016-10-05
"""
from docopt import docopt
if __name__ == "__main__":argu = docopt(__doc__)print argu

以上就是我们脚本的命令行交互信息,当执行命令格式有误时,会打印此信息。
如:

root@yanggd-OptiPlex-380:~/python# python 12306.py 青岛
Usage:12306.py <from> <to> <date>12306.py (-h|--help)
root@yanggd-OptiPlex-380:~/python# python 12306.py -h
Usage:12306.py <from> <to> <date>12306.py (-h|--help)Options:-h,--help            show this helpExample:12306.py 青岛 苏州北 2016-10-05

注意:
(1).Usage和Options之间必须有空行,否则Options中的内容会全部当做变量
(2).Usage中命令行格式必须是此命令的全部运行方式,否则当运行到没有定义的格式时会打印help信息
(3).Options中的可选参数后面应该用2个以上的空格,不要用tab,否则会报错
(4).Options中的可选参数应该空2个格,否则会有问题

2.http请求
通过分析12306的查票过程,如下图:

从上图我们可以得到以下信息:
访问链接为”https://kyfw.12306.cn/otn/leftTicket/log?leftTicketDTO.train_date=2016-10-14&leftTicketDTO.from_station=QDK&leftTicketDTO.to_station=OHH&purpose_codes=ADULT“,对应的站点信息为QDK、QHH,可见站点信息被对应的站点代码所代替,并且数据响应返回的格式为json。
再从站点源码中仔细查看,发现站点对应的代码链接”https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8955“。

因此,我们需要先获得每个站点对应的代码信息:

 station_code_url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8955"#去除https访问的警告信息requests.packages.urllib3.disable_warnings()r = requests.get(station_code_url, verify=False)station_code_html = r.textstation_code = re.findall(u'([\u4e00-\u9fa5]+)\|([A-Z]+)', station_code_html)station_code_dict = dict(station_code)source = station_code_dict.get(argu['<from>'].decode("utf-8"))des = station_code_dict.get(argu['<to>'].decode("utf-8"))

其中,我们利用re,通过中文字符对应的unicode字符为’([\u4e00-\u9fa5]+)|([A-Z]+)’来正则匹配站点对应代码的中文字符,然后将站点、代码初始化成字典的格式。
注意:由于站点以unicode字符存于字典中,因此当我们从命令行中读取到中文站点时,需要先decode成unicode的格式,才能在字典中匹配到对应的站点,进而得到站点的代码。

3.打印车票信息
由于查询到的数据以json格式输出,因此我们需要requests模块获取到json串,然后通过prettytable来格式化输出车票信息,方便我们能够直视

query_url = "https://kyfw.12306.cn/otn/leftTicket/queryT?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT".format(date, source, des)table = PrettyTable(["车次", "出发站", "到达站", "出发时间", "到达时间", "历时", "商务座", "特等座", "一等座", "二等座", "高级软卧", "软卧", "硬
卧", "软座", "硬座", "无座", "其他"])r2 = requests.get(query_url, verify=False)for info in r2.json()["data"]:detail = info["queryLeftNewDTO"]table.add_row([detail["station_train_code"], detail["start_station_name"], detail["to_station_name"], detail["start_time"], detail["arrive_time"], detail["lishi"], detail["swz_num"], detail["tz_num"], detail["zy_num"], detail["ze_num"], detail["gr_num"], detail["rw_num"], detail["yw_num"], detail["rz_num"], detail["yz_num"], detail["wz_num"], detail["qt_num"]])#打印车次信息print table

最后的代码为:

#!/usr/bin/env python
#-*- coding: utf-8 -*-"""
Usage:12306.py <from> <to> <date>12306.py (-h|--help)Options:-h,--help            show this helpExample:12306.py 青岛 苏州北 2016-10-05
"""import re
import requests
from docopt import docopt
from prettytable import PrettyTableif __name__ == "__main__":argu = docopt(__doc__)station_code_url = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8955"#去除https访问的警告信息requests.packages.urllib3.disable_warnings()r = requests.get(station_code_url, verify=False)station_code_html = r.text#过滤中文字符station_code = re.findall(u'([\u4e00-\u9fa5]+)\|([A-Z]+)', station_code_html)station_code_dict = dict(station_code)#获取站点的代码source = station_code_dict.get(argu['<from>'].decode("utf-8"))des = station_code_dict.get(argu['<to>'].decode("utf-8"))date = argu['<date>']query_url = "https://kyfw.12306.cn/otn/leftTicket/queryT?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT".format(date, source, des)table = PrettyTable(["车次", "出发站", "到达站", "出发时间", "到达时间", "历时", "商务座", "特等座", "一等座", "二等座", "高级软卧", "软卧", "硬
卧", "软座", "硬座", "无座", "其他"])r2 = requests.get(query_url, verify=False)for info in r2.json()["data"]:detail = info["queryLeftNewDTO"]table.add_row([detail["station_train_code"], detail["start_station_name"], detail["to_station_name"], detail["start_time"], detail["arrive_time"], detail["lishi"], detail["swz_num"], detail["tz_num"], detail["zy_num"], detail["ze_num"], detail["gr_num"], detail["rw_num"], detail["yw_num"], detail["rz_num"], detail["yz_num"], detail["wz_num"], detail["qt_num"]])#打印车次信息print table

查询结果为:

root@yanggd-OptiPlex-380:~/python# python 12306.py 青岛 北京 2016-10-10
+------+--------+--------+----------+----------+-------+--------+--------+--------+--------+----------+------+------+------+------+------+------+
| 车次 | 出发站 | 到达站 | 出发时间 | 到达时间 |  历时 | 商务座 | 特等座 | 一等座 | 二等座 | 高级软卧 | 软卧 | 硬卧 | 软座 | 硬座 | 无座 | 其他 |
+------+--------+--------+----------+----------+-------+--------+--------+--------+--------+----------+------+------+------+------+------+------+
| G178 |  青岛  | 北京南 |  07:02   |  11:51   | 04:49 |   4    |   --   |   无   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G180 |  青岛  | 北京南 |  07:10   |  12:01   | 04:51 |   1    |   --   |   无   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G182 |  青岛  | 北京南 |  08:20   |  12:58   | 04:38 |   8    |   --   |   无   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G184 |  青岛  | 北京南 |  09:29   |  14:18   | 04:49 |   5    |   --   |   有   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G186 |  青岛  | 北京南 |  10:22   |  15:14   | 04:52 |   13   |   --   |   有   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G188 |  青岛  | 北京南 |  11:27   |  16:22   | 04:55 |   2    |   --   |   无   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G190 |  青岛  | 北京南 |  12:14   |  17:05   | 04:51 |   6    |   --   |   12   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G192 |  青岛  | 北京南 |  12:32   |  17:17   | 04:45 |   17   |   --   |   有   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G194 |  青岛  | 北京南 |  14:30   |  19:18   | 04:48 |   18   |   --   |   有   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G196 |  青岛  | 北京南 |  16:00   |  20:40   | 04:40 |   有   |   --   |   有   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G198 |  青岛  | 北京南 |  17:11   |  22:02   | 04:51 |   20   |   --   |   有   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
| G200 |  青岛  | 北京南 |  18:35   |  23:38   | 05:03 |   3    |   --   |   14   |   有   |    --    |  --  |  --  |  --  |  --  |  --  |  --  |
|  Z8  | 青岛北 |  北京  |  21:00   |  06:10   | 09:10 |   --   |   --   |   --   |   --   |    --    |  有  |  --  |  无  |  --  |  --  |  --  |
+------+--------+--------+----------+----------+-------+--------+--------+--------+--------+----------+------+------+------+------+------+------+

python实现12306查询火车票相关推荐

  1. python刷火车票脚本_使用python脚本实现查询火车票工具

    使用python脚本实现查询火车票信息的效果图如下: 实现的代码: # coding: utf-8 """命令行火车票查看器 Usage: tickets [-gdtkz ...

  2. python识别火车票二维码_使用python脚本实现查询火车票工具

    使用python脚本实现查询火车票信息的效果图如下: 实现的代码: # coding: utf-8 """命令行火车票查看器 Usage: tickets [-gdtkz ...

  3. python爬虫——12306查询车次

    python爬虫--12306查询车次 使用抓包工具 中文地名转地名参数代码 使用12306提供的查询api进行查询 实现完整代码 使用抓包工具 首先登陆12306 点击查询:同时使用network抓 ...

  4. python查火车票_使用python制作查询火车票工具

    使用python脚本实现查询火车票信息的效果图如下: 实现的代码: 1 # coding: utf-8 2 3 """命令行火车票查看器 4 5 Usage: 6 tic ...

  5. 使用python制作查询火车票工具

    使用python脚本实现查询火车票信息的效果图如下: 实现的代码: 1 # coding: utf-8 2 3 """命令行火车票查看器 4 5 Usage: 6 tic ...

  6. 过年回家抢不到火车票?教你用 Python 开发 12306 查票神器

    临近年关,不少在外的游子都急着买票回家,但这时候的火车票,总是供不应求的. 我想到了几年前徐峥主演的<人在囧途>,春运期间,一个老板,一个民工,同时都因为买不到火车票而囧态百出,甚至辗转到 ...

  7. Python之12306余票查询

    简单的Python学习,用Python完成一个12306余票查询- Python之12306余票查询 参考资料来自Python 实现火车票查询工具 需要用到的第三方库 requests,使用 Pyth ...

  8. python 12306查询不到车次_python爬取12306火车车次信息

    #-*- coding:utf-8 -*- importrequestsimportreimportjson#关闭https证书验证警告 requests.packages.urllib3.disab ...

  9. 用python写12306系统_Python实现12306火车票抢票系统

    Python实现12306火车票抢票系统 来源:中文源码网    浏览: 次    日期:2019年11月5日 [下载文档:  Python实现12306火车票抢票系统.txt ] (友情提示:右键点 ...

  10. 最新Python实现12306余票查询系统

    首先感谢这篇博客的引导,但是这篇文章已经比较旧了,12306进行了改版,源码编排方式有了变化.12306源码获取的方法可以从这篇博客中学习,我在这里主要贴出对于目前最新的12306的Python余票查 ...

最新文章

  1. tortoisesvn的安装
  2. SecureCRT的上传下载小技巧(Linux)
  3. vue+element-ui实现数据的增删改查及分页
  4. linux安装mysql5.7.25教程,Linux安装mysql-5.7.25
  5. android项目允许命令,android 项目 gradle 命令
  6. 常用数据库的分页实现
  7. 转 JMeter之修改Sampler响应数据的编码格式
  8. scikit keras_使用Scikit-Learn,Scikit-Opt和Keras进行超参数优化
  9. 时间管理(二):时间管理的六项基本原则
  10. CSC公派|小红本及小黄本的办理
  11. 【iOS 开发】基础控件:UISwitch
  12. 【你好,windows】windows7 x64x86旗舰完整版(带驱动包usb3.0_nvme)2020.1.22
  13. Oracle SOA平台1——概述
  14. 洛谷p3764签到题3
  15. 什么是客户端与服务器端
  16. HTML内核超炫酷北漂鱼引导页源码
  17. 217小白最新详细linux环境下安装博客WordPress教程
  18. 企小码会话存档使用教程——删人提醒
  19. TCP/IP协议第一章笔记
  20. 《MetaSploit渗透测试魔鬼训练营》之WEB应用渗透技术

热门文章

  1. java中print的含义_【转】Java中print、printf、println的区别详解
  2. 每周一喂丨图说WiFi安全
  3. python描述对象静态特性的数据为_外国法律中,对婚生子女的否认请求均规定有时效限制,日本法律规定的时效期限是 ( )_学小易找答案...
  4. 微信游戏奇迹暖暖选取服务器失败,奇迹暖暖微信登录授权失败
  5. 使用开源文档工具docsify,用写博客的姿势写文档
  6. 深圳金证股份面试的经历
  7. QRCode.js:使用 JavaScript 生成二维码
  8. 损失函数大全Cross Entropy Loss/Weighted Loss/Focal Loss/Dice Soft Loss/Soft IoU Loss
  9. 计算机组成原理和微机原理实验报告,《计算机组成原理》实验指导.doc
  10. 利用akshare读取50EFF期权2