東京生まれHOUSE MUSIC育ち

悪そうな奴はだいたい友達なの?

TBSラジオ番組表のxmlをgolangでパースする


スポンサードリンク

背景

TVだと全番組を録画するような、「全録」というシステムががあります。

TVの全録システムをradikoでも実現できないかなと思って、試しにTBSラジオの番組を録画できないか試してみました。この記事はその事前調査として、golangでTBSラジオの番組情報を取得する方法を書いてみます。

f:id:padobure:20200707183054j:plain

TBSラジオの番組情報

番組情報は以下のURLで提供されています。番組情報はXML形式で提供されています。

http://radiko.jp/v3/program/station/weekly/TBS.xml

golangでXMLをパースするには?

標準で提供されているencoding/xmlを使用します。

構造体は手抜きして作る

golangでパースするには構造体を定義する必要があります。まずは動くものが作りたいので、以下のサイトを利用しました。

https://www.onlinetool.io/xmltogo/

ここに番組情報のXMLを入れると、構造体が出力されます。

厳密には変数の型を定義すると思いますが、動けばいいのでstringsで定義しています。

コード

以下のコードで動きます。

package main

import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "net/http"
)


func main() {
    data := httpGet("http://radiko.jp/v3/program/station/weekly/TBS.xml")

    result := Radiko{}
    err := xml.Unmarshal([]byte(data), &result)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
 
    for _, prog := range progs.Prog{
        fmt.Printf("%v - %v - %v - %v - ", prog.ID ,prog.Ft,prog.Title,prog.Pfm)
        fmt.Printf("%v秒\n", prog.Dur)  
        }
    }
}

type Radiko struct {
    XMLName  xml.Name `xml:"radiko"`
    Text     string   `xml:",chardata"`
    Ttl      string   `xml:"ttl"`
    Srvtime  string   `xml:"srvtime"`
    Stations struct {
        Text    string `xml:",chardata"`
        Station struct {
            Text  string `xml:",chardata"`
            ID    string `xml:"id,attr"`
            Name  string `xml:"name"`
            Progs []struct {
                Text string `xml:",chardata"`
                Date string `xml:"date"`
                Prog []struct {
                    Text         string `xml:",chardata"`
                    ID           string `xml:"id,attr"`
                    MasterID     string `xml:"master_id,attr"`
                    Ft           string `xml:"ft,attr"`
                    To           string `xml:"to,attr"`
                    Ftl          string `xml:"ftl,attr"`
                    Tol          string `xml:"tol,attr"`
                    Dur          string `xml:"dur,attr"`
                    Title        string `xml:"title"`
                    URL          string `xml:"url"`
                    FailedRecord string `xml:"failed_record"`
                    TsInNg       string `xml:"ts_in_ng"`
                    TsOutNg      string `xml:"ts_out_ng"`
                    Desc         string `xml:"desc"`
                    Info         string `xml:"info"`
                    Pfm          string `xml:"pfm"`
                    Img          string `xml:"img"`
                    Metas        struct {
                        Text string `xml:",chardata"`
                        Meta struct {
                            Text  string `xml:",chardata"`
                            Name  string `xml:"name,attr"`
                            Value string `xml:"value,attr"`
                        } `xml:"meta"`
                    } `xml:"metas"`
                } `xml:"prog"`
            } `xml:"progs"`
        } `xml:"station"`
    } `xml:"stations"`
} 


func httpGet(url string) string {
    response, _ := http.Get(url)
    body, _ := ioutil.ReadAll(response.Body)
    defer response.Body.Close()
    return string(body)
}

出力結果

以下のように出力されます。

9527304714 - 20200701174400 - エンタメExpress - 赤荻歩(TBSアナウンサー) - 360秒
9527743947 - 20200701175000 - マコくんのベリハピラジオ - 株式会社こす.くま - 600秒
9527489246 - 20200701180000 - アフター6ジャンクション(1)【カルチャートーク】など - ライムスター宇多丸/日比麻音子(TBSアナウンサー) - 3600秒
9527489247 - 20200701190000 - アフター6ジャンクション(2)【スタジオライブ】など - ライムスター宇多丸/日比麻音子(TBSアナウンサー) - 3600秒
9527489248 - 20200701200000 - アフター6ジャンクション(3)【特集コーナー】など - ライムスター宇多丸/日比麻音子(TBSアナウンサー) - 3600秒
9527503388 - 20200701210000 - テンカイズ - 宇賀なつみ/浜田敬子(ビジネスインサイダー 統括編集長) - 1800秒

参考にした記事

以下の記事を参考にしました。

qiita.com