Проблема в том, что буфер очищается, как только происходит какой-либо запрос навигации. Это может быть перенаправление или перезагрузка страницы в вашем случае.
Чтобы решить эту проблему, вам нужно убедиться, что страница не выполняет никаких запросов навигации, если вы не закончили загрузку своего ресурса. Для этого мы можем использовать page.setRequestInterception
.
Существует простое решение, которое может помочь вам начать, но не всегда может работать, и более сложное решение этой проблемы.
Простое решение
Это решение отменяет любые запросы навигации после первоначального запроса. Это означает, что любая перезагрузка или навигация на странице не будут работать. Поэтому буферы ресурсов не очищаются.
const browser = await puppeteer.launch();
const [page] = await browser.pages();
let initialRequest = true;
await page.setRequestInterception(true);
page.on('request', request => {
// cancel any navigation requests after the initial page.goto
if (request.isNavigationRequest() && !initialRequest) {
return request.abort();
}
initialRequest = false;
request.continue();
});
page.on('response', async (response) => {
if (response.url() === 'RESOURCE YOU WANT TO DOWNLOAD') {
const buffer = await response.buffer();
// handle buffer
}
});
await page.goto('...');
Расширенное решение
Следующий код будет обрабатывать каждый запрос один за другим. Если вы загружаете буфер, он будет ждать загрузки буфера, прежде чем обрабатывать следующий запрос.
const browser = await puppeteer.launch();
const [page] = await browser.pages();
let paused = false;
let pausedRequests = [];
const nextRequest = () => { // continue the next request or "unpause"
if (pausedRequests.length === 0) {
paused = false;
} else {
// continue first request in "queue"
(pausedRequests.shift())(); // calls the request.continue function
}
};
await page.setRequestInterception(true);
page.on('request', request => {
if (paused) {
pausedRequests.push(() => request.continue());
} else {
paused = true; // pause, as we are processing a request now
request.continue();
}
});
page.on('requestfinished', async (request) => {
const response = await request.response();
if (response.url() === 'RESOURCE YOU WANT TO DOWNLOAD') {
const buffer = await response.buffer();
// handle buffer
}
nextRequest(); // continue with next request
});
page.on('requestfailed', nextRequest);
await page.goto('...');