EnsekiTT Blog

EnsekiTTが書くブログです。

変更があったら教えてって言われたのでRubyとCapybaraに変更があったら教えてもらうことにした話

つまりなにしたの?

「このサイト、変化があったら教えて?」って言われたので
僕もCapybaraに「このサイト、変化があったら教えて?」とお願いした。
f:id:ensekitt:20170828025334j:plain

目的

あるWebサイトにアクセスして特定要素のTextが変化したことを知りたい
(一瞬変化して元に戻ったなどは検知する必要はない。)

検知したいもの

  • Webサイトにアクセスして特定要素のTextが変化したこと
  • Webサイトにアクセスして特定要素がなくなったこと

実現方法

  • アドレスリストとセレクタが書かれたCSVを読み込む
  • 各アドレスについて:

 初回: Capybaraで要素を取り出して保存する
 2回目以降:
  Capybaraで要素を取り出して保存する
  保存したデータ間でDiffをとる
  変化があったらSlackに変更内容と対象Webサイトへのリンクを通知する

CSVを読み取る

読み取るべきCSVの形式は
id, address, selector
とした。
idは行を識別するために適当に名前をつける
addressは対象のアドレス
selectorはCSSセレクタで例えば#blog-descriptionみたいな感じ。

csv_data = CSV.read(TARGET_CSV, headers: true)
csv_data.each do |data|
    puts data["id"]
end

Capybaraでアクセスしに行くところ

アドレスを指定して、セレクタのある場所を読み取ってくる
f:id:ensekitt:20170828025413j:plain
f:id:ensekitt:20170828025427j:plain

# カピバラのインスタンスを作成する
Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, {inspector: true, js_errors: false, timeout: 1000, phantomjs_options: ['--load-images=no', '--ignore-ssl-errors=yes', '--ssl-protocol=any']})
end
session = Capybara::Session.new(:poltergeist)
session.visit data["address"]
puts session.find(data["selector"]).text

比較をするところ

diffyをつかって比較をする。
このスニペットでは2つのファイルのdiffをとってる

File.open(TEMP + "current_file", "r") do |f|
  current = f.read
end
File.open(TEMP + "last_file", "r") do |f|
  last = f.read
  @diffs = Diffy::Diff.new(last, current)
  if @diffs.to_s.length > 0 then
    puts @diffs.to_s
  end

Slackに変更通知するところ

アタッチメント付きでSlackに通知してみた
WebHookのURLは環境変数で定義しておいた
参考:
api.slack.com

ここからWebHookを作成できる
https://my.slack.com/services/new/incoming-webhook/

作るとこんな画面になるのでWebHookを拾って環境変数に定義する
f:id:ensekitt:20170828025449j:plain

export WEBHOOK_URL=https://hooks.slack.com/services/yourwebhookurl/yourwebhookurlyourwebhookurl
  slack = Slack::Incoming::Webhooks.new ENV["WEBHOOK_URL"]

  attachments = [{
  title: "新しい変更があったみたい",
  title_link: address,
  text: msg,
  color: "#7CD197"
  }]
  slack.post "変更通知だよ", attachments: attachments

インストールと実行の方法

インストール

git clone https://github.com/EnsekiTT/check_web.git
cd check_web

# Rubyの文字コードをUTF-8にする
set RUBYOPT=-EUTF-8

# Bundlerをインストールする
gem install bundler

# Bundleでrequireファイルをインストールする(--path .bundleでローカルエリアのみ反映)
bundle install --path .bundle

実行

# ウェブフックのURL設定
export WEBHOOK_URL=https://hooks.slack.com/services/yourwebhookurl/yourwebhookurlyourwebhookurl
# 実行
bundle exec ruby check_web.rb

実行のシェルスクリプト

cd /home/yourhome/check_web
export WEBHOOK_URL=https://hooks.slack.com/services/yourwebhookurl/yourwebhookurlyourwebhookurl
bundle exec ruby check_web.rb

これをCRONで実行すればOK
ちなみに、自分はログインから15分後に実行とかにしている。

関連

久しぶりにCapybara使いました
ensekitt.hatenablog.com