Python查詢12306餘票

weixin_34236497發表於2018-01-27

一、requests等庫的介紹

requests:傳送請求,獲取響應內容

docopt:命令列解析工具,可以根據自定義的語法格式,自動生成解析器

prettytable:使用表格形式列印資料

colorama:命令列著色

二、開發環境搭建

下載Python2的安裝檔案[windows版]

https://www.python.org/

安裝Python2

此處省略N個字

配置環境變數

修改環境變數Path,追加Python2的安裝路徑[C:\Python27]

10027900-45f2a2d13e1e141a.png
image

檢查環境是否正常

10027900-9abde99906264c00.png
image

給eclipse工具安裝Aptana外掛

10027900-e4b3815d92bc32d4.png
image

配置eclipse

設定python直譯器的路徑[C:\Python27\python.exe]

10027900-642f538edf18d0cd.png
image

三、安裝相關的庫

安裝requests庫

10027900-770f3bdab8f19344.png
image

安裝docopt庫

pip install docopt

安裝prettytable庫

pip install prettytable

安裝colorama庫

pip install colorama

四、建立一個python工程

在eclipse裡面建立一個python工程,如下圖:

10027900-8247596a70e57876.png
image

五、設計一個字典stations

stations字典裡面的資料為:站點和對應編碼

程式碼如下:

# coding:utf-8

stations = {   'ZhenJiang': 'ZJH',     #鎮江
    'ZhenJiangNan': 'ZEH',             #鎮江南
    'ShangHai':  'SHH'}                #上海

附截圖(程式碼檔名為stations.py):

10027900-d40d1565b080e1e3.png
image

六、編寫查詢餘票的程式

程式碼如下:

# coding:utf-8

"""命令列火車票檢視器

Usage:
    tickets [-gdtkz] <from> <to> <date>

"""

from docopt import docopt
from stations import stations
import requests
from prettytable import PrettyTable
from colorama import init, Fore

init()


class TrainsCollection:
    header = '車次  車站  時間  經歷時  一等座  二等座  高階軟臥  軟臥  硬臥  硬座  無座'.split()

    def __init__(self, available_trains,available_place, options):
        """查詢的火車班次集合
        :param available_trains: 一個列表, 包含可獲得的火車班次, 每個
                                 火車班次是一個字典
        :param options: 查詢的選項, 如高鐵, 動車, etc...
        """
        self.available_trains = available_trains
        self.available_place = available_place
        self.options = options

    @property
    def trains(self):
        for raw_train in self.available_trains:
            raw_train_list = raw_train.split('|')
            train_no = raw_train_list[3]
            initial = train_no[0].lower()
            duration = raw_train_list[10]
            if initial in self.options:
                train = [
                    train_no,
                    '\n'.join([Fore.LIGHTGREEN_EX + self.available_place[raw_train_list[6]] + Fore.RESET,
                               Fore.LIGHTRED_EX + self.available_place[raw_train_list[7]] + Fore.RESET]),
                    '\n'.join([Fore.LIGHTGREEN_EX + raw_train_list[8] + Fore.RESET,
                               Fore.LIGHTRED_EX + raw_train_list[9] + Fore.RESET]),
                    duration,
                    raw_train_list[-6] if raw_train_list[-6] else '--',
                    raw_train_list[-7] if raw_train_list[-7] else '--',
                    raw_train_list[-12] if raw_train_list[-12] else '--',
                    raw_train_list[-14] if raw_train_list[-14] else '--',
                    raw_train_list[-9] if raw_train_list[-9] else '--',
                    raw_train_list[-8] if raw_train_list[-8] else '--',
                    raw_train_list[-11] if raw_train_list[-11] else '--',
                ]
                yield train

    def pretty_print(self):
        pt = PrettyTable()
        pt._set_field_names(self.header)
        for train in self.trains:
            pt.add_row(train)
        print(pt)


def cli():
    """command-line interface"""
    arguments = docopt(__doc__) 
    
    from_station = stations.get(arguments['<from>'])   
    
    to_station = stations.get(arguments['<to>'])
    
    date = 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)    
    
    r = requests.get(url, verify=False)

    available_trains = r.json()['data']['result']
    available_place = r.json()['data']['map']
    options = ''.join([
        key for key, value in arguments.items() if value is True
    ])
    TrainsCollection(available_trains,available_place, options).pretty_print()


if __name__ == '__main__':
    cli()

附截圖(程式碼檔名為tickets.py):

10027900-0ef93cb3b6497bef.png
image

七、設定出發站、目的站等引數

Eclipse裡面設定相關的引數,引數列表內容如下:

-gd ShangHai ZhenJiang 2018-01-28

附截圖:

10027900-b3b1c59d10cc8e6b.png
image

八、執行查詢餘票的指令碼

在eclipse裡執行該指令碼

附截圖:

10027900-b2672cdce575a168.png
image

相關文章