概要
Go言語でHeadlessChromeを使ってスクレイピングすることを目的にします。
Go言語でスクレイピングとなると、goqueryが有名ですが、もちろんgoqueryだけでも可能です。
では、なぜChromeDriverを使うのかというと、javascriptを利用した動的ページの取得をするためです。
たとえば、curlコマンドでQiitaのトップページを取得したソースと、実際にブラウザで確認したソースを見てみると結果が違う。
そのため、この記事では、動的ページのスクレイピングをする方法を記述します。
実行環境
CentOS Linux release 7.6.1810 (Core)
スクレイピング
ライブラリ
今回利用するライブラリは以下の2つです。go getコマンドで取得してください。
-
ChromeDriver
-
github.com/sclevine/agouti
-
goquery
-
github.com/PuerkitoBio/goquery
ソース
まずドライバーの設定です。
"--headless"オプションを付与し、ヘッドレスモードで利用します。
driver := agouti.ChromeDriver(
agouti.ChromeOptions("args", []string{
"--headless",
"--window-size=1280,800",
}),
agouti.Debug,
)
次はドライバの起動から対象URLの設定までになります。
page.Navigateに取得したいページのURLを設定します。
if err := driver.Start(); err != nil {
log.Fatal(err)
}
defer driver.Stop()
page, err := driver.NewPage()
if err != nil {
log.Fatal(err)
}
// URL Setting
page.Navigate(" 取得したいURL ")
次はいよいよHTML取得です。
getSource, err := page.HTML()
これですでにString型のDOMが取得できているのでparserなどで自力で必要な部分を取得してもよいのですが、jqueryのようにセレクタを利用して楽に対象箇所を取得できるようにgoqueryを使います。
先ほど取得した"getSource"にStringのDOMが入っているので、StringからReaderに変換し、goqueryで読み込める型にします。
r := strings.NewReader(getSource)
doc, err := goquery.NewDocumentFromReader(r)
あとは doc.Find で取得したい箇所のタグやクラスを書いていくだけです。
以下は例ですが対象のアンカータグのテキストとリンクの取得です。このように書きます。(もちろん中身は対象ページに合わせてください)
doc.Find("div.classname > div > div > a.item").Each(func(i int, s *\
goquery.Selection){
title := s.Text()
url, exists := s.Attr("href")
if exists == true{
fmt.Printf("Title: %s\n", title)
fmt.Printf("URL: %s\n", url)
}
})
終わりに
スクレイピングは相手のサイトにも負荷をかける可能性があるので、適度にアクセス数を気にするようにしてください。
意外とクローリングを禁止にしているサイトもあるので、使う場合は気をつけましょう。