ケイ
2023.02.16
258
ケイです。
YOKUの執行役員として日々、技術にアツく破天荒なYOKUをより良くするために奔走しています。
火傷しそうなくらいアツいマインドを持ったメンバーが集まっており、僕も負けじと技術と戦っています。
今回は、Goでスクレイピングをする時のオレオレ構成をまとめてみました!
最近、「〇〇の情報収集したいからスクレイピング頼む!」と依頼されることが多く、いくつかこなしていくうちに【いつもの構成】が固まってきたので、ここらで一つ記事にしようかと!
スクレイピングしようかな、でもどう始めようかな?
って思っている方の参考になればいいな!
とはいえ、自分のマシンで動かすだけの書き捨てスクリプトなら、書き慣れた言語でサクッと作っちゃう方が良いと思います。
僕の場合、メンバーに依頼されて作ることが殆どなので、どんなPCでも動くべきという課題があります。
過去にPythonを使ってスクレイピングをしまくってた時期があるので、Pythonが一番サクッと書けるのですが、
使うメンバーに、いちいちPythonインストールさせるのはダサすぎない?
という問題がありました。
そんな時にGo。バイナリにしちゃえばターミナルで動きます。
そしてクロスコンパイルでLinux・Mac・Windowsなんでもこい、強し。
方法としても、buildコマンドで実行環境を指定するだけという簡単なもの。
(対応している環境もかなり種類があります。よかったら調べてみてください。)
これにより、Slack上でバイナリを配布するだけでみんな使えちゃいます。
Goは後発の言語なので、「イマドキ技術でスクレイピングできる」っていう称号も付きます。
スクレイピングを実行するときって、検索ワードを受け入れる必要があるケースが多いです。
また、膨大な数のスクレイピングを一気にブン回しちゃうと相手方のサーバーに迷惑をかけることになるので、
例えば特定のカテゴリー別に分けて、必要分のデータだけを対象にする必要もあります。
つまり、ターミナル入力の受付を実装する必要があります。
そんな時にSurveyというパッケージが輝きます。
超簡単に色んなターミナル入力が実装できちゃいます。
初めて出会った時は感動しました。。。
Nuxt.jsプロジェクトを立ち上げるnpx create-nuxt-app
を実行したときに出るような選択式の入力もできて優秀です。
(凝った実装をしてるように見えるので、コスパ良く名声を得ることもできます。)
生のGoでWebサーバー作るときによく使われるアイツです。
このnet/http
パッケージのClient()
をスクレイピングで使います。
同じくnet/http
に入っているcookiejar
を併せて使えば、Cookieを持たせることができます。
サイトによってはCookieに値を保持できないとリクエストが通らないケースがあるのですが、これで解決です。
import (
"net/http"
"net/http/cookiejar"
)
func initClient() *http.Client {
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatalln(err)
}
return &http.Client{Jar: jar}
}
WebAPIから直接JSONとしてレスポンスを受けることができれば、スクレイピングの必要はありません。
リクエスト投げて、レスポンスのJSONをGoの構造体にバインドして処理するだけです。
(この方法はブラックに近いグレーだと思うけど。)
しかし、スクレイピングはHTML形式のレスポンスとの戦い。
そんな時にhtmlqueryをよく使います。
レスポンスとして受け取ったHTMLを与えて、そのままHTMLを要素探索するだけです。
無駄なくシンプルに、データの取り出しまでを行うことができます。
XPathによる探索ができるのが有難いです。
ブラウザで実際のページで検証しながら、XPathをポチポチ組んでいます。
XPathを使えばハニーポットトラップも回避できます。
でも、ハニーポットを仕掛けているサイトはスクレイピングされることを良しとしていないケースが多いので、スクレイピングをする前に、サイトの規約を確認しましょう…!
Macにて、Slack上でバイナリを渡したときに出るこれ。
検証されていないために、素直には実行できない。
バイナリに署名とかできるものなのかね?
実行する方法はあるから特に調査せず、それで問題なしとしてるけども。
良い感じの方法あったらまた記事にします。
読んでいただきありがとうございました!ノシ