簡單,好玩,有趣的命令列版12306(golang)

aliasliyu4發表於2017-02-06

前言

17年的春節即將臨近的時候,跟大多數人一樣都需要搶一下回家的票,慶幸我買到了回家的票,因為目的地離家還有一段距離,所以需要知道到達的時間,然後安排下中轉回家的行程。就想到如果再terminal中直接可以查就好了,接著就是google了一下,果然網上有很多類似的東西,但是查詢火車時刻表的功能好像沒有,那就自己寫吧。

環境

  1. chrome
  2. mac

專案地址

https://github.com/JingDa-open-source-community/go-home

旅途

從12306官網開始

查詢火車時刻表api

登陸12306輸入出發地和目的地,會出來很多車子,然後選擇你已經買到的那趟。見下圖。 開啟除錯工具command+shift+j),檢視網路,可以看到請求的url,點選這個url可以看到返回一個json,包含了這趟車的時刻資訊和其他的一些狀態資訊

時刻表url--》https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=5l000G138920&from_station_telecode=AOH&to_station_telecode=NXG&depart_date=2017-01-25,可以看到中間有train_no車次編號from_station_telecode出發站(代號) to_station_telecode到達站(代號) depart_date出發日期,重點看一下車次編號是一個經過了處理的資料,這趟車是G1389後面還帶了兩個數,出發城市和到達城市也是一個對映關係。google一下發現城市的對映關係儲存在https://kyfw.12306.cn/otn/reso ... .8968,這樣我們通過一些簡單的處理就能得到城市和相對應的程式碼,很容易想到把他們放在一個map裡面是再好不過的。 下面是完整的處理:

 func Stations(stationTetx []byte) map[string]string {
    comp, _ := regexp.Compile("([\u4e00-\u9fa5]+)\\|([A-Z]+)")

    datas := comp.FindAll(stationTetx, -1)

    cityMap2Code := make(map[string]string, len(datas))
    for _, v := range datas {
        temp := strings.Split(string(v), "|")
        cityMap2Code[temp[0]] = temp[1]
    }
    return cityMap2Code
}

還有一個問題就是車次編號的程式碼是如何生成的,好在他們也是可以通過url訪問到的。 https://kyfw.12306.cn/otn/resources/js/query/train_list.js?scriptVersion=1.5462 這個檔案稍微有些大,我們經過一次處理儲存在了本地(最好的方式是儲存的mysql中,但是鑑於這是一個簡單的專案就沒有這樣做),大概的形式是:

{
  "2017-01-03": {
    "1095": {
      "Train_no": "270000109500",
      "From": "太原",
      "To": "蘭州西"
    }
    // 省略很多
 }

可以看到這個結構包含一趟車的時間,車次,車次編號,出發地和終點。

渲染資料

terminal中顯示錶格的包有很多,我用了github上的tablewriter,他的使用是很簡單。你也可以加一些自己的序列化控制符,事實上我也是這樣乾的。

查詢火車時刻表

查詢火車餘票

更新本地資料

新增了對window console的color支援,同時支援cygwin和mysys 如果有同學願意和我一起做這個事情,隨時都歡迎!

相關文章