12306火车票查询——Python

原创 2017年05月08日 10:19:46

欢迎加入Python学习交流QQ群:535993938  禁止闲聊 ! 名额有限 ! 非喜勿进 !

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

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

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

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

    下面的将是实现步骤:

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

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

    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:

复制代码
 1 #coding=utf-8
 2 
 3 import requests
 4 import re
 5 from pprint import pprint
 6 
 7 
 8 def get_stations():
 9     # 7@cqn|重庆南|CRW|chongqingnan|cqn|
10     url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8968'
11     r = requests.get(url,verify=False)
12     patter = re.compile('([A-Z]+)\|([a-z]+)')
13     items = dict(re.findall(patter,r.text))
14     stations = dict(zip(items.values(),items.keys()))
15     # for key in stations:
16     #     print("{0}-->{1}".format(key,stations[key]))
17     pprint(stations,indent=4)
18 
19 if __name__ == '__main__':
20     get_stations()
复制代码

    其中pprint这个模块能是打印出来的信息,更加方便阅读:

在cmd中运行:python parse_stations.py > stations.py

就会在当前目录下得到stations.py文件,文件中就是站点名字和简称,在stations.py文件中加入"stations = "这样就是一个字典,方便后面的取值,下面就是stations.py文件的内容:

    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

复制代码
 1 """Train tickets query via command-line.
 2 
 3 Usage:
 4     tickets [-gdtkz] <from> <to> <date>
 5 
 6 Options:
 7     -h,--help   显示帮助菜单
 8     -g          高铁
 9     -d          动车
10     -t          特快
11     -k          快速
12     -z          直达
13 
14 Example:
15     tickets -gdt beijing shanghai 2016-08-25
16 """
17 import requests
18 from docopt import docopt
19 from stations import stations
20 # from pprint import pprint
21 from myprettytable import TrainCollection
22 
23 class SelectTrain(object):
24 
25     def __init__(self):
26         """
27         获取命令行输入的参数
28         """
29         self.args = docopt(__doc__)#这个是获取命令行的所有参数,返回的是一个字典
30 
31 
32     def cli(self):
33         """command-line interface"""
34         # 获取 出发站点和目标站点
35         from_station = stations.get(self.args['<from>']) #出发站点
36         to_station = stations.get(self.args['<to>']) # 目的站点
37         leave_time = self._get_leave_time()# 出发时间
38 
39         url = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={0}&from_station={1}&to_station={2}'.format(
40             leave_time,from_station,to_station)# 拼接请求列车信息的Url
41 
42         # 获取列车查询结果
43         r = requests.get(url,verify=False)
44         traindatas = r.json()['data']['datas'] # 返回的结果,转化成json格式,取出datas,方便后面解析列车信息用
45 
46         # 解析列车信息
47         traintypes = self._get_traintype()
48         views = TrainCollection(traindatas,traintypes)
49         views.print_pretty()
50 
51     def _get_traintype(self):
52         """
53         获取列车型号,这个函数的作用是的目的是:当你输入 -g 是只是返回 高铁,输入 -gd 返回动车和高铁,当不输参数时,返回所有的列车信息
54         """        
55         traintypes = ['-g','-d','-t','-k','-z']
56         # result = []
57         # for traintype in traintypes:
58         #     if self.args[traintype]:
59         #         result.append(traintype[-1].upper())
60 
61         trains = [traintype[-1].upper() for traintype in traintypes if self.args[traintype]]
62         if trains:
63             return trains
64         else:
65             return ['G','D','T','K','Z']
66 
67     def _get_leave_time(self):
68         """
69         获取出发时间,这个函数的作用是为了:时间可以输入两种格式:2016-10-05、20161005
70         """
71         leave_time = self.args['<date>']
72         if len(leave_time) == 8:
73             return '{0}-{1}-{2}'.format(leave_time[:4],leave_time[4:6],leave_time[6:])
74 
75         if '-' in leave_time:
76             return leave_time
77 
78 
79 if __name__ == '__main__':
80     cli = SelectTrain()
81     cli.cli()
复制代码

    好了,基本上就结束了,按照开头的哪样,就能查询你想要的车次信息了。

欢迎加入Python学习交流QQ群:535993938  禁止闲聊 ! 名额有限 ! 非喜勿进 !

版权声明:本文为博主原创文章,未经博主允许不得转载。

java抓取数据包查询12306余票信息

最近项目比较闲,闲来无事,参照网上的代码实现了一下抓取12306数据包查询余票的代码, 需要的jar包需要全部包含到项目下,代码测试OK,具体代码如下: import java.i...

安卓json解析——12306查询票价的字符串解析

突然看到群里有2个同学都在问关于json数据解析的问题,当然很多人用工具解析,都忘记是怎么解析,那我就先贴一下原始数据吧: {"reason":"查询成功","result":{"list":[{"t...

Python爬取12306实现火车票查询

介绍:除了官方的12306网站,其他的很多网站都提供了购买查询的功能,像携程的铁友,途牛等等。这些网站他们盈利大都是通过广告的收入,以及通过购票带动的网站内酒店、景点额外收入,他们的网站界面友好型优于...

python实现12306查询火车票

为方便查询12306的火车票信息,在此用python写了一个小工具,主要用到了docopt、requests、re、prettytable几个模块。其中: docopt模块作用是创建一个简洁漂亮的命...

使用Python和Splinter实现12306火车票查询与抢票

有一段时间没有使用Python了,前几天经朋友提起一篇关于用Python实现抢火车票的文章,百度了实现抢火车票的技术细节,网上却有不少资料,也不是新鲜的东西。在了解了一些技术手段后,也尝试实现了一下,...

python 火车票监控12306

import urllib.request as request import http.cookiejar as cookiejar import re import os import smtpl...

比12306快!用Python写一个火车票查看器~

当你准备出去玩,想查询一下火车票信息的时候,还在用12306官网吗?下面我们用 Python 写一个命令行版的火车票查看器, 只要在命令行敲一行命令就能获得你想要的火车票信息! ...

Python接口获取12306火车票信息

Python接口抓取12306火车票信息 最近在讲解接口测试,然后就拿12306网站来开刀,现在稍微大型一点的网站都是走接口,分布式部署,三层架构等等的。 既然要做接口,首先就需要抓取接口服务器已...

12306用的是SRCA的根证书——原文标题:在线买火车票为什么要【安装根证书】?

近期同事组织了一场《信息加密与安全技术》分享,其中对于根证书的安装有讲述。 期间交流中,有位同事提到12306网站的证书使用的是自己的SRCA的根证书(当然国内大部分的公司使用的是VeriSign的...
  • jackpk
  • jackpk
  • 2017年03月07日 16:52
  • 343

易达火车票之12306抢票工具——预览

缘由:这段时间抢票居然颗粒无收,一方面是由于12306系统很烂,另一方面是公司网速真的慢,还有都是热门路线,抢了几天居然都没有成功,也用过网络上的一下抢票工具,好用的极少,于是萌发了自己开发一个适合自...
  • lyh1234
  • lyh1234
  • 2014年01月17日 23:08
  • 2311
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:12306火车票查询——Python
举报原因:
原因补充:

(最多只允许输入30个字)