rubyとcrontabで毎朝、休講情報を取得するプログラムを作成した話
はじめに
私は、学内アルバイトとして、TA(Teaching Assistant)をしている。基本的な業務は、簡単なエクセルの使い方やワードの使い方などを教えている。 しかし、TAは授業を履修していないため、休講情報の通知が来ない。
休講情報はベーシック認証があるサーバに存在しており、自動で取得し通知することを考えた。
ロジック
--- ruby ---
- 外部からアクセス可能(basic認証)なウェブサイトの休講情報を取得する
- 整形させる
- 当日の休講情報を抽出/出力
crontabで、上記のプログラムを毎朝実行し、メールする。 これらを、ウェブサービスを公開するために借りたVPSにおいておく。
http://hagetak.hatenablog.com/entry/2015/02/20/232004
書いてみた。
require 'nokogiri' require 'mechanize' agent = Mechanize.new agent.add_auth('http://www.gakkounowebsite.info/', 'userid', 'password') @page = agent.get('http://www.gakkounowebsite.info/?page_id=1028') @content = @page.search('.entry-content') @class_datas = [] # 検索用 => "6月12日"という文字列を検索するために b = Time.now @today = "#{b.month}月#{b.day}日" # <p>6月12日 情報倫理<br>\n 教室:1201教室... </p> # <p>6月12日 財務諸表<br>\n 教室:1203教室... </p> # => ['6月12日 情報倫理...', '6月12日 財務諸表'] @content.xpath("//p").each do |c| @class_datas << c end a = [] @sending_datas = [] # [0] => date # [!0] => className, teacher, remarks # @class_datas[0] => "6月22日(月)\n 2限:情報演習・基礎 \n 担当:斉藤先生 \n 補講:課題指示あり" # a[0] => ["6月22日(月)", "2限:情報演習・基礎", "担当:斉藤先生", "補講:課題指示あり"] @class_datas.each do |info| a << info.text.split("\n") end # 本日休講の項目を取得 a.each do |s| s[0].tr!("0-9", "0-9") @sending_datas << s if(s[0].to_s.match(@today)) end puts '休講情報はありません' unless @sending_datas @sending_datas.each do |s| puts '*** ' * 10 puts s end
今こうしてみると、読みづらく、気持ち悪いね。整形作業に手間がかかってる感じ。もう少し簡単にできないだろうか...。
crontabの設定
crontabについて学んだことは、後日記事にする。 さて、このプログラム(fetch_class_info.rb)をcrontabで動かしたいと思う。
いかのプログラムを書いて、動かしている。
35 7 * * * /home/hagetak/.rbenv/shims/ruby /home/hagetak/cron/fetch_class_info.rb | mail -s `echo $(date +'\%Y/\%m/\%d')休講情報` your_email_address@domain.com
一つ一つ見てみると、わかるだろう。
minites hour * * * [実行するプログラム]
という感じで、この例では、毎日7時35分に実行するプログラムだ。所有者・実行者が違うと、PATHが通っていない可能性があるので、絶対参照でプログラムを実行させることにした。
実行させたい大本のプログラム(ruby だったり, pythonだったり...)は、whichコマンドで確認することができる。
> which ruby => /home/hagetak/.rbenv/shims/ruby
ruby yourprogram.rb
で実行できるので、rubyファイルは絶対参照で記述。
次のステップは、少しややこしい。(件名を日本語/変更したくない場合はこの処理は飛ばして良い)
mail -s
echo $(date +'\%Y/\%m/\%d')休講情報
your_email_address@domain.com
実行した結果を mail コマンドに受け渡し、送信するというモノだ。
echo $(date +'\%Y/\%m/\%d')休講情報
これは、いつの休講情報かわからないために追加したもの。
crontabのshに問題があるため、dateコマンド内の%はバックスラッシュでエスケープすること
この処理で引っかかって、1日ずっと考えていた...。
dateコマンド と crontab の コマンドライン中の %(パーセント)記号 - keigoiの日記
さて、これらをまとめると、以下に置き換えられるだろう。
result of your program | mail -s "件名" your_email_address@domain.com
cron処理結果を、subjectを日本語にしてメールする方法 | Web開発者の備忘録
知見
- いきなり毎朝...で設定すると気が遠くなるので、以下に変更すると良い(毎分)
*/1 * * *
- メールが届かない!ってときは、次のコマンドを打つと出ている
- 件名とかいらない。ってときは簡略なものでできる
MAILTO="your_email_address@domain.com" */2 * * * * /usr/bin/ruby /Users/hagetak/cron/fetch_class_info.rb