Goでスクレイピング


# はじめに
Dockerの環境構築からGo言語でスクレイピングする手順を整理しました。

# Go言語について
https://go.dev/

- Googleで開発されたプログラミング言語
- 文法がシンプルで大人数開発に向いている
- 処理速度が早い
- 並行処理が得意

# 本編
## ディレクトリ構成
ディレクトリ構成は下記のようになります。
```
.
├── cmd
│ └── main.go
│ └── colly.go
│ └── dohouse_news.go
│ └── go.mod
│ └── go.sum
├── docker-compose.yml
├── Dockerfile.yml
```

# Docker
Goを実行する環境をDockerで構築していきます。
### Dockerfile
```dockerfile:Dockerfile
# image取得
FROM golang:1.19.0-alpine3.16

# ホストのファイルをコンテナの作業ディレクトリにコピー
COPY . /go/src/app

# ワーキングディレクトリの設定
WORKDIR /go/src/app/cmd
```

Goのイメージは下記から必要に応じて選択してください。
https://hub.docker.com/_/golang


### docker-compose.yml

```docker:docker-compose.yml
version: "3.7"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: go_scraping_app
    ports:
      - "80:80"
    volumes:
      - .:/go/src/app
    tty: true
```

### main.go
実行するプログラムを作成しておきます。
```go:main.go
package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello world!!")
}
```

### ビルドと起動
Dockerfileとdocker-compose.ymlの準備ができたら、ビルドと起動を行います。
```
# ビルド
$ docker-compose build

# 起動
$ docker-compose up -d
```
コンテナの中に入ってプログラムが実行して「Hello World!!」が表示されればOK
```
# コンテナに入る
$ docker exec -it go_scraping_app ash

# プログラムの場所に移動（初期でこのディレクトリにいるので実行しなくても良い）
$ cd /go/src/app/cmd

# プログラム実行
$ go run main.go
Hello world!!
```

# スクレイピングのプログラム作成
### Colly
今回はCollyというスクレイピングのライブラリを使用します。

http://go-colly.org/

特徴（公式サイトから）
- クリーン API
- 高速 (シングルコアで 1k リクエスト/秒以上)
- リクエストの遅延とドメインごとの最大同時実行数を管理します
- Cookie とセッションの自動処理
- 同期/非同期/並列スクレイピング
- 分散スクレイピング
- キャッシング
- 非 Unicode 応答の自動エンコード
- robots.txt のサポート
- Google App Engine のサポート

### ドキュメント類
はじめに：https://go-colly.org/docs/introduction/start/
リファレンス：https://pkg.go.dev/github.com/gocolly/colly?utm_source=godoc

### インストール
コンテナの中に入ってインストールを実行します。
※既にコンテナ内のcmd配下にいる場合は、最初の２つは実行不要
```
# コンテナに入る
$ docker exec -it go_scraping_app ash

# プログラムの場所に移動（初期でこのディレクトリにいるので実行しなくても良い）
$ cd /go/src/app/cmd

# go.modの初期化
$ go mod init go_scraping

# collyのインストール
$ go get github.com/gocolly/colly/v2@latest
```

### サンプルコードを実行
colly.goファイルを作成
```go:colly.go
package main

import (
    "fmt"

    // collyのインポート
	"github.com/gocolly/colly/v2"
)

func main() {
	c := colly.NewCollector()

	// Find and visit all links
	c.OnHTML("a[href]", func(e *colly.HTMLElement) {
		e.Request.Visit(e.Attr("href"))
	})

	c.OnRequest(func(r *colly.Request) {
		fmt.Println("Visiting", r.URL)
	})

	c.Visit("http://go-colly.org/")
}
```

実行して結果が出力されればOK
```
$ go run colly.go
Visiting http://go-colly.org/
Visiting https://go-colly.org/
Visiting https://go-colly.org/docs/
Visiting https://go-colly.org/articles/
Visiting https://go-colly.org/services/
Visiting https://go-colly.org/datasets/
Visiting https://godoc.org/github.com/gocolly/colly
Visiting https://go.dev/
Visiting https://go.dev/solutions/
```

### ドゥ・ハウスのニュース一覧を取得してみる
対象のサイトはこちら

https://www.dohouse.co.jp/news/release/

ニュースの日付とタイトルを取得して出力する
```go:dohouse_news.go
package main

import (
	"fmt"

	"github.com/gocolly/colly/v2"
)

func main() {

	// colly初期化
	c := colly.NewCollector()

	// 受信したコンテンツがHTMLの場合の処理設定
	c.OnHTML(".news > dl", func(h *colly.HTMLElement) {

		date := h.DOM.Find(".entryDate").Text()
		title := h.DOM.Find("a").Text()

		fmt.Printf("%s %s\n", date, title)
	})

	// スクレイピング実行
	c.Visit("https://www.dohouse.co.jp/news/release/")
}
```

実行結果
```
$ go run dohouse_news.go 
2022.08.05 商品代相当のポイントがもらえる?!おトクなポイ活サービス『テンタメ』公式アプリがリニューアル
2022.08.01 美容・健康に特化した　ニュースメディア『モラタメビューティー』8月1日（月）スタート。“知って、タメして、もっとキレイに”をテーマに毎月約20記事発信
2022.07.29 総フォロワー数300万人超！インフルエンサーと企業が繋がるイベントContents Creator Japan開催報告
2022.07.13 モラタメ.netが新メディアの運営開始。気になる話題を調査するニュースサイト『ロバ耳』7月13日（水）スタート
2022.06.10 インフルエンサーマーケティングのREECH、新たに「Twitterユーザーの検索・分析機能」を提供開始
2022.06.07 モラタメ.net 16周年記念！モラタメ会員1万名と編集部で選んだベストヒット商品を1万名様にプレゼント！『絶対にモラえるでしょうキャンペーン』開始。
2022.05.09 インフルエンサーマーケティングの今後を考えるオンラインセミナー開催。別冊：よげんの書『エンゲージメント・ファーストの時代』発表。
2022.04.15 ドゥ・ハウス、REECHとの事業連携でインフルエンサーマーケティング領域に本格参入
2022.03.14 生活に嬉しい商品が無料でモラえる・お得にタメせるモラタメ.netが3月14日(月)より期間限定で新規登録キャンペーンを開始！
2022.03.03 バーバパパ、スポンジ・ボブをはじめとした海外アニメ・絵本キャラクターに関する調査結果や活用事例を紹介。『商品マーケティングのためのキャラクター活用セミナー』開催。
2022.03.02 モラタメ.net の『SDGsプロジェクト』で9つの支援団体へ総額300万円を寄附。ひとり親家庭の支援や動物の孤児院など、多彩な団体の活動を支援。
2022.01.20 生活に嬉しい商品が無料でモラえる・お得にタメせるモラタメ.netの新TVCMを1月21日(金)より放映開始。
2022.01.20 ドゥ・ハウス、iDAと協業しOMOでのインフルエンサーサービスを展開。店頭接客やPOP UPイベントなどオフラインでのプロモーション支援も。
2022.01.11 モラタメ.netの「SDGsプロジェクト」で7団体へ総額250万円を寄附。障がい者支援やフードセーフティネット等、多彩な団体の活動を支援。
2021.12.28 冬季休業のお知らせ
```


# 参考
https://osamu-tech-blog.com/go-docker/
https://hub.docker.com/_/golang
https://zenn.dev/kinariru/articles/51b2df87d2962e
https://blog.webmatrices.com/web-scraping-with-golang-go-and-colly/
https://blog.framinal.life/entry/2021/04/11/013819#gomod%E3%81%A8%E3%81%AF