0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

さっぽろのバス情報を取得するWebAPI

Posted at

はじめに

さっぽろのバスの運行情報をWebAPIを使って、プログラムから取得する手順です。
JSON形式をPOSTして、レスポンスをJSONで受け取る形式です。

※公式サイトや公式アプリより使いやすいとか、目指していません。

特定のバスのGPS位置情報がわかるものではありません。

バス停を指定して、バスが近づいてきたら、最低限の情報を得ることのみ可能です。

course_idとstation_idを取得する例

WebAPIを使うために、course_idとstation_idが必須で、これらを知る方法です。

chromeブラウザのDevToolsを使います。

えきバスnaviから

調べたいバス停を検索します。
image.png

使いたいルートを選びます。
image.png

キーボードのF12を押して、DevToolsを表示し、Networkタブ、ekibusでフィルタ、Fetch/XHRを選択する。
image.png

接近情報ボタンを押す。
image.png

Get_busstop_timetable_listを選択し、Previewタブを選択する。
▶の▼中身を開いていくと、情報が見える。

course_id:"420090"
station_id:"420118"

をメモする。
image.png

station_last_idを取得する方法

運行情報を取得するには、
course_id(既知)
station_last_id
が必要です。

station_last_idは以下のコードで、取得できます。
この例では、

420066

とでました。

processing
import java.net.*;

String c_id = "420090"; // 例: じょうてつバスの真駒内線[南54]
String s_id = "420118"; // 例: 光塩短大前

void setup() {
  String stationLastId = getStationLastId(c_id, s_id);
  println(stationLastId);
  exit();
}

String getStationLastId(String courseId, String stationId) {
  try {
    JSONObject body = new JSONObject();
    body.setString("kind", "0");
    body.setString("course_id", courseId);
    body.setString("station_id", stationId);

    HttpURLConnection con =
      (HttpURLConnection)new URL(
        "https://ekibus-api.city.sapporo.jp/Get_busstop_lastdata"
      ).openConnection();

    con.setRequestMethod("POST");
    con.setDoOutput(true);
    con.setRequestProperty("Content-Type", "application/json");
    con.getOutputStream().write(body.toString().getBytes("UTF-8"));

    JSONObject res = JSONObject.parse(
      join(loadStrings(con.getInputStream()), "")
    );

    return res.getString("station_last_id");

  } catch (Exception e) {
    e.printStackTrace();
    return null;
  }
}

station_last_idを使って、次の情報を得る

import java.net.*;

String c_id = "420090"; // 例: じょうてつバスの真駒内線[南54]
String s_id = "420118"; // 例: 光塩短大前
String l_id = "420066";

void setup() {
  JSONArray tl = getTimeList(c_id, l_id);
  println(tl);
  exit();
}

JSONArray getTimeList(String courseId, String stationLastId) {
  try {
    JSONObject body = new JSONObject();
    body.setString("kind", "0");
    body.setString("course_id_list", courseId);
    body.setString("station_id_list", stationLastId);

    HttpURLConnection con =
      (HttpURLConnection)new URL(
        "https://ekibus-api.city.sapporo.jp/Get_busstop_list"
      ).openConnection();

    con.setRequestMethod("POST");
    con.setDoOutput(true);
    con.setRequestProperty("Content-Type", "application/json");
    con.getOutputStream().write(body.toString().getBytes("UTF-8"));

    JSONObject res = JSONObject.parse(
      join(loadStrings(con.getInputStream()), "")
    );

    return res.getJSONArray("data")
              .getJSONObject(0)
              .getJSONArray("time_list");

  } catch (Exception e) {
    e.printStackTrace();
    return null;
  }
}

以下の出力を得ます。

[
  {
    "start_time": "05:55",
    "course_id": "420090",
    "note": "12/31~1/3運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "06:31",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "06:40",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "07:16",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "07:05",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "07:42",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "07:30",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "08:11",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "07:55",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "08:39",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "08:17",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "09:01",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "08:45",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "09:29",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "09:30",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "10:17",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "10:05",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "10:52",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "11:05",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "11:52",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "12:10",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "12:57",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "13:15",
    "course_id": "420090",
    "note": "",
    "last_stop_order": 9,
    "bus_status": 0,
    "time": "14:02",
    "last_stop": 420116,
    "barrier_free": 0,
    "delay_time": 5
  },
  {
    "start_time": "14:10",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "14:57",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "14:40",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "15:27",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "15:10",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "15:56",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "15:45",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "16:31",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "16:05",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "16:51",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "16:40",
    "course_id": "420090",
    "note": "",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "17:26",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "17:20",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "18:06",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "18:20",
    "course_id": "420090",
    "note": "1/1運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "19:03",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  },
  {
    "start_time": "19:35",
    "course_id": "420090",
    "note": "12/31~1/3運休",
    "last_stop_order": -1,
    "bus_status": 1,
    "time": "20:11",
    "last_stop": 0,
    "barrier_free": 0,
    "delay_time": 0
  }
]

この路線、このバス停には、この日、21台のバスが通り、下記の情報が得られます。

1 2
start_time 始発駅の始発時刻
course_id 路線ID
note 備考
last_stop_order 通常は-1
0:接近中
通り過ぎると1,2,3,...とバス停ごとに増えていく?
bus_status 0:運行中
1:非運行中
time 最終駅の到着時刻
last_stop 最後に着いたバス停
barrier_free 1:バリアフリー対応
0バリアフリー非対応
delay_time 遅延時間(分)

以下のプログラムで、この路線のバス停一覧を取得できます。

import java.net.*;

String c_id = "420090"; // 例: じょうてつバスの真駒内線[南54]
String s_id = "420118"; // 例: 光塩短大前

JSONArray getStops(String courseId, String stationId) {
  try {
    JSONObject body = new JSONObject();
    body.setString("kind", "0");
    body.setString("course_id", courseId);
    body.setString("station_id", stationId);

    HttpURLConnection con =
      (HttpURLConnection)new URL(
        "https://ekibus-api.city.sapporo.jp/Get_busstop_lastdata"
      ).openConnection();

    con.setRequestMethod("POST");
    con.setDoOutput(true);
    con.setRequestProperty("Content-Type", "application/json");
    con.getOutputStream().write(body.toString().getBytes("UTF-8"));

    JSONObject res = JSONObject.parse(
      join(loadStrings(con.getInputStream()), "")
    );

    return res.getJSONArray("station_data_list");

  } catch (Exception e) {
    e.printStackTrace();
    return null;
  }
}

void setup() {
  JSONArray stops = getStops(c_id, s_id);
  for (int i = 0; i < stops.size(); i++) {
    JSONObject s = stops.getJSONObject(i);
    println(s.getString("station_id"), s.getString("name"));
  }
  exit();
}
420123 南町4丁目
420122 南町2丁目
420121 泉町3丁目
420120 泉町中央
420067 真駒内駅
420098 南区役所前(北)
420119 緑町3丁目
420118 光塩短大前
420117 上町1丁目
420116 曙町
420115 真駒内本町
420085 南34条西11丁目
420009 南33条西11丁目
420084 南警察署前(国道)
420008 北海学園大工学部前
420083 南24条西11丁目
420007 南21条西11丁目
420082 南19条西11丁目
420081 南16条西11丁目
420006 南14条西11(札幌いしやま病院前)
420080 南11条西11丁目
420078 南7条西11丁目
420005 南6条西11丁目
420114 中央区役所前
420108 西11丁目駅前
420107 大通西8丁目
420104 大通西4丁目
420066 北2条西3丁目
420001 札幌駅前

というわけで、

  {
    "start_time": "13:15",
    "course_id": "420090",
    "note": "",
    "last_stop_order": 9,
    "bus_status": 0,
    "time": "14:02",
    "last_stop": 420116,
    "barrier_free": 0,
    "delay_time": 5
  },

これは、420116 曙町と420115 真駒内本町の間に、バスがいて、5分遅延していることが読み取れます。

次は、バス路線が複数ある場合について考えます。

中央バス

中央バス、リアルタイム運行情報

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?