web-dev-qa-db-ja.com

POST PhantomJsでの応答の要求)に添付ファイルとして含まれるファイルをダウンロードする

CSVファイルをダウンロードしたいのですが、POSTリクエストを介してボタンをクリックすると生成されます。casperJsとphantomJSフォーラムで最善を尽くして調査し、手ぶらで返しました。Firefoxのような通常のブラウザで、POSTリクエストの後にブラウザのダウンロードダイアログウィンドウが表示されます。PhantomJSでこのケースを処理する方法

TTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Content-disposition: attachment;filename=ExportData.csv
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Fri, 19 Apr 2013 23:26:40 GMT
Content-Length: 65183
17
vumaasha

Casperjsを使用してこれを行う方法を見つけました(XMLHttpRequestを使用してダウンロード関数を実装する場合はphantomjsのみで機能するはずですが、試していません)。

最近のmosをダウンロードしようとする実際の例を残しておきますPDF from this page 。ダウンロードリンクをクリックすると、JavaScriptコードがトリガーされます。いくつかの非表示の入力フィールドを生成し、それをPOSTします。

フォームのonsubmit関数を置き換えて、送信をキャンセルし、フォームの宛先(アクション)とそのすべてのフィールドを取得します。この情報は、後で実際のダウンロードを行うために使用します。

var casper=require('casper').create();
casper.start("https://sede.gobcan.es/tributos/jsf/publico/notificaciones/comparecencia/ultimosanuncios.jsp", function() {

    var theFormRequest = this.page.evaluate(function() {
        var request = {}; 
        var formDom = document.forms["resultadoUltimasNotif"];
        formDom.onsubmit = function() {
            //iterate the form fields
            var data = {};
            for(var i = 0; i < formDom.elements.length; i++) {
               data[formDom.elements[i].name] = formDom.elements[i].value;
            }
            request.action = formDom.action;
            request.data = data;
            return false; //Stop form submission
        }

        //Trigger the click on the link.
        var link = $("table.listado tbody tr:first a");
        link.click();

        return request; //Return the form data to casper
    });

    //Start the download
    casper.download(theFormRequest.action, "downloaded_file.pdf", "POST", theFormRequest.data);
});

casper.run(); 

注:使用するCAはブラウザのデフォルトのCAリストにないため、-ignore-ssl-errorsを指定して実行する必要があります。

casperjs --ignore-ssl-errors=true downloadscript.js
8
julianjm

受信時に_page.resource.received_イベントとdownload()ファイルをリッスンできます。

_casper.on('page.resource.received', function(resource) {
    if (resource.stage !== "end") {
        return;
    }
    if (resource.url.indexOf('ExportData.csv') > -1) {
        this.download(resource.url, 'ExportData.csv');
    }
});
_
3
NiKo

@julianjmアプローチがほぼ解決策ですが、私の場合、フォーム送信を置き換える正しいフォーム名がありませんでした。

だから私はphantomjsベータを使用して別の解決策を見つけました:

この問題を解決するイベントハンドラーを含むphantomjs2.0のベータ版があります。

まだベータ版なので、デバッグはありません。

そこで、リリースバージョンでクリックとページ処理を開発し、ダウンロードを機能させるためにファントムバージョンを変更しました。

 casper.start('http://www.website.com.br/', function() {
    this.page.onFileDownload = function(status){console.log('onFileDownload(' + status + ')'); 

//SYSTEM WILL DETECT THE DOWNLOAD, BUT YOU WILL HAVE TO NAME THE FILE BY YOURSLEF!!
return "ContactList_08-25-14.csv"; };

    });
      casper.then(function() {
        //DO YOUR STUFF HERE TO CLICK ON THE DOWNLOAD LINK. 
      });
    casper.run();

ダウンロード:ファントム2.0ベータ版

exeをダウンロードし、phantom.exeのリリースバージョンの名前をphantom.bkp.exeに変更し、この2.0バージョンをその場所に挿入します。次に、casperjsで、casperjs/bin/bootstrap.jsの最初にいくつかの行を追加する必要があります。

 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */
var system = require('system');
    var argsdeprecated = system.args;
    argsdeprecated.shift();
    phantom.args = argsdeprecated;

バージョンチェックにもコメントします(同じファイル):

(function(version) {
        // required version check
      /*  if (version.major !== 1) {
            return __die('CasperJS needs PhantomJS v1.x');
        } if (version.minor < 8) {
            return __die('CasperJS needs at least PhantomJS v1.8 or later.');
        }
        if (version.minor === 8 && version.patch < 1) {
            return __die('CasperJS needs at least PhantomJS v1.8.1 or later.');
        } */
    })(phantom.version);

これは微調整です!!。

したがって、bootstrapのこの行は、ファントムリリースバージョンまたはslimerjsを実行する場合に問題を引き起こします。

したがって、ダウンロードできるようにこのバージョンに微調整するよりも、リリースバージョンで開発してください。デバッグする必要がある場合は、bootstrap.jsの行を削除する必要があります

2
LeoPucciBr

ある種のASP.Netフレームワークで記述されたサイトを処理する必要があります。このサイトは、リクエストごとに大量のPOSTデータを送信します(約100 Kbデータ、そのうち約95はリクエスト間で変更されないようです-ビューポートの状態は明らかに関連しています)。

しかし、私が見つけた方法は私にはうまくいきませんでした。 XHRをインターセプトする を調べたところ、 まったく同じフレームワークに取り組んでいる人 (少なくともセレクターから判断すると)が見つかりましたが、より単純なケースで、インスピレーションを得ていますこの質問によって。 当時はこれができなかった PhantomJSであることがわかりました。

私の問題は、ボタンをクリックすると、AJAXリクエストのチェーンが開始され、この巨大なPOSTフォームが送信され、最終的にサーバーが応答することです。 「Content-Disposition:attachment」。

結局、ネットワーク効率が悪い場合でも、このアプローチがうまくいくことがわかりました。

_...setting up everything, until I just need to click on a button...

phantomData    = null;
phantomRequest = null;

// Here, I just recognize the form being submitted and copy it.

casper.on('resource.requested', function(requestData, request) {
    for (var h in requestData.headers) {
        if (requestData.headers[h].name === 'Content-Type') {
            if (requestData.headers[h].value === 'application/x-www-form-urlencoded') {
                phantomData         = requestData;
                phantomRequest      = request;
            }
        }
    }
});

// Here, I recognize when the request has FAILED because PhantomJS does
// not support straight downloading.

casper.on('resource.received', function(resource) {
    for (var h in resource.headers) {
        if (resource.headers[h].name === 'content-disposition') {
            if (resource.stage === 'end') {
                if (phantomData) {
                    // to do: get name from resource.headers[h].value
                    casper.download(
                        resource.url,
                        "output.pdf",
                        phantomData.method,
                        phantomData.postData
                    );
                } else {
                    // Something went wrong.
                }
                // Possibly, remove listeners?
            }
        }
    }
});

// Now, click on the button and initiate the dance.
casper.click(pdfLinkSelector);
_

ファイルが要求(および送信)された2回されていることがわかったとしても、ダウンロードは問題なく機能します。

_[debug] [phantom] Navigation requested: url=https://somesite/SomePage.aspx, type=FormSubmitted, willNavigate=true, isMainFrame=true
[debug] [application] GOT FORM, REQUEST DATA SAVED
[warning] [phantom] Loading resource failed with status=fail (HTTP 200): https://somesite/SomePage.aspx
[debug] [application] END STAGE REACHED, PHANTOMDATA PRESENT
[debug] [application] ATTEMPTING CASPERJS.DOWNLOAD
[debug] [remote] sendAJAX(): Using HTTP method: 'POST'
[debug] [phantom] Downloaded and saved resource in output.pdf
[debug] [application] TERMINATING SUCCESSFULLY
[debug] [phantom] Navigation requested: url=about:blank, type=Other, willNavigate=true, isMainFrame=true
[debug] [phantom] url changed to "about:blank"
_

(次に、スクリプトを変更して、_resource.requested_リスナー内からrequest.abort()を呼び出し、セマフォを設定して、ダウンローダーを再度呼び出します。添付ファイルのファイル名を取得できません。 、しかしそれは私にはほとんど関係ありません)。

0
LSerni