ラベル Ruby の投稿を表示しています。 すべての投稿を表示
ラベル Ruby の投稿を表示しています。 すべての投稿を表示

2013/09/23

Ruby & Mechanize を使ったWeb上の情報の自動取得

Webからの情報取得の自動化

昔と違って最近は使用量やら請求額やらいろいろなデータがWeb上で見られるようになったので、便利になった。
けど、ほとんどのものは自分から見に行く必要があるため、じきに面倒になって見に行かなくなってしまう。

ということで、どうせならPush通知させたい! と思った。

Mechanize

最初は全部自前でParser書いて所望の情報を取得しようと思っていたけど、Cookieの処理等々面倒で挫けかけていた。
ところが、調べてみたら便利なシロモノを発見。

どうやら、RubygemsにあるMechanizeを使えば、その辺りを気にせずに作れるらしい。
gem install mechanize
でさくさくとインストールして使ってみた。

参考:
以下、軽く使ってみたところで気づいた嬉しい点と要注意点。

嬉しい点

  • Cookieの処理を気にしなくてもいい
  • Formの処理がとっても楽

要注意点

  • frameを使ったサイトでどちらかのframe内のFormを触る場合などは、まずはそのframeの取得が必要
  • Javascriptの処理までは自動的に処理してくれないので、FormにJavascriptが絡んでいる場合などはソースを解析してJavascriptで処理されている部分の模擬が必要
  • TLSv1のみ対応のサイトの場合、追加でオプションが必要(後述)

ハマったポイント

Javascriptによる自動転送

某サイトが、
リンクをクリック → OTP取得用?のページを表示 → Javascriptで自動的に転送 → メインのページを表示
という手順を踏んでいて、ブラウザで表示した際には間のページの存在に気づかず、次のページをMechanizeで表示させようとしてもエラーページに飛ばされるばかりだった。 一歩一歩調べたところ間のページの存在に気づいたため、Javascriptで処理している箇所をMechanizeに行わせるようにした。

TLSv1のみ対応のサイト

某クレジットカード会社のhttpsなログインページを取得しようとしたところ、
SSL_connect SYSCALL returned=5 errno=0 state=unknown state (OpenSSL::SSL::SSLError)
というエラーが出て取得が失敗した。 どうやらTLSv1にのみ対応なサイトにそのまま取得しようとしたことによるエラーの可能性が高そうだったため、下記のようにTLSv1でhttpsの接続を行うように指定したところ、問題なく接続できるようになった。
agent.ssl_version = 'TLSv1'
参考:

作ってみたもの

以前Nokogiriを使って下記のものをcronで定期的に取得して携帯のメールアドレスに送信するようにしていた。
  • 天気予報
  • 近隣の鉄道の運行状況
今回Mechanizeを使うことで、下記のものを取得できるようになった。
  • IIJmioの利用状況
  • クレジットカードの請求額

いくつかハマりポイントはあったものの、必要な情報のPush通知っぽいことがだいぶできるようになってきた。

2013/02/19

Ruby1.8でSegmentation fault

個人的にはRubyが好きなので、個人的に作ったスクリプトはRubyなことが多いのだが…
Rubyのバージョンアップをしたら、こんなエラーが出るようになってしまった。

/usr/lib/ruby/1.8/timeout.rb:60: [BUG] Segmentation fault
ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux]

Aborted (core dumped)

いろいろ調べてみると、Mac OS Xの場合はコンパイラをgccにすれば解決するらしいが、Ubuntuの場合どうすればいいのかがよくわからなかった。
ただ、この事象はRuby 1.8系統でだけ発生しているように見えた。
ということで、Rubyを1.8系統から1.9系統に変更。

Ruby 1.9系では $KCODE が廃止されてたので文字コード周りの変更はする必要はあったけど、それ以外に大きな変更なく問題なく動作した。