javascript - Puppeteer - „Solicitarea cadrului principal prea devreme!”
Am creat o funcție folosind Puppeteer care verifică dacă utilizatorul este autentificat. Practic, la început verifică dacă browserul și pagina sunt deschise și apoi caută un selector și, în funcție de faptul dacă elementul a fost găsit, returnează true/false.
export async function checkIfUserIsLoggedIn() {
const logger = getLogger('checkIfUserIsLoggedIn()');
try {
if (!page || !browser) {
logger.info('page or browser is not open');
return false;
}
logger.info('page or browser is open');
await delay(randomWaitTimeSeconds1_2());
// await page.waitForSelector(selector);
const btn = await page.$(selector);
logger.info(`user is logged in - ${!!btn ? 'YES' : 'NO'}`);
return !!btn;
} catch (e) {
logError('checkIfUserIsLoggedIn()', e);
}
}Uneori apare eroarea „Error: Requesting main frame too early!” când încerc să selectez elementul necesar sau când aștept selectorul (linia de deasupra, cea comentată). Mesajul complet de eroare:
[2023-10-02T01:58:06.825] [ERROR] checkIfUserIsLoggedIn() - Error: Requesting main frame too early!
at assert (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\util\assert.js:28:15)
at FrameManager.mainFrame (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\cdp\FrameManager.js:219:32)
at CdpPage.mainFrame (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\cdp\Page.js:407:35)
at CdpPage.$ (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\api\Page.js:324:31)
at checkIfUserIsLoggedIn (file:///C:/Users/simon/Desktop/tb-project-pup/main/checkIfUserIsLoggedIn.js:19:38)Pagina în care se întâmplă acest lucru are un fel de cronometru. Și când cronometrul ajunge la 00, pagina se reîncarcă automat („?reload=auto”), ceea ce cred că cauzează eroarea. Dar acest lucru se întâmplă foarte rar.
Încerc să înțeleg de ce această eroare determină Puppeteer să se închidă și să închidă browserul? În alte funcții uneori primesc eroarea TimeoutError: Waiting for selector .el failed: Waiting failed: 30000ms exceeded, sau altă eroare ProtocolError: Protocol error (DOM.describeNode): Cannot find context with specified id, dar în acele scenarii eroarea nu închide browserul, însă aceasta îl închide.
Poate cineva mă poate ajuta să înțeleg de ce se închide Puppeteer? Și, de asemenea, să mă ajute să găsesc o soluție corectă pentru asta?
Cred că poate înainte de const btn=await page.$ (selector); aș putea adăuga ceva de genul await page.waitForNavigation({ waitUntil: 'domcontentloaded', });, dar acea navigare nu se întâmplă foarte des, poate dura până la mai mult de 2 minute pentru ca pagina să se reîncarce. De asemenea, mă gândeam că poate aș putea introduce un alt bloc try catch pentru a rula din nou această funcție dacă apare o eroare, de exemplu: (dar dacă fac asta, mai am nevoie de blocul meu original try/catch?)
const anchorElement = await page.$(selector).catch(async () => {
retryCount++;
if (retryCount < 3) {
await checkIfUserIsLoggedIn();
// OR await page.$(selector)
}
});Răspuns #1
Acest lucru ar putea fi util, tocmai m-am întâlnit și eu cu asta în cod asincron.
S-ar putea să ai o condiție de cursă în ceea ce privește momentul în care închizi browserul, așa că verifică asta și asigură-te că codul tău asincron rulează înainte ca instanța browserului să fie închisă.
Răspunsul #2
Folosesc Puppeteer de patru ani, în același proiect. Această problemă apare aleatoriu, mai mult sau mai puțin după această versiune a noului mod headless https://developer.chrome.com/articles/new-headless/. În general, am obținut de mai multe ori problema „Requesting main frame too early!” imediat după acea versiune de Puppeteer. Am încercat să deschid un raport de bug, dar nu am nici o idee cum să reproduc problema, pentru că este aleatorie.
Pot obține această eroare în diferite metode
- pagina.mergiLa
- pagina.așteaptăSelector
punctul din codul sursă care ridică acea excepție este acesta.
