ho a che fare con un sito scritto con una sorta di quadro ASP.Net, che invia una notevole quantità di dati POST ad ogni richiesta (circa 100 Kb di dati, di cui circa 95 non sembrano mai cambiare tra le richieste - apparentemente legate allo stato della vista).
Tuttavia, nessun metodo che ho trovato ha funzionato per me. Ho esaminato intercepting XHR, ho persino trovato someone who is tackling the very same framework (almeno a giudicare dai selettori) ma con un caso più semplice, ispirato proprio da questa domanda. Ho scoperto che back in the day this couldn't be done con PhantomJS.
Il mio problema è che un clic su un pulsante avvia una catena di richieste AJAX che culmina con l'invio di questo enorme modulo POST, al quale infine il server risponde con una "Content-Disposition: attachment".
Alla fine, ho trovato questo approccio che funziona per me, anche se si tratta di rete-inefficiente:
...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);
Il download funziona perfettamente, anche se mi rendo conto che il file viene richiesto (e inviato due volte.
[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"
(Avanti, io probabilmente modificare lo script per provare invocare request.abort()
dall'interno della resource.requested
ascoltatore, impostare un semaforo e richiamare nuovamente il downloader - non sarò in grado di ottenere il nome del file allegato, ma che conta poco per me).
grazie, finalmente sono riuscito a ottenere il download CSV per la mia banca per lavorare con il tuo approccio – vinzenzweber
Questo ha funzionato per me ma nella mia istanza cliccando sul link non ho inviato il modulo perché è stato gestito da javascript. Ho dovuto chiamare $ ("# theForm"). Sumit() per far sì che il modulo fosse effettivamente inviato. –