12306火车票余票查询器

12306火车票余票查询器


今天写了一个12306火车票余票查询器的爬虫,在这里记录一下过程.

本博客同步更新:http://blog.csdn.net/riba2534

首先先看一下最终效果:

比如想查9月2日从西安—北京动车特快的余票

效果预览:

首先我们梳理一下用到的工具:

  1. Python3.x(必备)
  2. requests库,用来进行http请求的访问
  3. docopt库,用来实现命令行参数处理(使用方法)
  4. prettytable,使信息以好看的表格形式呈现出来
  5. colorama,用来设置命令行中显示的颜色

一、前期准备

我们的主程序就叫做tickets.py,因为我们是用的带参数的形式实现程序,所以我们要先进行参数的声明:
我们先:from docopt import docopt

这些信息会存储在__doc__中,docopt会对这个信息进行解析然后返回我们需要的信息,解析的代码如下:

二、解析URL

既然要写爬虫,那么首先肯定是要对URL进行解析了,我们要爬取的是12306的网站,那么我们首先找到查询余票的网站:

我们会看到这个:

然后进行抓包,我们会发现一个GET请求:

也就是这个链接:

我们通过观察就会发现这个请求里面有4个参数:

  • leftTicketDTO.train_date=2017-09-01
  • leftTicketDTO.from_station=XAY
  • leftTicketDTO.to_station=BJP
  • purpose_codes=ADULT

我们通过观察就可以知道,这四个属性分别对应着:查询的时间,出发的站点,结束的站点,票的种类

现在发现了一个问题,出发站点和结束站点的值为什么都是英文,这些字母肯定表示的是城市的名称,那么我们现在就要去寻找这些城市的代码,我们查看网页源代码

发现了一个JS文件,打开以后会发现

这个页面竟然包含着全部的站点名称和对应的代码,所以我们只需要把这些东西解析一下,就可以得到车站和对应的代码了.

所以我们就有了思路了,我们应该先用requests来获取这个页面,然后再用正则表达式来把对应的信息解析一下,然后进行一些处理就好了,关于正则表达式的使用,不会的童鞋还是去百度百度吧~
根据网页上面的信息,我们可以写出如下正则表达式:

先匹配汉字,然后后面匹配字母,中间有一个分隔符,完整的代码.

我们建一个文件parser_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

(^▽^)

点赞
  1. wustxiao说道:

    github下载下来的代码怎么用啊?

    1. riba2534说道:

      用法就和文章里面写的一样啊 :surprised:

发表评论

电子邮件地址不会被公开。 必填项已用*标注