Help us understand the problem. What is going on with this article?

Capybara+PhantomJSでCSVをダウンロード

More than 3 years have passed since last update.

フォームやリンクからCSVをダウンロードしたい場合があるかと思いますが、PhantomJSが現行バージョンではContent-Dispositionで返ってきたレスポンスを受け取ってくれません。

https://github.com/ariya/phantomjs/issues/10052

とはいえ、どうしてもファイルを受け取りたい場合があったので、結構強引だけど実装してみた(実際に書いたコードは複雑なので、エッセンス部分だけ)。

まず「クリックしたいボタンのPOSTをAjaxでエミュレートして結果コンテンツを戻す関数」をJavaScriptで書き、定義をぶっ込む。

page.execute_script(%!
  window.getCsv = function(target){
    var efn = document.querySelector("input[value='"+target+"']");
    if (efn) {
      var f = efn.parentNode;
      var es = f.getElementsByTagName("input");
      var query_str = "";
      for (var i=0; i<es.length; i++) {
        var name = es[i].getAttribute('name');
        var val  = es[i].getAttribute('value');
        if (name) {
          query_str += name + '=' + val + '&';
        }
      }
      var xhr = new XMLHttpRequest();
      xhr.open(f.getAttribute('method'), f.getAttribute('action'), false);
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xhr.send(query_str);
      return xhr.responseText;
    }else{
      return "";
    }
  }
!)

関数の中身は、適当に。対象ページによって全然変わってくるだろうし、jQueryなどをインジェクトしてあればもっと簡単に書けるはず。

そして、必要な場面でCSVを取り出す。

ret = page.evaluate_script("getCsv('#{target}')")
ret.split("¥r¥n").each do |line|
  # do something
end

RubyとJavaScriptが錯綜して少しトリッキーだけど、基本的には認証やCSRF対策が施されたページでも動くはず。

nao58
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away