🤖
保育園の体温入力を自動化する
きっかけ
- 今までは毎日紙に書いて提出していたものがWebで入力する方式に変更になった
- Webでの入力はログインや画面遷移など今までよりも時間がかかる
- 「Hey Siri」で入力ができれば手間がないのでは?
システム構成
システム構成は以下のとおりです。
- iPhoneもしくはApple Watchから「ショートカット」で体温を入力
- ショートカットは音声入力の内容を取り出してWebhookをキックする事ができる
- 体温の情報を埋め込んだコードをWebhookでSlackに投稿する
- サーバ上のSlackボットが上記のコードに反応して体温情報を抜き取り、スクリプトを起動
- ショートカットをトリガーにRaspberryPiを動作させたかったのでSlackとHubotを利用
- スクリプトでWebサイトを操作して体温を自動入力する
「ショートカット」を使うと任意のサービスのWebhookをキックする事ができます。IFTTTなどのサービスとの連携など色々幅が広がります。
必要な知識, ハード, 事前準備
- Raspberry Piなどのサーバ
- Linuxの知識 (cron, aptなどでの必要なソフトの導入)
- 基本的なプログラミング知識(RubyとかPythonとか)
- Slackアカウントの作成と、Slackボットの作成(Hubot)
- Webサイトのログイン情報
- HTML, JavaScriptなどに対する基本的な知識
- iPhoneで任意のショートカットを作成する(音声で数値を入力してWebhookを実行します)
この記事では、主にWebサイトの操作(プログラム)についてフォーカスしています。
cronの設定方法やSlackの設定などは他の人の記事などを参考にしてください。
ある程度のことは、ご自分で調べて解決できる人を対象にしています。
ブラウザの操作を自動化する
ポイント
- Seleniumなどのヘッドレスブラウザが必要
- 対象のサイトがAjaxを使っているので、ヘッドレスのブラウザがないと上手く操作できない
- 今回はPhantomJSを利用
- PhantomJSは開発が停止している
- これからやる人はSeleniumを使った方が良い
- 導入方法は他の人の記事を参考にしてください
- Rubyで実装(Pythonとかの方が情報が多いけど、Rubyが好きだから)
- Capybaraを利用(Webのテストとかで使われる)
- ボタンを押したりとか、画面遷移の記述が楽になる
- 色々試したけど、体温入力画面にURLを指定して直接遷移させることにした
- ログイン画面からボタンを押して遷移していく場合、Ajaxのロードとか待ったりとかでうまくいかなかった
- この辺りは、対象のシステム毎に調整が必要
プログラム
実際に作成したプログラムはこちらです。
(サイトのURLなどは別の物に変えてあります)
実行引数に体温が渡される仕様にしています。
#!/usr/bin/ruby
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
require 'nokogiri'
require 'open-uri'
Capybara.configure do |config|
config.run_server = false
config.default_driver = :poltergeist
config.javascript_driver = :poltergeist
config.app_host = "https://example.com" # 対象のサイトのURL
config.default_max_wait_time = 60
config.ignore_hidden_elements = false
end
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {
:timeout=>120,
js_errors: false,
phantomjs_options: [
'--load-images=no',
'--ignore-ssl-errors=yes',
'--ssl-protocol=any'
]
})
end
module Crawler
class Bluemix
include Capybara::DSL
def login(username, password)
page.driver.headers = { "User-Agent" => "Mac Safari" }
visit('/parent/secure/ログインページのパス')
fill_in 'txtID', with: username
fill_in 'txtPASS', with: password
click_on 'ログイン'
#doc = Nokogiri::HTML.parse(page.html)
#pp doc
end
def inputTemp(value)
# ご家庭よりに遷移 (直接URLで遷移する)
visit('/parent/secure/体温入力先のパス.aspx')
s = value.split(".")
select s[0], :from => 'ddlTEMPERATURE1'
select s[1], :from => 'ddlTEMPERATURE2'
select '特に無し', :from => 'grdFREE_ctl02_ddlNAIYO'
select '無', :from => 'grdFREE_ctl03_ddlNAIYO'
click_on '登録'
page.accept_confirm
end
end
end
# 数値かどうか判定します
def is_numeric?(text)
true if Float(text) rescue false
end
# __main__
if ARGV.size < 1
exit 1
end
temp = ARGV[0]
exit 2 if !is_numeric?(temp)
crawler = Crawler::Bluemix.new
crawler.login("ユーザID", "パスワード")
crawler.inputTemp(temp)
Discussion