下载PhantomJs中POST请求响应中作为附件的文件
我想下载一个CSV文件,它是通过POST请求点击按钮生成的。我在casperJs和phantomJS论坛上尽了最大努力,结果空手而归。在像firefox这样的普通浏览器中,post请求后会出现一个浏览器下载对话框窗口。如何在PhantomJS中处理此情况下载PhantomJs中POST请求响应中作为附件的文件,phantomjs,casperjs,Phantomjs,Casperjs,我想下载一个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
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
您可以收听
page.resource.received
事件和下载()
接收文件时:
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');
}
});
我已经找到了一种使用casperjs实现这一点的方法(如果您使用XMLHttpRequest实现下载功能,那么它应该可以单独使用phantomjs,但我没有尝试) 我将留给您一个工作示例,它尝试从下载mos最新PDF。单击下载链接时,会触发一些javascript代码,生成一些隐藏的输入字段,然后发布这些字段 我们要做的是替换表单的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();
@julianjm aproach几乎就是解决方案,但就我而言,我没有正确的表单名称来替换表单提交 因此,我使用phantomjs beta找到了另一个解决方案: phantomjs 2.0有一个beta版,其中包含一个解决此问题的事件处理程序 它仍然是测试版,因此没有调试。 因此,我在发布版本上开发了点击和页面处理,然后更改了幻影版本以使下载工作正常
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();
下载:
下载exe,将phantom.exe的发布版本重命名为phantom.bkp.exe
并将此2.0版本插入该位置。
然后,在casperjs中,您需要在casperjs/bin/bootstrap.js的beging中添加一些行
* 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);
(函数(版本){
//所需版本检查
/*如果(version.major!==1){
返回uu die('CasperJS需要phantomjsv1.x');
}if(version.minor<8){
return uu die('CasperJS至少需要phantomjsv1.8或更高版本');
}
if(version.minor==8&&version.patch<1){
return uu die('CasperJS至少需要phantomjsv1.8.1或更高版本');
} */
})(幻影版);
记住,这是一个调整强>
所以,如果您想运行phantom release version或slimerjs,引导程序上的这行代码将导致问题
所以在发布版本上开发,然后调整到该版本以便能够下载。
如果您需要调试,您必须删除bootstrap.js的行我必须处理一个使用某种ASP.Net框架编写的站点,它在每次请求时发送大量POST数据(大约100KB的数据,其中大约95 Kb的数据在请求之间似乎从未更改-显然与视口状态相关)
* 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;
然而,我找不到适合我的方法。我已经研究过了,我甚至发现(至少从选择器判断),但有一个更简单的案例,受这个问题的启发。我是用幻影发现的
我的问题是,点击一个按钮就会启动一系列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);
下载工作完美无瑕,即使我可以看到文件被请求(和发送)两次
(下一步,我可能会修改脚本,尝试从
资源中调用请求.abort()
。请求的侦听器,设置信号量并再次调用下载程序-我将无法获取附件文件名,但这对我来说无关紧要).也不确定这应该如何工作,除非未提及的步骤0是编译phantom的开发分支,而不是当前的分支?不,应该使用默认的稳定phantomjs,因为download()
方法是在casper端实现的(它在幕后使用XHR)。似乎应该将resource.stage===“end”
添加到if
中(&&)以进行正确操作。是否需要等待此函数大约4秒?这仅适用于通过HTTP GET方法发送的请求。如果点击是使用POST触发的-如OP的问题中所述-您需要这样做。下载(resource.url,'ExportData.csv',“POST”)。但是这还不够,因为您需要将POST数据作为第四个参数发送到下载(…)谢谢,我最终设法获得CSV下载,以便我的银行使用您的方法。这对我来说很有效,但在我的例子中,单击链接没有提交表单,因为它是由javascript处理的。我不得不调用$(“#theForm”).sumit()使表单实际提交。
[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"