Mat*_*ert 19 javascript google-chrome puppeteer
使用Puppeteer,我想在Chrome中加载一个网址并捕获以下信息:
set-cookie)捕获完整的响应体是导致我的问题的原因.
我试过的事情:
response.buffer- 如果在任何时候有重定向,这不起作用,因为缓冲区在导航上被擦除getResponseBodyForInterception- 这意味着我无法再访问encodedLength,在某些情况下我也遇到了获取正确请求和响应头的问题理想情况下,解决方案应该只有较小的性能影响,并且与正常加载页面没有任何功能差异.我也想避免分叉Chrome.
Tho*_*orf 19
这可以单独使用 puppeteer 来完成。您描述的问题response.buffer是在导航上被清除,可以通过一个接一个地处理每个请求来规避。
下面的代码page.setRequestInterception用于拦截所有请求。如果当前有正在处理/正在等待的请求,则将新请求放入队列中。然后,response.buffer()可以在没有其他请求可能异步擦除缓冲区的问题的情况下使用,因为没有并行请求。一旦处理了当前处理的请求/响应,就会处理下一个请求。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
const results = []; // collects all results
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();
const responseHeaders = response.headers();
let responseBody;
if (request.redirectChain().length === 0) {
// body can only be access for non-redirect responses
responseBody = await response.buffer();
}
const information = {
url: request.url(),
requestHeaders: request.headers(),
requestPostData: request.postData(),
responseHeaders: responseHeaders,
responseSize: responseHeaders['content-length'],
responseBody,
};
results.push(information);
nextRequest(); // continue with next request
});
page.on('requestfailed', (request) => {
// handle failed request
nextRequest();
});
await page.goto('...', { waitUntil: 'networkidle0' });
console.log(results);
await browser.close();
})();
Run Code Online (Sandbox Code Playgroud)
Gra*_*ler 11
您可以page.setRequestInterception()为每个请求启用请求拦截,然后在内部page.on('request'),您可以使用该request-promise-native模块充当中间人来收集响应数据,然后request.continue()在Puppeteer中继续请求.
这是一个完整的工作示例:
'use strict';
const puppeteer = require('puppeteer');
const request_client = require('request-promise-native');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const result = [];
await page.setRequestInterception(true);
page.on('request', request => {
request_client({
uri: request.url(),
resolveWithFullResponse: true,
}).then(response => {
const request_url = request.url();
const request_headers = request.headers();
const request_post_data = request.postData();
const response_headers = response.headers;
const response_size = response_headers['content-length'];
const response_body = response.body;
result.push({
request_url,
request_headers,
request_post_data,
response_headers,
response_size,
response_body,
});
console.log(result);
request.continue();
}).catch(error => {
console.error(error);
request.abort();
});
});
await page.goto('https://example.com/', {
waitUntil: 'networkidle0',
});
await browser.close();
})();
Run Code Online (Sandbox Code Playgroud)
我建议您搜索一个允许将请求日志与实际内容一起写入的快速代理服务器。
目标设置是让代理服务器只写一个日志文件,然后分析日志,搜索你需要的信息。
不要在代理工作时拦截请求(这会导致速度变慢)
您可能遇到的性能问题(使用代理作为记录器设置)主要与 TLS 支持有关,请注意在代理设置中允许快速 TLS 握手、HTTP2 协议
例如Squid 基准测试表明它能够处理数百个 RPS,这对于测试来说应该足够了
| 归档时间: |
|
| 查看次数: |
5626 次 |
| 最近记录: |