En utilisant Puppeteer, je voudrais charger une URL dans Chrome et capturer les informations suivantes:
set-cookie
)La capture du corps de réponse complet est ce qui cause les problèmes pour moi.
Ce que j'ai essayé:
response.buffer
- cela ne fonctionne pas s'il y a des redirections à tout moment, car les tampons sont effacés lors de la navigationgetResponseBodyForInterception
- cela signifie que je peux ne plus accéder à encodedLength , et j'ai également eu des problèmes pour obtenir les en-têtes de demande et de réponse corrects dans certains casIdéalement, la solution ne devrait avoir qu'un impact mineur sur les performances et ne présenter aucune différence fonctionnelle par rapport au chargement normal d'une page. Je voudrais également éviter de bifurquer Chrome.
Vous pouvez activer une interception de demande avec page.setRequestInterception()
pour chaque demande, puis, à l'intérieur page.on('request')
, vous pouvez utiliser le - request-promise-native
module pour agir en tant qu'intermédiaire pour recueillir les données de réponse avant de poursuivre la demande avec request.continue()
dans Puppeteer.
Voici un exemple de travail complet:
'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();
})();
Je vous suggère de rechercher un serveur proxy rapide qui permet d'écrire les journaux des demandes avec le contenu réel.
La configuration cible consiste à permettre au serveur proxy d'écrire simplement un fichier journal, puis d'analyser le journal, en recherchant les informations dont vous avez besoin.
Ne pas intercepter les demandes pendant que le proxy fonctionne (cela entraînera un ralentissement)
Les problèmes de performances (avec proxy comme configuration de l'enregistreur) que vous pouvez rencontrer sont principalement liés au support TLS, veuillez faire attention à permettre une prise de contact TLS rapide, protocole HTTP2 dans la configuration du proxy
Par exemple. Squid benchmarks montre qu'il est capable de traiter des centaines de RPS, ce qui devrait être suffisant pour les tests
Je suggérerais d'utiliser un outil à savoir ' fiddler '. Il capturera toutes les informations que vous avez mentionnées lorsque vous chargez une URL URL.
Cela peut être fait avec un marionnettiste seul. Le problème que vous décrivez que le response.buffer
Est effacé lors de la navigation, peut être contourné en traitant chaque demande l'une après l'autre.
Le code ci-dessous utilise page.setRequestInterception
pour intercepter toutes les demandes. S'il y a actuellement une demande en cours de traitement/en attente, de nouvelles demandes sont placées dans une file d'attente. Ensuite, response.buffer()
peut être utilisé sans le problème que d'autres requêtes peuvent effacer le tampon de manière asynchrone car il n'y a pas de requêtes parallèles. Dès que la demande/réponse actuellement traitée est traitée, la prochaine demande sera traitée.
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();
})();
allez à Chrome appuyez sur F12, puis allez dans l'onglet "réseau", vous pouvez y voir toutes les requêtes http que le site envoie, vous pourrez voir les détails que vous avez mentionnés.