Lorsque je navigue sur un site Web A en utilisant un navigateur normal (Chrome) et lorsque je clique sur un lien du site Web A, Chrome télécharge immédiatement le rapport sous forme de fichier CSV.
Lorsque j'ai vérifié les en-têtes de réponse d'un serveur, j'obtiens les résultats suivants:
Cache-Control:private,max-age=31536000
Connection:Keep-Alive
Content-Disposition:attachment; filename="report.csv"
Content-Encoding:gzip
Content-Language:de-DE
Content-Type:text/csv; charset=UTF-8
Date:Wed, 22 Jul 2015 12:44:30 GMT
Expires:Thu, 21 Jul 2016 12:44:30 GMT
Keep-Alive:timeout=15, max=75
Pragma:cache
Server:Apache
Transfer-Encoding:chunked
Vary:Accept-Encoding
Maintenant, je veux télécharger et analyser ce fichier à l'aide de PhantomJS. J'ai défini l'écouteur page
onResourceReceived
pour voir si Phantom recevra/téléchargera le fichier.
clientRequests.phantomPage.onResourceReceived = function(response) {
console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response));
};
Lorsque je fais une demande Phantom pour télécharger un fichier (c'est page.open ('URL DU FICHIER')), je peux voir dans le journal Phantom que le fichier est téléchargé. Voici les journaux:
"contentType": "text/csv; charset=UTF-8",
"headers": {
"name": "Date",
"value": "Wed, 22 Jul 2015 12:57:41 GMT"
},
"name": "Content-Disposition",
"value": "attachment; filename=\"report.csv\"",
"status":200,"statusText":"OK"
J'ai reçu le fichier et son contenu, mais comment accéder aux données du fichier? Lorsque j'imprime l'objet PhantomJS page
actuel, j'obtiens le code HTML de la page A et je ne le veux pas, je veux un fichier CSV, que j'ai besoin d'analyser en utilisant JavaScript.
Après des jours et des jours d'enquête, je dois dire qu'il existe des solutions:
Si vous devez télécharger un fichier à l'aide de PhanotmJS, , fuyez PhantomJS et utilisez CasperJS . CasperJS est basé sur PhantomJS, mais il a une syntaxe et un flux de programme bien meilleurs et intuitifs.
Voici un bon article expliquant " Pourquoi CasperJS est meilleur que PhantomJS ". Dans cet article, vous trouverez une section sur le téléchargement de fichiers.
Comment télécharger un fichier CSV à l'aide de CasperJS (cela fonctionne même lorsque le serveur envoie un en-tête Content-Disposition:attachment; filename='file.csv
)
Ici vous pouvez trouver des fichiers csv personnalisés disponibles en téléchargement: http://captaincoffee.com.au/dump/items.csv
Pour télécharger ce fichier à l'aide de CasperJS, exécutez le code suivant:
var casper = require('casper').create();
casper.start("http://captaincoffee.com.au/dump/", function() {
this.echo(this.getTitle())
});
casper.then(function(){
var url = 'http://captaincoffee.com.au/dump/csv.csv';
require('utils').dump(this.base64encode(url, 'get'));
});
casper.run();
Le code ci-dessus téléchargera http://captaincoffee.com.au/dump/csv.csv
Fichier CSV et imprimera les résultats sous forme de chaîne base64. Donc, de cette façon, vous n'avez même pas à télécharger de données dans un fichier, vous avez vos données sous forme de chaîne base64.
Si vous souhaitez explicitement télécharger un fichier dans un système de fichiers, vous pouvez utiliser la fonction download
qui est disponible dans CasperJS.
J'ai trouvé une solution pour PhantomJS. En lisant cette discussion j'ai trouvé un jsfiddle qui télécharge une URL via la méthode ajax de jQuery et code le fichier en base64.
Le fichier que je voulais télécharger était en texte brut (CSV), j'ai donc supprimé les fonctions d'encodage. Ma page cible avait également déjà inclus jQuery, donc je n'avais pas besoin de injecter jQuery dans la page cible .
Mon code suppose que vous avez déjà ouvert la page sur laquelle vous souhaitez télécharger le fichier à l'aide de PhantomJS, et que cette page contient jQuery. Dans mon cas, je devais d'abord me connecter au site afin d'obtenir le lien de téléchargement.
var fs = require('fs');
var page=this;
var result = page.evaluate(function() {
var out;
$.ajax({
'async' : false,
'url' : 'fullurltodownload.csv',
'success' : function(data, status, xhr) {
out = data;
}
});
return out;
});
fs.write('mydownloadedfile.csv', result);
Les 2 réponses précédentes supposent que vous pouvez connaître à l'avance l'URL du fichier CSV final. Ce ne sera pas le cas si le lien va vers une page HTML qui fait une redirection Javascript vers le fichier et que vous ne voulez pas évaluer ce Javascript en dehors de PhantomJS. Vos options sont alors:
text/plain
et supprime les en-têtes Content-Disposition
, afin que vous puissiez lire le fichier de PhantomJS de la manière normale - cela devrait fonctionner pour un fichier CSV mais ne fonctionnera pas pour les binaires contenant 0 octet.La première de ces options (PhantomJS + proxy amont) est facilitée si le proxy amont peut surveiller l'en-tête Accept
que PhantomJS envoie au site distant. Au moins dans PhantomJS version 2.1.1, les requêtes principales ont Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
, Les requêtes de feuille de style ont Accept: text/css,*/*;q=0.1
Et toutes les autres requêtes (images, scripts, XMLHttpRequest) par défaut à Accept: */*
Bien que cela peut être remplacé par les sites qui utilisent XMLHttpRequest.setRequestHeader()
. Par conséquent, si le proxy en amont voit une demande avec un en-tête Accept
contenant text/html
Et transmet cette demande à la les résultats du serveur dans un fichier CSV ou un autre document non HTML, il y a de fortes chances que ce soit celui à enregistrer.