Мне приходится иметь дело с сайтом, написанным с какой-то инфраструктурой ASP.Net, которая отправляет значительное количество данных POST при каждом запросе (около 100 КБ данных, из которых около 95 никогда не меняются между запросами - очевидно, связано с состоянием окна просмотра) .
Однако ни один метод, который я мог найти, не работал у меня. Я просмотрел перехватывая XHR, я даже нашел кого-то, кто работа с той же структурой (по крайней мере, судя по селекторам), но с более простым случаем, вдохновленным этим вопросом. Я обнаружил, что в прошлом это было невозможно с помощью PhantomJS.
Моя проблема в том, что щелчок по кнопке запускает цепочку запросов AJAX, кульминацией которой является отправка этой огромной формы POST, на которую, наконец, сервер отвечает «Content-Disposition: вложение».
В конце концов, я нашел этот подход, который работает для меня, даже если он неэффективен для сети:
...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);
Загрузка работает безупречно, даже если я вижу, что файл запрашивается (и отправляется) дважды.
[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
, установить семафор и снова вызвать загрузчик — я не смогу получить имя файла вложения, но это меня мало волнует).
person
LSerni
schedule
14.09.2017