Help us understand the problem. What is going on with this article?

Golang + Chrome on CentOS7(Docker)でスクレイピング

More than 1 year has passed since last update.

概要

Golangとchromeを使って、CentOS7上でスクレイピングをする環境を構築します。
Dockerで環境を構築します。

python版は、こちらです。
Python + Chrome on CentOS7(Docker)でスクレイピング

関連記事

環境構築

以下の内容はGitHubにpushしてあるので、こちらをcloneしていただいてDockerを起動させれば実現できます。
https://github.com/Esfahan/docker-go-chrome

ディレクトリ構成

以下のディレクトリ構成を前提とします。
/codeは、dockerコンテナにマウントさせる領域です。

code/
Dockerfile
files/

google-chrome.repo

google-chromeを取得するためのレポジトリファイルを作成します。
files/etc/yum.repos.d/google-chrome.repoとして作成します。

[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub

Dockerfileを作成

From centos:7

ARG GO_VER=1.11
ARG CHROME_DRIVER_VER=2.43

RUN yum update -y

########
# go
########
WORKDIR /usr/local/src
RUN yum install -y git
RUN curl -O https://dl.google.com/go/go${GO_VER}.linux-amd64.tar.gz
RUN tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz

ENV GOPATH=/code
ENV PATH=$PATH:$GOPATH/bin
ENV PATH=$PATH:/usr/local/go/bin


########################
# chromedriver, chrome
########################
# chromedriver
RUN yum install -y unzip
RUN curl -O https://chromedriver.storage.googleapis.com/${CHROME_DRIVER_VER}/chromedriver_linux64.zip
RUN unzip chromedriver_linux64.zip
RUN mv chromedriver /usr/local/bin/

# Dependencies
RUN yum install -y libX11 \
                   GConf2 \
                   fontconfig

# chrome
ADD files/etc/yum.repos.d/google-chrome.repo /etc/yum.repos.d/google-chrome.repo
RUN yum install -y google-chrome-stable \
                   libOSMesa

# fonts
RUN yum install -y google-noto-cjk-fonts \
                   ipa-gothic-fonts

build

$ docker build -t go-chrome:latest ./

コンテナ起動

$ docker run --name go-chrome-container \
             -v $(pwd)/code:/code \
             -itd go-chrome:latest /bin/bash

初期設定

プロジェクトルートディレクトリを作成

$ mkdir -p code/src/prj/

depをインストール

$ docker exec -it go-chrome-container /bin/bash -c 'go get -u github.com/golang/dep/cmd/dep'

ディレクトリが色々作成されたことを確認

$ docker exec -ti go-chrome-container /bin/bash -c 'ls /code/*'
/code/bin:
dep

/code/pkg:
dep

/code/src:
github.com  prj

dep init

$ docker exec -it go-chrome-container /bin/bash -c 'cd /code/src/prj/ && dep init'

ファイルが色々作成されたことを確認

$ docker exec -ti go-chrome-container /bin/bash -c 'ls /code/src/prj'
Gopkg.lock  Gopkg.toml  vendor

Golangのスクリプトを作成

/code/src/prj/main.go

package main

import (
    "github.com/PuerkitoBio/goquery"
    "github.com/sclevine/agouti"
    "log"
    "strings"
)

func main() {
    driver := agouti.ChromeDriver(
        agouti.ChromeOptions("args", []string{
            "--headless",
            "--disable-gpu",
            "--window-size=1280,1024",
            "--disable-dev-shm-usage",
            "--no-sandbox",
        }),
        agouti.Debug,
    )

    if err := driver.Start(); err != nil {
        log.Printf("Failed to start driver: %v", err)
    }
    defer driver.Stop()

    page, err := driver.NewPage(agouti.Browser("chrome"))
    if err != nil {
        log.Printf("Failed to open page: %v", err)
    }

    // Access to a target page
    url := "https://www.google.co.jp/"
    err = page.Navigate(url)
    if err != nil {
        log.Printf("Failed to navigate: %v", err)
    }

    // Wait for a DOM element to exist
    page.Session().SetImplicitWait(30)

    // Get screen shot
    page.Screenshot("Google.png")

    // Get title
    title, err := page.Title()
    if err != nil {
        log.Printf("Failed to get Title: %v", err)
    }
    log.Printf(title)

    // Get current url
    current_url, err := page.URL()
    if err != nil {
        log.Printf("Failed to get current url: %v", err)
    }
    log.Printf(current_url)

    // Get HTML
    getSource, err := page.HTML()
    //log.Printf(getSource)
    if err != nil {
        log.Fatalf("Failed to get HTML:%v", err)
    }

    // Parse DOM
    readerCurContents := strings.NewReader(getSource)
    doc, err := goquery.NewDocumentFromReader(readerCurContents)
    if err != nil {
        log.Fatal(err)
    }

    // Get title from DOM
    log.Printf(doc.Find("title").Text())
}

必要なモジュールをインストール

$ docker exec -it go-chrome-container /bin/bash -c 'cd /code/src/prj && dep ensure'

実行

これを実行すると、GoogleのトップページのtitleであるGoogleが表示され、Google.pngとして、スクリーンショットが作成されます。

$ docker exec -it go-chrome-container /bin/bash -c 'cd /code/src/prj && go run main.go'
Starting ChromeDriver 2.43.600233 (523efee95e3d68b8719b3a1c83051aa63aa6b10d) on port 42712
Only local connections are allowed.
2018/11/01 09:30:53 Google
2018/11/01 09:30:53 https://www.google.co.jp/
2018/11/01 09:30:53 Google

Prevent Error: Fontconfig warning: "/etc/fonts/fonts.conf", line 86: unknown element "blank"というエラーが出る場合は、/etc/fonts/fonts.confの、<blank></blank>の削除、もしくはコメントアウトをして下さい。

参考:発生したエラーについて

Esfahan
WEB系出身。現在はビッグデータの基盤構築、ETLなどがメイン。 / [YouTube] https://www.youtube.com/channel/UCeqPhExV09EF5o8lZLO15Eg / [クックパッド] https://cookpad.com/kitchen/13476667
https://www.youtube.com/channel/UCeqPhExV09EF5o8lZLO15Eg
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした