Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@Esfahan

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

概要

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>の削除、もしくはコメントアウトをして下さい。

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

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
4
Help us understand the problem. What are the problem?