notebook

都内でWEB系エンジニアやってます。

centos7 + headless chromeでスクレイピング

chromeスクレイピングで使う必要があったので開発環境から作ってみたときのメモ

特にメモすら必要ないかもしれないくらい環境整ってるなと感じました

google chrome

  • install
yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm

これで一発

  • 試してみる
[root@localhost ~]#  google-chrome --headless --screenshot --window-size=1024,2000 --hide-scrollbars http://swfz.hatenablog.com/
[1026/040341.372041:ERROR:zygote_host_impl_linux.cc(88)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
[root@localhost ~]#  google-chrome --headless --screenshot --window-size=1024,2000 --hide-scrollbars --no-sandbox http://swfz.hatenablog.com/
shared memfd open() failed: Invalid argument
[1026/040521.768393:ERROR:service_manager.cc(156)] Connection InterfaceProviderSpec prevented service: content_renderer from binding interface: blink::mojom::BudgetService exposed by: content_browser
[1026/040524.788707:ERROR:BudgetService.cpp(167)] Unable to connect to the Mojo BudgetService.
[1026/040535.388908:INFO:headless_shell.cc(503)] Written to file screenshot.png.
[root@localhost ~]# ls
screenshot.png

普通にできた

rootで実行してると--no-sandboxオプションをつけないと怒られる

フォントのインストール

これだけだと日本語が表示されないのでnotofontを入れておく

# mkdir notofont
# cd notofont
# curl -LO https://noto-website-2.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip
# unzip NotoSansCJKjp-hinted.zip
# cp *.otf /usr/share/fonts/noto/
# chmod 644 /usr/share/fonts/noto/*.otf
# fc-cache -fv

最後644にするの忘れがちですがポイントです、落としてきただけだと640になっててアプリケーションユーザーから実行してもfont読み込めないので適用されない...

従ってインストールしてるのに日本語出ない!といったことになります、まぁ基本だろって話ではあるんですが見落としがち

f:id:swfz:20171130040353p:plain

しっかりスクリーンショット取れました

capybara経由で使ってみる

rubychromeを扱うためのchromedriverをインストールする必要があるがchromedriver-helperをインストールすることでその辺りをよしなにやってくれる

  • Gemfile
source 'https://rubygems.org'
gem 'capybara'
gem 'selenium-webdriver'
gem 'chromedriver-helper'

設定側はこんな感じ

      Capybara.register_driver :selenium do |app|
        Capybara::Selenium::Driver.new(
          app,
          browser: :chrome,
          desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
            chrome_options: {
              args: %w(headless disable-gpu window-size=1920,1200),
            }
          )
        )
      end
      Capybara.default_selector  = :xpath
      Capybara.configure do |config|
        config.default_max_wait_time = 10
        config.default_driver = :selenium
      end
      @session = Capybara::Session.new(:selenium)
  • app.rb

実際のファイルはこんな感じ

#!/usr/bin/env ruby

require 'nokogiri'
require 'capybara'
require 'selenium-webdriver'

class Scraper
  attr_reader :session

  def initialize
    Capybara.register_driver :selenium do |app|
      Capybara::Selenium::Driver.new(
        app,
        browser: :chrome,
        desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
          chrome_options: {
            args: %w(headless disable-gpu window-size=1024,768),
          }
        )
      )
    end
    Capybara.default_selector  = :xpath
    Capybara.configure do |config|
      config.default_max_wait_time = 60
      config.default_driver = :selenium
    end
    @session = Capybara::Session.new(:selenium)
  end

  def execute
    url = 'https://twitter.com/?lang=ja'

    session.visit url

    session.save_screenshot('twitter.png')

  end
end

Scraper.new.execute

こちらも特に問題なくスクリーンショットまで取れました

f:id:swfz:20171130040416p:plain

まとめ

  • rpmでstable chromeインストール
  • notofontインストール
  • gemでchromedriver-helperインストール

(゚д゚)ウマー

productionはいつも通りamazon linuxでやりたかったので一応使えるように試みたものの挫折してubuntuで動かすことにしました :(