以前に
SeleniumとPythonで定期実行処理を作ってみた
をやったのだが、いつの間にか動作しなくなった……
で、最新のfirefox、seleniumで再度環境構築しても中々上手くいかない……
(geckodriverが必要?implicitly_waitが効かない?centos6じゃダメ?同時並行で実行できない?等々、いろいろな経緯を辿ってますが、忘れたので詳細割愛)
ということで、CentOS7およびChromeに切り替えて環境構築してみました。
環境
- CentOS Linux release 7.3.1611 (ConoHa VPS)
- Python 2.7.5
- Selenium(python) 3.3.3
- Xvfb 1.17.2
- google-chrome-stable 58.0
- ChromeDriver 2.29
構築
Selenium
yum install python-pip
pip install selenium
Xvfb
yum install xorg-x11-server-Xvfb
vim /usr/lib/systemd/system/Xvfb.service
[Unit]
Description=Virtual Framebuffer X server for X Version 11
[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/Xvfb
ExecStart=/usr/bin/Xvfb $OPTION
ExecReload=/bin/kill -HUP ${MAINPID}
[Install]
WantedBy=multi-user.target
vim /etc/sysconfig/Xvfb
# Xvfb Enviroment File
OPTION=":1 -screen 0 1366x768x24"
systemctl enable Xvfb
systemctl start Xvfb
Chrome
vim /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
yum install google-chrome-stable
日本語表示のために
yum install ipa-pgothic-fonts.noarch
ChromeDriver - WebDriver for Chrome : Downloads
から適切なドライバーをダウンロード。今回はバージョン2.29。
wget http://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
mv chromedriver /usr/local/bin
rm chromedriver_linux64.zip
- itamae
上記構築内容を構成管理ツール「itamae」に落とし込んでみました。よければ、どうぞ。
=> https://github.com/kotanbo/itamae-selenium-centos7
(一部(Xvfb)にCentOS6のパターンが記載されていますが、CentOS6での構築は途中で諦めました……)
実装
ChromeDriver - WebDriver for Chrome : Getting started
を参考にサンプルとしては以下です。
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import os, time, datetime, re, util, sys
import selenium.webdriver.chrome.service as service
class Sample():
def __init__(self):
self.aservice = service.Service('/usr/local/bin/chromedriver')
self.aservice.start()
capabilities = {'chrome.binary': '/usr/bin/google-chrome-stable', "chromeOptions": {"args": ['--no-sandbox']}}
self.driver = webdriver.Remote(self.aservice.service_url, capabilities)
self.driver.implicitly_wait(3)
self.base_url = "http://example.jp/"
def __del__(self):
self.driver.close()
def sample(self):
driver = self.driver
try:
driver.get(self.base_url + "/home")
driver.find_element_by_xpath("//a[@id='LoginButton']/img").click()
except:
finally:
sample = Sample()
sample.sample()
0 9 * * * export DISPLAY=localhost:1.0; python /root/selenium/sample.py
0 9 * * * export DISPLAY=localhost:1.0; python /root/selenium/sample.py
0 4 * * * pkill -KILL -f chromedriver
ポイント
- 本環境ではchromeの起動オプションで「--no-sandbox」を付与しないとエラーとなりました。
- 「selenium.webdriver.chrome.service」を使わない実装だと、cronサンプルのように同時並行で実行できないかと思います。
- 「self.driver.close()」にてchromeプロセスは終了しますが、ChromeDriverのプロセスは残るので、cronで「0 4 * * * pkill -KILL -f chromedriver」等でプロセスをkillしておけばいいかと思います。