How to spend the terminal

技術ブログでさえない

Go言語でriver.go.jpからダムの貯水率を取得する

最近雨が降らないな、と思っていたらニュースで早明浦ダム取水制限が始まることを知り驚きました。 取水制限が始まるくらい貯水率が減っていたのなら早明浦ダムbotが毎時間ツイートしているだろう、 と思っていたら止まっていました。(2017/06/18現在動いています。)

作者の 103yen (@103yen) | Twitter さんによると、 river.go.jpの仕様が変わって貯水率を取得できなかったようです。

なんでbotが止まっていたかどうかわからなかったので、自分で貯水率を取得してつぶやこうと思いました。 作者さんのWebページ( ダムbotシリーズについて )とブログ( Pythonでriver.go.jpからダムの貯水率を取得する - 99円のへたれ日記! )を参考にしてGo言語で実装しました。(ほぼgoquery)

package main

import (
    "fmt"
    "log"

    "github.com/PuerkitoBio/goquery"
)

type Storage struct {
    date string
    time string
    pos  string
}

var (
    BASE_URL           = "http://www1.river.go.jp"
    OUTSIDE_URL_BEFORE = "/cgi-bin/DspDamData.exe?ID="
    OUTSIDE_URL_AFTER  = "&KIND=3&PAGE=0"
    ID                 = "1368080700010"
)

func GetPerOfStorage() (s Storage) {
    found := false
    outside_url := BASE_URL + OUTSIDE_URL_BEFORE + ID + OUTSIDE_URL_AFTER
    outside, err := goquery.NewDocument(outside_url)
    if err != nil {
        log.Fatal(err)
    }
    iframe := outside.Find("iframe")
    iframe_url, _ := iframe.Attr("src")
    contents_url := BASE_URL + iframe_url
    contents, _ := goquery.NewDocument(contents_url)
    contents.Find("tr").EachWithBreak(func(i int, tr *goquery.Selection) bool {
        if found == true {
            return false
        }
        tr.Find("td").EachWithBreak(func(j int, td *goquery.Selection) bool {
            if j == 0 {
                s.date = td.Text()
            } else if j == 1 {
                s.time = td.Text()
            } else if j == 6 {
                s.pos = td.Text()
            }
            if s.pos != "" && s.pos != "-" {
                found = true
                return false
            }
            return true
        })
        return true
    })
    return
}

func main() {
    s := GetPerOfStorage()
    fmt.Printf("%s %s %s\n", s.date, s.time, s.pos)
}

これで取得したデータをRubyを用いてツイートしました。

2時間ごとにツイートしていたのですが、早明浦ダムbotが復活したのでtwitterでのツイートはやめました。 (GNU socialでは毎時間クイップしてます)