メイン

[Ruby] MechanizeでEOFError?

こんにちわ。ばたっちです。

WWW::Mechanizeでサイトを巡回していて、EOFErrorになることがあったので覚書。

エラーの内容は以下のとおり。


/usr/lib/ruby/1.8/net/protocol.rb:133:in `sysread': \
  end of file reached (EOFError)
        from /usr/lib/ruby/1.8/net/protocol.rb:133:in `rbuf_fill'
        from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout'
        from /usr/lib/ruby/1.8/timeout.rb:76:in `timeout'
        from /usr/lib/ruby/1.8/net/protocol.rb:132:in `rbuf_fill'
        from /usr/lib/ruby/1.8/net/protocol.rb:116:in `readuntil'
        from /usr/lib/ruby/1.8/net/protocol.rb:126:in `readline'
        from /usr/lib/ruby/1.8/net/http.rb:2017:in `read_status_line'
        from /usr/lib/ruby/1.8/net/http.rb:2006:in `read_new'
        from /usr/lib/ruby/1.8/net/http.rb:1047:in `request'
        from /usr/lib/ruby/gems/1.8/gems/mechanize-0.6.10/lib/\
  mechanize.rb:514:in `fetch_page'
        from /usr/lib/ruby/gems/1.8/gems/mechanize-0.6.10/lib/\
  mechanize.rb:185:in `get'
        from test.rb:19
正確なパターンは分からないのですが、以下のようにJavaScriptファイルの取得前後でエラーになるようでした。
  • 「http://~/test1.html」のように最初のページをGETする
  • 相対パス指定で次のページをGETする (A)
  • 相対パス指定でJavaScriptをGETする
  • backメソッドで履歴を戻る
  • 相対パス指定で(A)のページなどを再GETする
特定の条件で発生するのか、一般的なサイトで同じ動作をさせても再現できなくて、具体的なサンプルを示せません。。orz

直接関係あるかは分かりませんが、気になった点は次のとおり。

  • サーバがIIS
  • Content-Typeが「application/x-javascript」(通常は text/javascript)
結論を言うと、Mechanize の keep_alive を無効にするとうまくようです。 ※サンプルコードはイメージです。

原因がはっきりしないので気持ち悪いですが、とりあえずうまく行きました。(^^)v
同じような現象に会った人いるかな?

トラックバック

このエントリーのトラックバックURL:
http://pw.tech-arts.co.jp/cgi-bin/tamt32/mt-tb.cgi/71

コメント

同じ現象にぶつかって、keep_alive = falseで解決しました。とても助かりました。

原因はあまり調べていないので、さっぱりわからずです。同じように再現性に問題があって、サーバによってはときどきなるものと、いつもエラーが出るものがありました。

同じ現象に会われた方がいたとは。。A^^;
無事解決されたようでよかったです♪

ときどき発生するケースもあるのですね。私が試していたサイトでは、あるパターンで必ず発生していました。

すごい今更ですが、Net::HTTP の仕様だかバグのせいかと。
keep-alive 接続がタイムアウト後にソケットからデータを読もうとすると EOFError が出るようになっているみたいです。

すごい忘れた頃に~ A^^;

やっぱり、Keep-Alive周りに問題がありそうなんですね。
最新版ではどうなってるのかな。。?

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)