タイトルですべてを語っているだけの自分用メモ
背景
そういう機会に直面してしまった。pythonなら余裕だがpython/Node以外だとそういえばやったことがない。せっかくなのでGoでやる。以上
chromedpは初めて使った
四方山
また、最初テキトーにググった内容をノールックでパクろう参考にしようとしてたため、日本語記事ではchromedpより多くヒットしたagoutiを使おうとしてたが、コピペサンプルを実装して「あれ?なんか動かんな」ってなってから初めて調べて、1年前にプロジェクト終了のお知らせを出してたのを知った。使用するライブラリのreadmeくらいちゃんと読もうね....
chromedpはagoutiと違ってseleniumやchromedriverといったwebdriverのたぐいを用意しなくても動くのが便利。昨今のスクレイピングツールはだいたいそういう感じなのかもしれないが知らない
コード
素晴らしいことにchromedpのリポジトリにはたくさんの(完動する)サンプルがある。ろくにリファレンス読まずとも今回やりたかった用途程度ならば剽窃書けてしまった。
「JSがロードされたあとの、ブラウザでレンダリングされた結果のhtml」が欲しかったのである。この用途でいうと、以下のサンプルでいい
なお、今回のはホントにイージーなので、むしろgoquery
を使わなくてもいいのだが、怠惰なので使った。ついでにUser-Agentをランダムに生成してくれるパッケージを使ってみた。スクレイピング仕草(?)
package main import ( "context" "fmt" "log" "strings" "time" "github.com/DataHenHQ/useragent" "github.com/PuerkitoBio/goquery" "github.com/chromedp/chromedp" ) func main() { // user-agent ua, err := useragent.Desktop() if err != nil { log.Fatalln(err) } // options いろいろあるけど今回はuser-agentだけ opts := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.UserAgent(ua), ) ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) defer cancel() // create context ctx, cancel = chromedp.NewContext(ctx) defer cancel() // time out ctx, cancel = context.WithTimeout(ctx, 50*time.Second) defer cancel() var wholeHtml string // run task list err = chromedp.Run( ctx, chromedp.Navigate("ターゲットのサイトURL"), chromedp.Sleep(1000*time.Millisecond), // いちおうスクレイピング仕草(?) chromedp.WaitVisible("div.mb-2:nth-child(2)"), chromedp.OuterHTML("html", &wholeHtml, chromedp.ByQuery), ) if err != nil { log.Fatalln(err) } dom, err := goquery.NewDocumentFromReader(strings.NewReader(wholeHtml)) if err != nil { log.Fatalln(err) } a := dom.Find("div.text-base:nth-child(1)").Text() b := dom.Find("div.mb-2:nth-child(2)").Text() fmt.Printf("GET TEXT:\nA: %s\nB: %s\n", a, b) }
CSSセレクターは横着してfirefoxのdevtoolの「コピー->CSSセレクター」でコピーしたものをそのまんま貼り付けただけである。うーん怠惰
参考
Golang+chromedp+goquery 简单爬取动态数据
全体的な構成を参考にした(bilibiliのサイトなのでちょっと重い)
chromedp で Chrome を見える状態(not headless)で起動して、かつ終了しないようにする - Qiita
オプションの書き方を参考にした