Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

526
Views
Titiritero: se agotó el tiempo de espera de waitForResponse(), pero page.on('response') encuentra la respuesta

Estoy tratando de obtener una respuesta XHR de una página web. Encontré el

 await page.waitForResponse(url);

o

 await page.waitForResponse((res) => { if (res.url() === myUrl) return true; });

método, pero siempre se agota el tiempo de espera para la respuesta de URL que estoy tratando de obtener.

Sin embargo, si configuro

 page.on('response', (res) => { if (res.url() === myUrl) { // do what I want with the response } })

se encuentra la respuesta correcta y puedo recuperar los datos.

Después de algunas depuraciones, parece que waitForResponse() no devuelve ningún requerimiento/resolución XHR.

¿Alguna idea?

EDITAR: Ejemplo. Para este caso, se requiere usar el paquete puppeteer-extra-plugin-stealth y puppeteer-extra , de lo contrario, esta URL devolverá el código de estado '403':

 import StealthPlugin from 'puppeteer-extra-plugin-stealth'; import UserAgent from 'user-agents'; import puppeteer from 'puppeteer-extra'; import { Page } from 'puppeteer'; const wantedUrl = 'https://www.nike.com.br/DataLayer/dataLayer'; const workingFunction = async (page: Page) => { let reqCount = 0; let resCount = 0; page.on('request', req => { reqCount++; if (req.url() == wantedUrl) { console.log('The request I need: ', req.url()); console.log(reqCount); } }); page.on('response', async res => { resCount++; if (res.url() == wantedUrl) { console.log('The response I need:', await res.json()); console.log(resCount); } }); await page.goto('https://www.nike.com.br/tenis-nike-sb-dunk-low-pro-unissex-153-169-229-284741', { timeout: 0, }); }; const notWorkingFunction = async (page: Page) => { let resCount = 0; await page.goto('https://www.nike.com.br/tenis-nike-sb-dunk-low-pro-unissex-153-169-229-284741'); const res = await page.waitForResponse( res => { resCount++; console.log(res.url()); console.log(resCount); if (res.url() === wantedUrl) { return true; } return false; }, { timeout: 0 } ); return res; }; (async () => { puppeteer.use(StealthPlugin()); const browser = await puppeteer.launch({}); const page = await browser.newPage(); const userAgent = new UserAgent({ deviceCategory: 'desktop' }); await page.setUserAgent(userAgent.random().toString()); try { // workingFunction(page); const res = await notWorkingFunction(page); } catch (e) { console.log(e); } })();
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

La razón por la que funciona la versión page.on es porque establece los controladores de solicitud/respuesta antes de realizar la navegación . Por otro lado, la versión waitForResponse espera hasta que se activa el evento de "load" (punto de resolución predeterminado de page.goto() ), y solo entonces comienza a rastrear las respuestas con la llamada a page.waitForResponse . MDN dice del evento de load :

El evento de load se activa cuando se ha cargado toda la página, incluidos todos los recursos dependientes, como hojas de estilo e imágenes. Esto contrasta con DOMContentLoaded , que se activa tan pronto como se carga el DOM de la página, sin esperar a que los recursos terminen de cargarse.

En base a esto, podemos inferir que para cuando se activa el evento de load y la función waitForResponse finalmente comienza a escuchar el tráfico, ya se perdió la respuesta deseada, ¡así que espera para siempre!

La solución es crear la promesa para page.waitForResponse antes (o al mismo tiempo) de la llamada goto de modo que no se pierda tráfico cuando inicie la navegación.

También sugiero usar "domcontentloaded" en la llamada goto . "domcontentloaded" está infrautilizado en Puppeteer: no tiene sentido esperar a que lleguen todos los recursos cuando solo está buscando uno. La configuración predeterminada de "load" o "networkidleN" de uso frecuente es mejor para casos de uso como captura de pantalla de la página donde desea que todo se vea como lo vería un usuario. Para ser claros, esta no es la solución al problema, solo una optimización, y no es demasiado evidente en los documentos cuál es adecuado cuando.

Aquí hay un ejemplo mínimo (utilicé JS, no TS):

 const puppeteer = require("puppeteer-extra"); // ^3.2.3 const StealthPlugin = require("puppeteer-extra-plugin-stealth"); // ^2.9.0 const UserAgent = require("user-agents"); // ^1.0.958 puppeteer.use(StealthPlugin()); let browser; (async () => { browser = await puppeteer.launch(); const [page] = await browser.pages(); const userAgent = new UserAgent({deviceCategory: "desktop"}); await page.setUserAgent(userAgent.random().toString()); const url = "https://www.nike.com.br/tenis-nike-sb-dunk-low-pro-unissex-153-169-229-284741"; const wantedUrl = "https://www.nike.com.br/DataLayer/dataLayer"; const [res] = await Promise.all([ page.waitForResponse(res => res.url() === wantedUrl, {timeout: 90000}), page.goto(url, {waitUntil: "domcontentloaded"}), ]); console.log(await res.json()); })() .catch(err => console.error(err)) .finally(() => browser?.close()) ;
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!