LoginSignup
64
62

More than 5 years have passed since last update.

Go言語で東京メトロAPIを叩く

Posted at

東京メトロがWebAPIで色々な情報を提供しているようなので早速使ってみました。

東京メトロ オープンデータ 開発者サイト
元々はコンテスト用に公開してたAPIがそのまま使えるようになったみたいですね。

ユーザ登録

APIの利用にはユーザ登録が必要です。登録は無料です。
申請内容の確認から登録まで最大で2営業日ほどお時間を、とありましたが自分が登録した時は数分で完了しました。

アクセストークンの取得

登録が完了したら1個デフォルトのアクセストークンが発行されていると思いますので、今回はそれを使ってアクセスしてみましょう。

ログインして「アクセストークンの確認・追加」から確認できます。

いざデータ取得

今回は運行情報を取得してみます。
→ API仕様: 列車運行情報 odpt:TrainInformation

main.go
package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "strings"
    "time"
)

const (
    ENDPOINT     = "https://api.tokyometroapp.jp/api/v2/datapoints"
    CONSUMER_KEY = <your consumer key>
)

// レスポンスJSONデータ用構造体
type TrainInfomation struct {
    Context                string    `json:"@context"`
    Id                     string    `json:"@id"`
    Type                   string    `json:"@type"`
    Date                   time.Time `json:"dc:date"`
    Valid                  time.Time `json:"dct:valid"`
    Operator               string    `json:"odpt:operator"`
    TimeOfOrigin           time.Time `json:"odpt:timeOfOrigin"`
    Railway                string    `json:"odpt:railway"`
    TrainInformationStatus string    `json:"odpt:trainInformationStatus"`
    TrainInformationText   string    `json:"odpt:trainInformationText"`
}

// レスポンスJSONデータ配列
type TrainInformations []TrainInfomation

func main() {
  // URL生成
  q := map[string]string{
    "rdf:type": "odpt:TrainInformation", // TypeにTrainInformation(運行情報)を設定
    "acl:consumerKey": CONSUMER_KEY, // アクセストークン
  }
  url := fmt.Sprintf("%s?%s", ENDPOINT, buildQuery(q))
  // URLを叩いてデータを取得
  resp, err := http.Get(url)
  if err != nil {
    log.Fatal(err)
  }
  defer resp.Body.Close()
  body, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    log.Fatal(err)
  }
  // 取得したデータをJSONデコード
  var trains TrainInformations
  err = json.Unmarshal(body, &trains)
  if err != nil {
    log.Fatal(err)
  }
  // 取得したデータを整形して出力する
  for _, train := range trains {
    // 路線名
    railway := strings.Replace(train.Railway, "odpt.Railway:TokyoMetro.", "", -1)
    // 運行情報を組み立てる
    text := train.TrainInformationText
    if len(train.TrainInformationStatus) > 0 {
      text = fmt.Sprintf("%s (%s)", train.TrainInformationStatus, train.TrainInformationText)
    }
    fmt.Printf("%s: %s [%s]\n", railway, text, train.Date)
  }
}
func buildQuery(q map[string]string) string {
  queries := make([]string, 0)
  for k, v := range q {
    qq := fmt.Sprintf("%s=%s", k, v)
      queries = append(queries, qq)
  }
  return strings.Join(queries, "&")
}
Fukutoshin: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]
Hanzomon: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]
Hibiya: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]
Ginza: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]
Chiyoda: ダイヤ乱れ (21時23分頃、JR常磐線各駅停車内で地震のため、ダイヤが乱れ ています。只今、東京メトロ線、都営地下鉄線、JR線、東急線、東武線、京成線、小田急線、京王線、つくばエクスプレス線に振替輸送を実施しています。詳しくは、駅係員にお尋ねください。) [2016-05-16 23:10:03 +0900 JST]
Namboku: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]
Marunouchi: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]
Yurakucho: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]
Tozai: 現在、平常どおり運転しています。 [2016-05-16 23:10:03 +0900 JST]

こういうのをサクッと作れるのもGo言語の強みですね。
時間があったらAPIのラッパーライブラリを作ろうと思います。

64
62
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
64
62