我使用 Puppeteer 创建了一个函数来检查用户是否已登录。基本上,它首先检查浏览器、页面是否打开,然后查找选择器,并根据是否找到项目返回 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);
}
}
有时会出现错误“错误:请求主机太早!”当我尝试选择所需元素或等待选择器(上面一行,注释行)时会发生这种情况。 完整错误消息:
[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)
发生这种情况的页面有某种计时器。当计时器转到 00 时,页面会自动重新加载(“?reload = auto”),我认为这会导致错误。但这种情况很少发生。
我试图理解为什么这个错误会导致 Puppeteer 关闭并关闭浏览器?在其他函数中,我有时会收到错误
TimeoutError: Waiting for selector
.el failed: Waiting failed: 30000ms exceeded
,或另一个错误 ProtocolError: Protocol error (DOM.describeNode): Cannot find context with specified id
,但在这些情况下,错误不会关闭浏览器,但这个会关闭。
也许有人可以帮助我理解为什么 puppeteer 被关闭?还帮我找到正确的解决方案吗?
我想也许在
const btn = await page.$(selector);
之前我可以添加类似的内容
await page.waitForNavigation({ waitUntil: 'domcontentloaded', });
但导航并不经常发生,页面重新加载可能需要 2 分钟以上的时间。
另外我在想也许我可以引入另一个 try catch 块来在发生错误时重新运行此函数,例如:
(但是如果我这样做,我还需要原来的 try/catch 块吗?)
const anchorElement = await page.$(selector).catch(async () => {
retryCount++;
if (retryCount < 3) {
await checkIfUserIsLoggedIn();
// OR await page.$(selector)
}
});
page.$不会等待,你想要page.waitForSelector:
let loggedIn = await page.waitForSelector('[href*=logout]', { timeout: 10000 }).catch(e => {})