javascript - Puppeteer - „Požadovanie hlavného rámca príliš skoro!“
Vytvoril som funkciu pomocou Puppeteer, ktorá kontroluje, či je používateľ prihlásený. V podstate najprv kontroluje, či sú prehliadač a stránka otvorené, a potom hľadá selektor a v závislosti od toho, či bol objekt nájdený, vracia 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);
}
}Niekedy sa vyskytne chyba „Chyba: Požiadavka na hlavný rám príliš skoro!“ keď sa snažím vybrať požadovaný prvok alebo keď čakám na selektor (riadok vyššie, ten komentovaný). Celá chybová správa:
[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)Stránka, na ktorej sa to deje, má určitý časovač. A keď časovač dosiahne 00, stránka sa automaticky obnoví ("?reload=auto"), čo si myslím, že spôsobuje chybu. Ale stáva sa to veľmi zriedka.
Snažím sa pochopiť, prečo táto chyba spôsobuje, že Puppeteer sa vypne a zavrie prehliadač? V iných funkciách sa mi niekedy objaví chyba TimeoutError: Waiting for selector .el failed: Waiting failed: 30000ms exceeded alebo iná chyba ProtocolError: Protocol error (DOM.describeNode): Cannot find context with specified id, ale v týchto scenároch chyba prehliadač nezavrie, zatiaľ čo táto áno.
Možno mi niekto môže pomôcť pochopiť, prečo sa Puppeteer zatvára? A tiež mi pomôcť nájsť správne riešenie pre toto?
Myslím, že možno pred const btn=await page.$ (selector); by som mohol pridať niečo ako await page.waitForNavigation({ waitUntil: 'domcontentloaded', });, ale táto navigácia sa nedeje veľmi často, načítanie stránky môže trvať až 2+ minúty. Tiež som rozmýšľal, že by som mohol zaviesť ďalší blok try catch, aby sa táto funkcia znovu spustila, ak nastane chyba, napr.: (ale ak to urobím, ešte stále potrebujem môj pôvodný blok try/catch?)
const anchorElement = await page.$(selector).catch(async () => {
retryCount++;
if (retryCount < 3) {
await checkIfUserIsLoggedIn();
// OR await page.$(selector)
}
});Odpoveď č. 1
Toto by mohlo byť užitočné, práve som na to tiež narazil pri asynchrónnom kóde.
Môžete mať problém so súbežným spracovaním týkajúci sa toho, kde zatvárate prehliadač, takže to tiež skontrolujte a uistite sa, že váš asynchrónny kód beží predtým, než sa inštancia prehliadača zatvorí.
Odpoveď č. 2
Používam Puppeteer už štyri roky na tom istom projekte. Tento problém sa objavuje náhodne viac-menej po vydaní nového režimu bez hlavičky https://developer.chrome.com/articles/new-headless/. Vo všeobecnosti som niekoľkokrát získal chybu „Requesting main frame too early!“ hneď po tomto vydaní Puppeteer. Skúšal som otvoriť hlásenie o chybe, ale nemám žiadnu predstavu, ako problém replikovať, pretože je to náhodné.
Môžem získať túto chybu v rôznej metóde
- stránka.prejsťNa
- page.waitForSelector
Bod zdrojového kódu, ktorý vyvoláva túto výnimku, je tento.
