Golangでもスクレイピング
通常Webスクレイピングをする時はPythonで実装していましたが、
インターネット上のVPSで実行するとしたら、Golangでの選択も「あり」ではないかと思い調べてみました。
リンク
- golangでagoutiとgoqueryを使ってスクレイピングする
- Go言語(golang)のAgouti(Selenium WebDriver)の使い方
- How to fix: Chromedriver Page Immediately Closes
分かったこと
今までPythonでやっていた事はGolangでも出来そうでした。ただ相手サーバには少々迷惑をおかけしそうです。
とりあえずDockerfile
# syntax=docker/dockerfile:1
FROM golang:1.20-alpine
WORKDIR /go/src/app
COPY . .
RUN apk upgrade --update && \
apk add --no-cache git && \
apk add --no-cache gcc musl-dev && \
apk add sqlite && \
apk add wget && \
apk add udev && \
apk add ttf-freefont && \
apk add chromium && \
apk add chromium-chromedriver
RUN go get github.com/antchfx/htmlquery
RUN go get github.com/sclevine/agouti
RUN go get github.com/PuerkitoBio/goquery
RUN go get github.com/gin-gonic/gin
RUN go get github.com/jinzhu/gorm
RUN go get github.com/mattn/go-sqlite3
RUN go get -u github.com/cosmtrek/air && \
go build -o /go/bin/air github.com/cosmtrek/air
# RUN go mod tidy
RUN go mod download
CMD ["air", "-c", ".air.toml"]
htmlqueryのサンプル
url := "https://www.example.xxx" // urlを指定
log.Println("Scraping start")
doc, _ := htmlquery.LoadURL(url)
var _itemid []string
tagID := "//div[contains(@id, 'itemInfo_')]/@id"
elements := htmlquery.Find(doc, tagID)
agoutiのサンプル
url := "https://www.example.xxx" // urlを指定
// driver := agouti.ChromeDriver() // ドライバの起動
driver := agouti.ChromeDriver(
agouti.ChromeOptions("args", []string{
"--headless",
"--no-sandbox",
"--disable-dev-shm-usage",
"--disable-gpu",
"--whitelisted-ips",
"--detach",
}),
// agouti.Debug, // ローカルオンリー
)
log.Println("start")
err := driver.Start()
if err != nil {
log.Printf("Error starting driver: %v", err.Error())
}
defer driver.Stop()
page, err := driver.NewPage(agouti.Browser("chrome")) // クロームを起動。page型の返り値(セッション)を返す。
if err != nil {
log.Printf("Error creating new page: %v", err.Error())
}
time.Sleep(1 * time.Second)
err = page.Navigate(url) // 指定したurlにアクセスする
if err != nil {
log.Printf("Error navigating to job post link: %v", err.Error())
}
time.Sleep(1 * time.Second)
log.Println("end")
curContentsDom, err := page.HTML()
if err != nil {
log.Printf("Failed to get html: %v", err)
}
readerCurContents := strings.NewReader(curContentsDom)
contentsDom, _ := goquery.NewDocumentFromReader(readerCurContents) // 現状ブラウザで開いているページのDOMを取得
listDom := contentsDom.Find("ul").Children() // selector 部分にセレクトボックスのセレクタを入れる。セレクトボックス内の子要素を全部取得
log.Println("[SELECTOR]", listDom)
最近はPythonでスクレイピング
通常はPython + Jupyterでスクレイピングしてます。開発の初期段階ではトライ and エラーの連続なので、相手サーバにどうしてもご迷惑をかけてしまいます。
Jupyterを使う開発の場合は、相手サーバにご迷惑を掛けることを軽くする事が出来る所がやっぱり良くて。
同じような(スクレイピングしたデータを保持しておく)ことがGolangでも出来れば良いなって思います。(知らないだけで、存在しているのかもですが・・・)
以上になります。またお会いしましょう