Golangでもスクレイピング

Golang

通常Webスクレイピングをする時はPythonで実装していましたが、
インターネット上のVPSで実行するとしたら、Golangでの選択も「あり」ではないかと思い調べてみました。

リンク

分かったこと

  • htmlqueryでXPathの解析が出来る
  • agoutiでブラウザを操作? Seleniumのようなことが出来る
  • デバッグを実行するたびに、相手サーバにスクレイピングをしてしまう

今まで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でも出来れば良いなって思います。(知らないだけで、存在しているのかもですが・・・)

以上になります。またお会いしましょう

鹿児島県の出水市という所に住んでいまして、インターネット周辺で色々活動して行きたいと思ってるところです。 Webサイト作ったり、サーバ設定したり、プログラムしたりしている、釣りと木工好きなMacユーザです。 今はデータサイエンスに興味を持って競馬AI予想を頑張ってます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください