在PhantomJs中下载POST请求响应中附件的文件

时间:2013-04-22 09:58:22

标签: phantomjs casperjs

我想下载一个CSV文件,它是通过POST请求点击按钮生成的。我在casperJs和phantomJS论坛上进行了最好的研究并空手而归。在像firefox这样的普通浏览器中,在发布请求后会出现浏览器下载对话窗口。如何在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

4 个答案:

答案 0 :(得分:8)

我已经找到了一种方法来使用casperjs(如果你使用XMLHttpRequest实现下载功能,它应该单独使用phantomjs,但我还没试过)。

我会留下一个工作示例,试图从this page下载最近的最新PDF文件。当您单击下载链接时,会触发一些javascript代码,生成一些隐藏的输入字段,然后进行POST。

我们所做的是替换表单提交功能,以便取消提交,并获取表单目标(操作)及其所有字段。我们稍后会使用此信息进行实际下载。

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(); 

注意:您必须使用--ignore-ssl-errors运行它,因为他们使用的CA不在您的浏览器默认CA列表中。

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

答案 1 :(得分:3)

收到时,您可以收听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');
    }
});

答案 2 :(得分:2)

@julianjm aproach几乎是解决方案,但在我的情况下,我没有正确的表单名称来替换表单提交。

所以我找到了另一个使用phantomjs beta的解决方案:

有一个测试版的phantomjs 2.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();

下载: Phantom 2.0 BETA

下载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);

请记住,这是一个调整!!

因此,如果您想运行幻像发布版本或slimerjs,那么引导程序中的这些行将导致问题。

所以开发发布版本,而不是调整到这个版本才能下载。 如果需要调试,则必须删除bootstrap.js

的行

答案 3 :(得分:0)

我必须处理一个用某种ASP.Net框架编写的网站,该框架在每次请求时发送大量的POST数据(大约100 Kb的数据,其中大约95个似乎永远不会在请求之间发生变化 - 视口状态显然相关)。

但是,我找不到任何方法。我调查了intercepting XHR,我甚至找到了someone who is tackling the very same framework(至少从选择者那里判断)但是在一个更简单的情况下,受到这个问题的启发。我发现了back in the day this couldn't be done与PhantomJS。

我的问题是点击按钮会启动一系列AJAX请求,最终发送这个巨大的POST表单,服务器最终会回复“Content-Disposition:attachment”。

最后,我发现这种方法对我有用,即使它是网络效率低的:

[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"

下载工作完美无缺,即使我可以看到文件被请求(和发送)两次

request.abort()

(接下来,我可能会修改脚本以尝试从resource.requested侦听器内部调用setattr,设置信号量并再次调用下载程序 - 我将无法获取附件文件名,但对我来说很重要。)