基于python的火車票查詢工具

效果圖

  • 1.只查詢動車票


  • 2.查詢所有票


Github鏈接

代碼鏈接為:https://github.com/happyte/tickets

接口設(shè)計

  • 1.查詢火車票定鸟,需要出發(fā)地點均牢,目的點,日期和所乘列類型這幾個參數(shù),因此設(shè)計出的接口為python3 tickets.py [-gdtkz] <from> <to> <date> , [-gdtkz] 代表查詢的火車類型亿汞,該參數(shù)可疊加,例如-gd代表查詢所有的動車和高鐵揪阿。
  • 2.python的docopt模塊可以解析命令行的參數(shù)疗我,代碼如下:
"""命令行火車票查看器
Usage:
    tickets [-gdtkz] <from> <to> <date>
Options:
    -h,--help   顯示幫助菜單
    -g          高鐵
    -d          動車
    -t          特快
    -k          快速
    -z          直達(dá)
Example:
    tickets 北京 上海 2016-10-10
    tickets -dg 成都 南京 2016-10-10
"""
 from docopt import docent

 def cli():
      arguments = docopt(__doc__)
      print(arguments)

 if __name__ == '__main__':
     cli()
  • 3.在命令行輸入命令python3 tickets.py -dg 成都 上海 2017-02-10 輸出的結(jié)果如下:

獲取12306數(shù)據(jù)

  • 1.用谷歌的chrome瀏覽器抓取下網(wǎng)頁的數(shù)據(jù)


    從上圖中發(fā)現(xiàn)請求的url后面跟了4個參數(shù)咆畏,分別為leftTicketDTO.train_date=2017-02-07leftTicketDTO.from_station=CDW吴裤、leftTicketDTO.to_station=SHH旧找、purpose_codes=ADULT 四個參數(shù)。

  • 2.再抓取下response,結(jié)果如下:



    所有的車次信息都在data這個字典中麦牺,0-10這個分別包含了每趟車的所有信息钮蛛。

  • 3.在請求的url中出發(fā)點和目的地都是英文縮寫,例如上面的CDWSHH剖膳,而我們在命令行中輸入的是中文魏颓,那么需要通過中文查找到對應(yīng)的英文縮寫,這個用chrome抓取到的數(shù)據(jù)好像沒找到吱晒。那么查看下網(wǎng)頁源代碼


    點擊進(jìn)入第一個station_version=1.8994這個文件甸饱,進(jìn)入之后看到該文件是所有車站對應(yīng)的中文和英文縮寫,但是只需要提取中文和英文的大寫縮寫仑濒,編寫一個正則表達(dá)式提取叹话。另外新建一個文件叫parse_station.py,代碼如下:

 # -*- coding:utf-8 -*-
 import re
 import requests
 from pprint import print

 url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8994'
response = requests.get(url, verify=False)     # verify=False不驗證證書
stations = re.findall(u'([\u4e00-\u9fa5]+)+\|([A-Z]+)', response.text)
pprint(dict(stations), indent=4)       # indent代表縮進(jìn)
  • 4.在命令行執(zhí)行python3 parse_station.py > stations.py墩瞳,就新建了一個stations.py文件里面生成了一個中文和英文縮寫對應(yīng)的字典驼壶,如下所示:
    這里寫圖片描述

獲取需要的信息

  • 1.構(gòu)造url請求套鹅,導(dǎo)入上面生成的stations.py文件
 from stations import stations

 def cli():
    arguments = docopt(__doc__)
    from_station = stations.get(arguments['<from>'])
    to_staion = 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_staion)
    response = requests.get(url, verify=False)
  • 2.得到請求的json應(yīng)答防楷,因為上面說了所有的列車信息都在data字典內(nèi)部,因此需要的信息在response.json()['data'] 中怠噪。
  • 3.創(chuàng)建一個類用于分析需要的數(shù)據(jù)瞭吃,prettytable 模塊用于創(chuàng)建圖形化表格碌嘀,colorama 模塊用于給表格上色。
class TransCollection:
    header = '車次 車站 時間 歷時 一等座 二等座 軟臥 硬臥 硬座 無座'.split()

    def __init__(self, available_trains, options):
        self.availavle_trains = available_trains
        self.options = options

    def _get_duration(self, train_data):
        duration = train_data.get('lishi').replace(':', '小時')+'分'
        if duration.startswith('00'):
            return duration[4:]
        if duration.startswith('0'):
            return duration[1:]
        return duration

    @property
    def trains(self):
        for train in self.availavle_trains:
            train_data = train['queryLeftNewDTO']
            train_number = train_data['station_train_code'][0].lower()   # 開頭轉(zhuǎn)換成小寫
            if not self.options or train_number in self.options:
                train = [
                    train_data['station_train_code'],              # 車次
                    '\n'.join([Fore.GREEN+train_data['from_station_name']+Fore.RESET,    # 車站
                               Fore.RED+train_data['to_station_name']+Fore.RESET]),
                    '\n'.join([Fore.GREEN+train_data['start_time']+Fore.RESET,           # 車站
                               Fore.RED+train_data['arrive_time']+Fore.RESET]),
                    self._get_duration(train_data),                # 歷時
                    train_data['zy_num'],                          # 一等座
                    train_data['ze_num'],                          # 二等座
                    train_data['rw_num'],                          # 軟臥
                    train_data['yw_num'],                          # 硬臥
                    train_data['yz_num'],                          # 硬座
                    train_data['wz_num'],                          # 無座
                ]
                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)
  • 4.創(chuàng)建一個上面類的對象歪架,調(diào)用pretty_print 函數(shù)股冗,在cli函數(shù)中添加
def cli():
    arguments = docopt(__doc__)
    from_station = stations.get(arguments['<from>'])
    to_staion = 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_staion)
    response = requests.get(url, verify=False)
    options = ''.join([key for key, value in arguments.items() if value is True])
    TransCollection(response.json()['data'], options).pretty_print()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市和蚪,隨后出現(xiàn)的幾起案子止状,更是在濱河造成了極大的恐慌,老刑警劉巖攒霹,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怯疤,死亡現(xiàn)場離奇詭異,居然都是意外死亡催束,警方通過查閱死者的電腦和手機集峦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人塔淤,你說我怎么就攤上這事摘昌。” “怎么了高蜂?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵聪黎,是天一觀的道長。 經(jīng)常有香客問我备恤,道長稿饰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任烘跺,我火速辦了婚禮湘纵,結(jié)果婚禮上脂崔,老公的妹妹穿的比我還像新娘滤淳。我一直安慰自己,他們只是感情好砌左,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布脖咐。 她就那樣靜靜地躺著,像睡著了一般汇歹。 火紅的嫁衣襯著肌膚如雪屁擅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天产弹,我揣著相機與錄音派歌,去河邊找鬼。 笑死痰哨,一個胖子當(dāng)著我的面吹牛胶果,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斤斧,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼早抠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了撬讽?” 一聲冷哼從身側(cè)響起蕊连,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎游昼,沒想到半個月后甘苍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡烘豌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年载庭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡昧捷,死狀恐怖闲昭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情靡挥,我是刑警寧澤序矩,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站跋破,受9級特大地震影響簸淀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毒返,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一租幕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拧簸,春花似錦劲绪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牺六。三九已至颤枪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淑际,已是汗流浹背畏纲。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留春缕,地道東北人盗胀。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像淡溯,于是被迫代替她去往敵國和親读整。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容