12306火车票余票查询器
今天写了一个12306火车票余票查询器的爬虫,在这里记录一下过程.
本博客同步更新:http://blog.csdn.net/riba2534
首先先看一下最终效果:
比如想查9月2日从西安—北京动车
和特快
的余票
tickets.py -dg 西安 北京 2017-09-02
效果预览:
首先我们梳理一下用到的工具:
- Python3.x(必备)
requests
库,用来进行http请求的访问docopt
库,用来实现命令行参数处理(使用方法)prettytable
,使信息以好看的表格形式呈现出来colorama
,用来设置命令行中显示的颜色
前期准备
我们的主程序就叫做tickets.py
,因为我们是用的带参数的形式实现程序,所以我们要先进行参数的声明:
我们先:from docopt import docopt
"""命令行火车余票查询器
Usage:
tickets [-gdtkz] <from> <to> <date>
Options:
-h,--help 显示帮助菜单
-g 高铁
-d 动车
-t 特快
-k 快速
-z 直达
"""
这些信息会存储在__doc__
中,docopt
会对这个信息进行解析然后返回我们需要的信息,解析的代码如下:
解析URL
既然要写爬虫,那么首先肯定是要对URL进行解析了,我们要爬取的是12306的网站,那么我们首先找到查询余票的网站:
https://kyfw.12306.cn/otn/leftTicket/init
我们会看到这个:
然后进行抓包,我们会发现一个GET
请求:
也就是这个链接:
https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-09-01&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=BJP&purpose_codes=ADULT
我们通过观察就会发现这个请求里面有4个参数:
- leftTicketDTO.train_date=2017-09-01
- leftTicketDTO.from_station=XAY
- leftTicketDTO.to_station=BJP
- purpose_codes=ADULT
我们通过观察就可以知道,这四个属性分别对应着:查询的时间,出发的站点,结束的站点,票的种类
现在发现了一个问题,出发站点和结束站点的值为什么都是英文,这些字母肯定表示的是城市的名称,那么我们现在就要去寻找这些城市的代码,我们查看网页源代码 发现了一个JS文件,打开以后会发现 这个页面竟然包含着全部的站点名称和对应的代码,所以我们只需要把这些东西解析一下,就可以得到车站和对应的代码了.
所以我们就有了思路了,我们应该先用requests
来获取这个页面,然后再用正则表达式
来把对应的信息解析一下,然后进行一些处理就好了,关于正则表达式的使用,不会的童鞋还是去百度百度吧~
根据网页上面的信息,我们可以写出如下正则表达式:
([\u4e00-\u9fa5]+)\|([A-Z]+)
先匹配汉字,然后后面匹配字母,中间有一个分隔符,完整的代码.
我们建一个文件parser_stations.py
解析:
使用方法是运行这个文件,然后把这个文件的结果重定向到一个新文件:
python parser_stations.py > stations.py
然后对新的文件进行处理:
这样我们就可以通过stations.py
里面的两个函数进行获取操作了,这样的话我们就可以构造出我们需要的URL
|
|
解析火车票信息
我们现在已经获取到了url,我们现在就可以对其访问,还是用requests来访问我们构造好的URL,比如我们构造的是2017-09-02从西安到北京的火车,那么url是:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-09-02&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=BJP&purpose_codes=ADULT
我们进入后会看到:
很明显,这是一个json
信息,我们用requests
自带的json
解析器来进行解析,会得到一个列表:
|
|
这个列表里面:
- 6,7元素代表起点和终点的名称
- 8,9元素代表这趟列车出发和到达的时间
- 10号元素代表,列车的用时
- 31代表一等座,30代表二等座
- 23,28,29代表软卧,硬卧,硬座
- 26代表无座的信息
我们知道了每个元素代表的信息,只需要把它们呈现出来就可以了,我们先创建一个prettytable
对象:
|
|
然后弄好表格的标题后,插入列:
|
|
在这里面用了colorama
来对命令行里面的字符进行上色,相关用法去百度找找就行了~
代码长得比较丑陋,还请不要嫌弃,主要作为练手之用,所以懒得重构代码了,相关的源代码已经上传至Github,欢迎提出问题和Bug…
GitHub地址:https://github.com/riba2534/12306Tickets_search
(^▽^)
最后修改于 2017-09-02
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。