美文网首页Python数据从入门到实践
Python命令行查询12306火车票

Python命令行查询12306火车票

作者: Sunflow007 | 来源:发表于2020-03-03 23:00 被阅读0次
    8.jpg
    程序很简单,主要是调用了12306的api。用法也很简单:输入出发地、目的地、乘车时间,将查询到的结果在命令行打印出来。对了,这个是我以前参照了:Python3 实现火车票查询工具Python实验楼 - 实验楼 ,现在我把简单修改了一下,适合新人练练手!

    有两点需要注意:

    1.from stations import stations这个是stations是个存储城市和代码的字典{},譬如南京,对应的城市代码是NKH,这个就是在stations里查找得出的。

    2.主要用到了colorama,docopt,prettytable可以将命令行的查询结果以彩色表格形式打印。

    3.用到了while True....这样可以保证程序一直循环,查询一次,输出结果以后,再次开始新一轮的查询。如果需要中断程序可以用ctrl+c。

    使用方法如下:

    """
    Usage:
        输入要查询的火车类型可以多选(动车d,高铁g,特快t,快速k,直达z)
        输入出发地、目的地、出发日期。
        查询结果以命令行形式自动呈现。
    
    Examples:
        Please input the trainType you want to search :dgz
        Please input the city you want leave :南京
        Please input the city you will arrive :北京
        Please input the date(Example:2017-09-27) :2018-03-01
    """
    

    程序截图如下:

    image

    动态效果请在知乎观看:https://zhuanlan.zhihu.com/p/33875291

    程序源代码,包含两部分:1.stations.py 2.searchTrain.py

    1.stations.py

    import re
    import requests
    from pprint import pprint
    
    url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9018'
    requests.packages.urllib3.disable_warnings()#如果不加此句会有:InsecureRequestWarning: Unverified HTTPS request is being made
    html = requests.get(url,verify=False)
    station = re.findall(u'([\u4e00-\u9fa5]+)\|([A-Z]+)', html.text)
    stations = dict(station)
    pprint(stations,indent = 4)
    

    2.searchTrain.py

    """
    Usage:
        输入要查询的火车类型可以多选(动车d,高铁g,特快t,快速k,直达z)
        输入出发地、目的地、出发日期。
        查询结果以命令行形式自动呈现。
    
    Examples:
        Please input the trainType you want to search :dgz
        Please input the city you want leave :南京
        Please input the city you will arrive :北京
        Please input the date(Example:2017-09-27) :2018-03-01
    """
    #coding = utf-8
    #author = Lyon
    #date = 2017-12-17
    import json
    import requests
    from docopt import docopt
    from prettytable import PrettyTable
    from colorama import init,Fore
    from stations import stations
    
    class searchTrain:
        def __init__(self):
            self.trainOption = input('-d动车 -g高铁 -k快速 -t特快 -z直达,Please input the trainType you want to search :')
            self.fromStation = input('Please input the city you want leave :')
            self.toStation = input('Please input the city you will arrive :')
            self.tripDate = input('Please input the date(Example:2017-09-27) :')
            self.headers = {
                "Cookie":"自定义",
                "User-Agent": "自定义",
                }
            self.available_trains,self.options = self.searchTrain()
    
        @property
        def trains(self):
            for item in self.available_trains:
                cm = item.split('|')
                train_no = cm[3]
                initial = train_no[0].lower()
                if not self.options or initial in self.options:
                    train = [
                    train_no,
                    '\n'.join([Fore.GREEN + cm[6] + Fore.RESET,
                              Fore.RED + cm[7] + Fore.RESET]),
                    '\n'.join([Fore.GREEN + cm[8] + Fore.RESET,
                              Fore.RED + cm[9] + Fore.RESET]),
                    cm[10],
                    cm[32],
                    cm[25],
                    cm[31],
                    cm[30],
                    cm[21],
                    cm[23],
                    cm[28],
                    cm[24],
                    cm[29],
                    cm[26],
                    cm[22]   ]
                    yield train
    
        def pretty_print(self):
            pt = PrettyTable()
            header = '车次 车站 时间 历时 商务座 特等座 一等 二等 高级软卧 软卧 硬卧 软座 硬座 无座 其他'.split()
            pt._set_field_names(header)
            for train in self.trains:
                pt.add_row(train)
            print(pt)
    
        def searchTrain(self):
            arguments = {
            'option':self.trainOption,
            'from':self.fromStation,
            'to':self.toStation,
            'date':self.tripDate
            }
            options = ''.join([item for item in arguments['option']])
            from_station, to_station, date = stations[arguments['from']] , stations[arguments['to']] , arguments['date']
            url = ('https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT').format(date,from_station,to_station)
            requests.packages.urllib3.disable_warnings()
            html = requests.get(url,headers = self.headers,verify=False)
            available_trains = html.json()['data']['result']
            return available_trains,options
    
    if __name__ == '__main__':
        while True:
            asd = searchTrain()
            asd.pretty_print()
    

    后续:其实查询还是很简单的,就是调用API接口,输入查询关键词就OK了,但是要想完整地实现购买火车票的流程,还是一个比较复杂的项目,Github上有完整的项目,喜欢的童鞋可以上去看看~testerSunshine/12306

    彩蛋:

    下一篇文章:Python命令行实现—查全国7天天气

    下下篇文章:Python—itchat实现微信自动回复

    下下下篇文章:Python实现微信查天气+火车+飞机+快递!!!

    相关文章

      网友评论

        本文标题:Python命令行查询12306火车票

        本文链接:https://www.haomeiwen.com/subject/nbqrlhtx.html