Goでスクレイピングするためにgoqueryを使い、Yahoo路線情報の遅延情報を取得してみる
やったこと
Goのプログラミング学習の一環としてスクレイピングするためにgoquery使ってみた。
goqueryについて
- GoDoc
Yahoo路線運行情報をスクレイピングする
■ スクレイピングするサイト ( Yahoo路線運行情報 )
■ main.go
package main import ( "fmt" "net/url" "github.com/PuerkitoBio/goquery" ) var( _url = "https://transit.yahoo.co.jp/traininfo/area/4/" ) func main() { doc, err := goquery.NewDocument(_url) if err != nil { fmt.Println(err) } u := url.URL{} u.Scheme = doc.Url.Scheme u.Host = doc.Url.Host fmt.Println(u.Scheme) fmt.Println(u.Host) title := doc.Find("title").Text() fmt.Println(title) } /* 実行結果 https transit.yahoo.co.jp 関東の運行情報(JR、私鉄、地下鉄、新幹線) - Yahoo!路線情報 */
コードを読む
■ goquery.NewDocument(_url)
↓↓↓NewDocument
↓↓↓
package goquery ・・・ func NewDocument(url string) (*Document, error) { // Load the URL res, e := http.Get(url) if e != nil { return nil, e } return NewDocumentFromResponse(res) }
↓↓↓Document
↓↓↓
package goquery ・・・ type Document struct { *Selection Url *url.URL rootNode *html.Node }
↓↓↓url.URL
↓↓↓
package url ・・・ type URL struct { Scheme string Opaque string // encoded opaque data User *Userinfo // username and password information Host string // host or host:port Path string // path (relative paths may omit leading slash) RawPath string // encoded path hint (see EscapedPath method) ForceQuery bool // append a query ('?') even if RawQuery is empty RawQuery string // encoded query values, without '?' Fragment string // fragment for references, without '#' }
↑↑↑URL
↑↑↑
■ u := url.URL{}
■ title := doc.Find("title").Text()
↓↓↓Find("title")
↓↓↓
package goquery ・・・ type Document struct { *Selection Url *url.URL rootNode *html.Node } // ↑↑↑*SelectionはDocument構造体に埋め込まれている↓↓↓ ・・・ func (s *Selection) Find(selector string) *Selection { return pushStack(s, findWithMatcher(s.Nodes, compileMatcher(selector))) }
↓↓↓Text()
↓↓↓
package goquery ・・・ func (s *Selection) Text() string { var buf bytes.Buffer // Slightly optimized vs calling Each: no single selection object created var f func(*html.Node) f = func(n *html.Node) { if n.Type == html.TextNode { // Keep newlines and spaces, like jQuery buf.WriteString(n.Data) } if n.FirstChild != nil { for c := n.FirstChild; c != nil; c = c.NextSibling { f(c) } } } for _, n := range s.Nodes { f(n) } return buf.String() }
Yahoo路線情報の遅延情報を取得する
■ 運行情報 ( 関東 )
<div class="elmTblLstLine trouble">
■ main.go
package main import ( "fmt" "net/url" "github.com/PuerkitoBio/goquery" ) var( targetUrl = "https://transit.yahoo.co.jp/traininfo/area/4/" ) func main() { doc, err := goquery.NewDocument(targetUrl) if err != nil { fmt.Println(err) } u := url.URL{} u.Scheme = doc.Url.Scheme u.Host = doc.Url.Host //fmt.Println(u.Scheme) //fmt.Println(u.Host) title := doc.Find("title").Text() fmt.Println(title) var message string doc.Find("div.trouble > table > tbody").Each(func(_ int, s *goquery.Selection) { s.Children().Each(func(i int, ss *goquery.Selection) { if (i > 0) { //fmt.Println(i) route := ss.Children().Find("a").Text() status := ss.Children().Find("span.colTrouble").Text() info := ss.Children().Next().Next().Text() message = message + status + " / " + route + " (" + info + ")\n" } }) }) fmt.Println(message) }
■ 実行結果
関東の運行情報(JR、私鉄、地下鉄、新幹線) - Yahoo!路線情報 列車遅延 / 常磐線(快速)[品川~取手] (06:07頃、松戸~柏駅間で線…)