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

  1. stránka.prejsťNa
  2. page.waitForSelector

Bod zdrojového kódu, ktorý vyvoláva túto výnimku, je tento.