Dockerイメージの作成
環境を汚したくないので、Dockerを使います。
Dockerfile中のgoogle-chromeの内容は
EC2 UbuntuでGoogle Chromeをヘッドレス実行してスクリーンショットを採取する手順を参考にしています。
Dockerfile
FROM python:3.6-stretch
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get install -y --no-install-recommends unzip wget curl unzip fontconfig && \
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - && \
echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | tee /etc/apt/sources.list.d/google-chrome.list && \
apt-get update && \
apt-get -y install --no-install-recommends google-chrome-stable
RUN apt-get update && \
apt-get install -y --no-install-recommends python3-dev python3-pip && \
rm -rf /var/lib/apt/lists/*
RUN pip3 install selene --pre
RUN wget https://chromedriver.storage.googleapis.com/2.31/chromedriver_linux64.zip && \
unzip chromedriver_linux64.zip -d /usr/bin/
WORKDIR /data
VOLUME /data
COPY IPAfont00303.zip /data/IPAfont00303.zip
RUN unzip IPAfont00303.zip -d /usr/share/fonts/ && \
fc-cache -fv
IPAfont00303.zipファイルのダウンロードはDockerfile中にwgetすると終了コードがエラーになって失敗するため事前にzipファイルでダウンロードしておき、ビルド時にホストからコピーします。
MyDNS.jp更新用のスクリプト作成
Python経由でSeleniumを使用して更新を行います。
Selenium単体だと要素の指定が面倒なため、
CSSセレクタなどで要素の選択ができる「Selene」を使用します。
※Seleneの導入については、Selene : Python にも Selenide ライクな Selenium ラッパーありますを参考にさせて頂きました。
mydns.py
# -*- coding: utf-8 -*-
import os
import traceback
import sys
import logging
from selene import config
from selene.browsers import BrowserName
from selene.api import *
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def main():
args = sys.argv
logger = logging.getLogger(__name__)
username = os.getenv("MYDNS_USER", "guest")
password = os.getenv("MYDNS_PASS", "password")
if len(args) < 2:
raise ValueError("Please specify one of the least argument")
options = Options()
# google-chromeのインストールパス指定
options.binary_location = '/usr/bin/google-chrome'
# ヘッドレスモードで起動
options.add_argument('--headless')
options.add_argument('--no-sandbox')
# 画面サイズ指定
options.add_argument('--window-size=1280,1024')
driver = webdriver.Chrome('chromedriver', chrome_options=options)
config.browser_name = BrowserName.CHROME
browser.set_driver(driver)
# Mydnsトップページを開く
browser.open_url('https://www.mydns.jp/')
# ユーザー名,パスワード入力してログインボタンをクリック
setvalue_nophoto('dd.content12:nth-child(3) > input:nth-child(1)',username)
setvalue('dd.content12:nth-child(5) > input:nth-child(1)',password)
clickbutton('dd.content12:nth-child(7) > input:nth-child(1)')
# IP ADDE DIRECTを選択
clickbutton('''body > table:nth-child(1) > tbody:nth-child(1) >
tr:nth-child(4) > td:nth-child(1) > table:nth-child(1) >
tbody:nth-child(1) > tr:nth-child(5) > td:nth-child(1) >
a:nth-child(1) > img:nth-child(1)''')
# IP v4アドレスをセット
setvalue('dd.content14:nth-child(4) > input:nth-child(1)',args[1])
# checkボタン押下
clickbutton('dd.content12:nth-child(9) > input:nth-child(1)')
# okボタン押下
clickbutton('''table.content14:nth-child(3) > tbody:nth-child(1) >
tr:nth-child(6) > td:nth-child(1) > input:nth-child(1)''')
driver.quit()
def setvalue(cssselector,value):
setvalue_nophoto(cssselector,value)
browser.take_screenshot("mydns")
def clickbutton(cssselector):
clickbutton_nophoto(cssselector)
browser.take_screenshot("mydns")
def setvalue_nophoto(cssselector,value):
s(by.css(cssselector)).set_value(value)
def clickbutton_nophoto(cssselector):
s(by.css(cssselector)).click()
if __name__ == '__main__':
main()
要素のCSSセレクタはブラウザからの取得そのままなので、最適ではない可能性があります。
第一引数には設定するIPv4アドレスを設定します。
Jenkinsで定期実行してみる
jenkinsfile
pipeline {
agent {
docker {
image '(ビルドしたdockerイメージ名)'
}
}
environment {
MYDNS_USER="(mydnsのユーザー名)"
MYDNS_PASS="(mydnsのパスワード)"
}
stages() {
stage('update-mydns')
{
steps() {
checkout scm
script {
def ipaddress = globalip()
sh script: 'python mydns.py ' + ipaddress
archiveArtifacts artifacts: 'mydns/*.png'
}
}
}
}
}
def globalip() {
sh (
returnStdout: true,
script: '''
curl ifconfig.io
'''
)
}
archiveArtifactsしておけば、Selenium中で取得したスクリーンショットの保存が行えます。