概要
コード
総務省の無線局等情報検索APIについては、Web-API機能(無線局等情報検索)についてをご覧ください。
総務省の無線局等情報検索APIは、https://www.tele.soumu.go.jp/musen/list?ST=1&OF=2&OW=AT&DA=1&SC=1&DC=1
のようなリクエストを送ると、下記のようなJSONを取得できます。
この場合は、アマチュア無線局について検索結果の1件目から500件分の詳細情報をJSON形式で送ってくださいという意味のリクエストになります。
{ "musen": [{ "detailInfo": { "radioSpec1": "A1A\\t435.795 MHz\\t1 W\\nG1D\\t435.91 MHz\\t1 W\\n20K0F1D\\t435.91 MHz\\t1 W\\n20K0F3E\\t435.91 MHz\\t1 W\\nA1A\\t435.795 MHz から 435.9 MHz まで\\t1 W\\nJ3E\\t435.795 MHz から 435.9 MHz まで\\t1 W", "radioStationPurpose": "アマチュア業務用", "note": "", "permittedOperatingHours": "常 時", "address": "*****", "licenseDate": "2016-08-19", "broadcastMatter": "", "commMatter": "アマチュア業務に関する事項", "office": "", "validTerms": "2021-08-18まで", "commPartner": "アマチュア局", "startingLimit": "", "broadcastDistrict": "", "workPersonName": "", "identificationSignals": "8J1JCS ", "radioStationNumber": "", "radioStationCategory": "アマチュア局", "movementArea": "", "radioEuipmentLocation": "軌道傾斜角 98度\\n軌道周期 110分\\n遠地点高度 1,705km\\n近地点高度 805km\\n軌道の種類 円軌道極軌道", "licenseNumber": "*****", "name": "一般社団法人日本アマチュア無線連盟" }, "listInfo": { "name": "一般社団法人日本アマチュア無線連盟(8J1JCS)", "radioStationPurpose": "アマチュア業務用", "tdfkCd": " ", "no": "1", "licenseDate": "2016-08-19" } }, { ... ... 省略 ... ... } }], "musenInformation": { "totalCount": "408919", "lastUpdateDate": "2019-07-05" } }
これをJSON-to-Go を使って、Golangの構造体に変換します。 生成直後は、構造体の名前が AutoGenerated となっているので、適当な名前に変更します。 ここでは、無線局詳細情報のリストを表しているので、radioListsとしました。
// json struct // generated by this site: type radioLists struct { Musen []struct { DetailInfo struct { RadioSpec1 string `json:"radioSpec1"` ... ... 省略 ... ... } `json:"detailInfo"` ListInfo struct { Name string `json:"name"` RadioStationPurpose string `json:"radioStationPurpose"` TdfkCd string `json:"tdfkCd"` No string `json:"no"` LicenseDate string `json:"licenseDate"` } `json:"listInfo"` } `json:"musen"` MusenInformation struct { TotalCount string `json:"totalCount"` LastUpdateDate string `json:"lastUpdateDate"` } `json:"musenInformation"` }
次に、APIにリクエストを投げて、構造体を返してくれる関数を書きます。
// get list of radio // sc is start count // sc番目から最大500件のデータを取得します。 func requestList(sc int) (*radioLists, error) { // Options st := 1 // 免許状の情報 of := 2 // json format ow := "AT" // amateur radio da := 1 // request details dc := 2 // Number of acquisitions url := fmt.Sprintf("https://www.tele.soumu.go.jp/musen/list?ST=%d&OF=%d&OW=%s&DA=%d&SC=%d&DC=%d", st, of, ow, da, sc, dc) // get web api response resp, err := http.Get(url) if err != nil { return nil, err } defer resp.Body.Close() // check HTTP status code if 300 <= resp.StatusCode && resp.StatusCode < 200 { return nil, errors.New("request faild") } // decode response data var data *radioLists err = json.NewDecoder(resp.Body).Decode(&data) if err != nil { return nil, err } return data, nil }
url := fmt.Sprintf("https://www.tele.soumu.go.jp/musen/list?ST=%d&OF=%d&OW=%s&DA=%d&SC=%d&DC=%d", st, of, ow, da, sc, dc)
初めに、fmt.Sprintf()を使い、リクエストを組み立てurlに代入します。 オプションを後々変更することを考えて、変数に一度代入してから、fmt.Sprintfで結合しています。 そのURLを使用して、http.Get()でレスポンスを得ます。 実際には、HTTPのステータスコードをチェックして、対応した処理を行う必要があるのですが、 簡単にするために、200番台なら続行、それ以外の場合はすべてエラーとしています。
得られたレスポンスボディを下記のコードでパースして終了! めちゃくちゃ簡単。
// decode response data by json format var data *radioLists err = json.NewDecoder(resp.Body).Decode(&data) if err != nil { return nil, err }
このrequestList関数は、引数に何件目から取得するかを指定して呼び出します。 下のような感じで使います。
lists, err := requestList(1) if err != nil { fmt.Println(err) }
あとは、得られたJSONを表す構造体を使えばいろいろと遊べます。 すべての無線局の情報について、取得したい場合は、検索結果の総件数を超えるまで requestList() を引数を変えながら呼び出すことでできます。 総件数は、requestList() で得られる構造体に含まれているのでそれを利用します。
ただし、その際はサーバに負荷を掛けすぎないように行ってください。