TIGの伊藤真彦です
先日Go Conference’20 in Autumn SENDAI に登壇させていただきました、リモート登壇の為残念ながら現地には行きませんでした。
発表資料はこちらです。
Youtubeのアーカイブ としても確認いただけます
補足 発表で紹介したコードを詳しく確認できるようにまとめます。
goqueryについて
goqueryはjQueryを意識した命名から想像できる通り、Find等のメソッドチェーンを繋いで直感的にスクレイピングを行う事ができます。
ページURLを与えて読み取るだけでなく、別途htmlや文字列からスクレイピングを行う事も可能です。
main.go func scrapeYahoo (url string ) string { items := []Item{} doc, err := goquery.NewDocument(url) if err != nil { return ("" ) } selection := doc.Find("ul.Products__items" ).Find("li.Product" ) selection.Each(func (index int , s *goquery.Selection) { url := s.Find("div.Product__image" ).Find("a" ).AttrOr("href" , "" ) name := s.Find("h3.Product__title" ).Text() price := s.Find("span.Product__priceValue" ).First().Text() image := s.Find("div.Product__image" ).Find("img" ).AttrOr("src" , "" ) item := Item{ Url: url, Name: name, Price: price, Image: image } items = append (items, item) }) json, _ := json.Marshal(items) return string (json) }
agoutiについて
agoutiはスクレイピングを行うための補助として用いましたが、–headlessオプションを使わなければ普段お使いのウェブブラウザが自動で動く様を実際に目で確認できます。
ブラウザでのルーチンワークの自動化など夢が広がりますね。
main.go func scrapeReverb (url string ) string { items := []Item{} driver := agouti.ChromeDriver( agouti.ChromeOptions("args" , []string { "--headless" , "--window-size=30,120" , "--disable-gpu" , "no-sandbox" , "disable-dev-shm-usage" , }), ) driver.Start() defer driver.Stop() page, _ := driver.NewPage(agouti.Browser("chrome" )) page.Navigate(url) time.Sleep(7 * time.Second) content, _ := page.HTML() reader := strings.NewReader(content) doc, _ := goquery.NewDocumentFromReader(reader) selection := doc.Find("ul.tiles.tiles--four-wide-max" ).Find("li.tiles__tile" ) selection.Each(func (index int , s *goquery.Selection) { url := s.Find("a" ).AttrOr("href" , "" ) name := s.Find("h4.grid-card__title, h3.csp-square-card__title" ).Text() price := s.Find("span.price-display, div.csp-square-card__details__price" ).Text() image := s.Find("img" ).AttrOr("src" , "" ) item := Item{ Url: url, Name: name, Price: price, Image: image } if name != "" { items = append (items, item) } }) json, _ := json.Marshal(items) return string (json) }
Dockerファイルについて 一人で作ったのと趣味なので動けばよしの精神があり、スライドでも書いた通り更に攻める余地があると認識しています。 マルチステージビルドの活用などのノウハウ共有が好意的な感想を頂けたので一安心です。
FROM golang:1.12 -alpine as builderWORKDIR ./ RUN apk add --no-cache git ENV GOBIN=/go/binENV GO111MODULE=onENV GOPATH=COPY ./go.mod ./go.sum ./main.go ./ RUN go mod download RUN env GOOS=linux GOARCH=amd64 GIN_MODE=release go build -o /go-api FROM node:12.7 .0 -alpineWORKDIR /myapp COPY --from=builder /go-api . RUN apk add --update \ wget \ udev \ ttf-freefont \ chromium \ chromium-chromedriver \
最後に 株式会社Fusic清家史郎様、株式会社Gunosy平田智子様にもフューチャー技術ブログの存在について触れて頂けました。
我らが渋川さん及び社員一同大喜びでした、ありがとうございます。