昨年、GoogleAppEngineとGoogleAppsScriptなどを使い、アルクマスケジュールでいろいろと試してみていました。
ただ、アドベントカレンダー用に急ごしらえで作った部分もあり、正直12月以降についてはあまり考慮していなかったため、残念な部分が残っていました。
そのため、アルクマスケジュールをGoogleカレンダー化する部分を、Rubyを使って改良してみました。
なお、Googleカレンダーへ登録する際は、削除後の新規登録としています。
また、以前作ったアプリに対応させるためだけを目的として作ったため、イベントの開始・終了時刻があるものも終日の予定としています。
■環境
他には、Google Calendar API を有効化し、「CLIENT ID」などの認証キーを取得しておきます。詳しくは前回の記事を参照して下さい。
Windows7 + Ruby + google-api-clientで、GoogleAPI向けOAuth認証用のYAMLファイルを取得する - メモ的な思考的な
■調べたことなど
ジオコーディングについて
今回もジオコーディングはGoogle Geocoding APIを使用することにしました。APIをそのまま使っても良かったのですが、他のジオコーディングAPIを呼べそうなgemの「geocoder」があったため、そちらを使うことにしました。
ただ、連続してGoogle Geocoding APIを呼び出すと制限に引っかかるため、呼び出しは1秒に1回としています。
以下のような感じで使っています。
Geocoder.configure(lookup: :google, language: :ja, timeout: 5) geo_params = { countrycodes: 'ja' } begin result = Geocoder.search(place, params: geo_params) if result.size > 0 result.first.coordinates.join(',') else DEFAULT_LAT + ',' + DEFAULT_LNG end rescue Exception => e puts $! DEFAULT_LAT + ',' + DEFAULT_LNG end
なお、緯度経度を取得していろいろとやるには、Geocoder.searchの戻り値(result)を
result.first.coordinates.join(',')
のようにGeocoder::Result::Google#coordinatesメソッドを使って取得するか、
result.first.geometry["location"]["lat"].to_s + ',' + result.first.geometry["location"]["lng"].to_s
のようにハッシュから取得します。
Geocoder.searchの結果は以下が参考になりました。
Ruby geocoderがすごい - もぎゃろぐ
スクレイピングについて
「nokogiri」gemを使いました。
なお、アルクマスケジュールを確認すると、前後に改行コードやスペースが入っていることが多かったため、以下のように改行やスペースを消すようにしました。
item.xpath(xpath).text.gsub(/(\r\n|\r|\n)/, '').strip
カレントディレクトリのrequireについて
「require_relative」を使って読み込みました。
Ruby1.9.2以降でrequireする際の注意点 - Qiita
Rubyのrequireで相対的にパスを指定する方法 - QA@IT
一件目の削除について
今回の作り方だと、一件目にタイトルが入ってくるため、dropメソッドを使って削除しました。
@doc.xpath('//div[@class="schedule aug"]/table/tr').drop(1).each do |item| # hoge end
How to act differently on first iteration in a Ruby loop? - Stack Overflow
google-api-clientにアプリ名とバージョンを渡す
渡さないとワーニングが出たため、、適当なものを渡しました。
google-api-clientのコマンドライン版でも、アプリ名などを渡しているようです。
https://github.com/google/google-api-ruby-client/blob/master/bin/google-api#L166
Events#listについて
日付については、今のところは以下を参考にUTCのISO8601形式で設定します。
[Ruby]Google Calendar APIでカレンダーを取得するスクリプト - Blogaomu
以下のIssueが閉じられれば、今後やり方が変わるかもしれません。
When providing parameters to execute(), + is replaced by space · Issue #38 · google/google-api-ruby-client · GitHub
また、以下のパラメータも追加しています。
- singleEvents: このパラメータが無いと、手元のカレンダーでは取得できるイベント数が不定になっていた
- maxResults: デフォルト値が不明なので、取得する件数を確実にするため*1
- showDeleted: 削除したイベントを取得しないと明確にするため
Events: list - Google Calendar API — Google Developers
■参考
NokogiriやXPathについて
*1:300件/月のイベントは、さすがに無いはず...