gpt4 book ai didi

node.js - 如何使用puppeteer获取下载流(缓冲区)?

转载 作者:行者123 更新时间:2023-12-03 12:11:07 26 4
gpt4 key购买 nike

我想获取下载内容(缓冲区),不久后,将数据存储在我的S3帐户中。到目前为止,我还无法找到解决方案……在网络上寻找一些示例时,我注意到很多人都遇到了这个问题。我尝试(未成功)使用page.on(“response”)事件来检索原始响应内容,并遵循以下代码片段:

const bucket = [];
await page.on("response", async response => {
const url = response.url();
if (
url ===
"https://the.earth.li/~sgtatham/putty/0.71/w32/putty-0.71-installer.msi"
) {
try {
if (response.status() === 200) {
bucket.push(await response.buffer());
console.log(bucket);
// I got the following: 'Protocol error (Network.getResponseBody): No resource with given identifier found' }
}
} catch (err) {
console.error(err, "ERROR");
}
}
});

通过上面的此类代码,我打算检测下载对话框的事件,然后以某种方式能够接收二进制内容。

我不确定这是否是正确的方法。我注意到有些人使用基于读取文件的解决方案,换句话说,下载完成后,他们会从磁盘读取存储的文件。在 https://github.com/GoogleChrome/puppeteer/issues/299上也有类似的讨论。

我的问题是:是否有某种方法(使用操纵符)来拦截下载流,而不必先将文件保存到磁盘上?

非常感谢你。

最佳答案

问题是,一旦发生任何类型的导航请求,便会立即清除缓冲区。在您的情况下,这可能是重定向或页面重新加载。

要解决此问题,您需要确保只要您还没有完成资源下载,该页面就不会发出任何导航请求。为此,我们可以使用 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('...');

关于node.js - 如何使用puppeteer获取下载流(缓冲区)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55408302/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com