【问题标题】:timeout error with navigation and waitForSelector() in puppeteer irrespective of timeout valuepuppeteer 中的导航和 waitForSelector() 出现超时错误,与超时值无关
【发布时间】:2020-10-19 00:18:54
【问题描述】:

我希望我的程序这样做:

  1. 打开网页
  2. 点击按钮进入新页面
  3. 对新页面进行截图。

第 1 步和第 2 步工作正常,但在第 3 步时遇到超时错误。根据对 StackOverflow 上类似问题的回答,我使用了具有更大超时跨度(最长 2 分钟)的 waitForNavigation(),但我是仍然得到同样的错误。使用 waitForSelector() 而不是 waitForNavigation() 也会给出同样的错误。如果我同时删除两者,puppeteer 会在步骤 1 中截取网页的屏幕截图。我还尝试在 waitUntil 中使用不同的选项,例如“domcontentloaded”、“loaded”、“networkidle0”和“newtorkidle2”,但没有任何效果。 这是我在 puppeteer 中的第一个程序,我已经被这个问题困扰了很长时间。

这是我的代码:

 await page.waitForSelector('#featured > c-wiz > div.OXo54d > div > div > div > span > span > span.veMtCf');
         
 // await navigation;
 await page.screenshot({path: 'learnmore.png'});
 console.log('GOT THIS FAR:)');
 //await page.close();
 await browser.close();
 return 0;

这是完整的程序:

const puppeteer = require('puppeteer');
(async () => {
    try{
        const browser = await puppeteer.launch({headless: false});
        const page = await browser.newPage();
       // const navigationPromise = page.waitForNavigation({waitUntil: "load"});

        //google.com
        await page.goto('https://google.com');
        await page.type('input.gLFyf.gsfi',"hotels in london");
        await page.keyboard.press('Enter');
        //search results
       // await navigationPromise;
        await page.waitForSelector('#rso > div:nth-child(2) > div > div > div > g-more-link > a > div');
        await page.click('#rso > div:nth-child(2) > div > div > div > g-more-link > a > div'); 
        //list of hotels
       // await navigationPromise;
        await page.waitForSelector('#yDmH0d > c-wiz.zQTmif.SSPGKf > div > div.lteUWc > div > c-wiz > div > div.gpcwnc > div.cGQUT > main > div > div.Hkwcrd.Sy8xcb.XBQ4u > c-wiz > div.J6e2Vc > div > div > span > span');
        await page.click("#yDmH0d > c-wiz.zQTmif.SSPGKf > div > div.lteUWc > div > c-wiz > div > div.gpcwnc > div.cGQUT > main > div > div.Hkwcrd.Sy8xcb.XBQ4u > c-wiz > div.l5cSPd > c-wiz:nth-child(3) > div > div > div > div.kCsInf.ZJqrAd.qiy8jf.G9g6o > div > div.TPQEac.qg10C.RCpQOe > a > button > span");
        //"learn more"
       // await navigationPromise;   
       
        //This is where timeout error occurs:
        await page.waitForSelector('#featured > c-wiz > div.OXo54d > div > div > div > span > span > span.veMtCf');             
       // await navigation;
        await page.screenshot({path: 'learnmore.png'});
        console.log('GOT THIS FAR:)');

        //await page.close();
        await browser.close();
        return 0;
    }
    catch(err){
       console.error(err);
    }
})()
.then(resolvedValue => {
    console.log(resolvedValue);
})
.catch(rejectedValue => {
    console.log(rejectedValue);
})

【问题讨论】:

    标签: node.js timeout puppeteer


    【解决方案1】:

    您的超时发生是因为您正在等待的选择器在页面上不存在。 (如果您打开脚本卡住的浏览器控制台并启动$(selector),它将返回null

    Google 使用动态 class 和 id 值,正是为了防止(或使其更难)通过脚本检索数据,每次访问页面时选择器都会有不同的值。

    如果你真的需要抓取它的内容,你可以使用XPath selectors,与动态更改选择器名称相比,它不那么脆弱:

    例如:

    await page.waitForXpath('//h3[contains(text(), "The Best Hotels in London")]')
    
    const link = await page.$x('//h3[contains(text(), "The Best Hotels in London")]')
    await link[0].click()
    

    文档参考:

    【讨论】:

    • 感谢您的回复,但我仍然无法访问新页面上的内容。具体来说,这就是我想要做的:打开谷歌>>搜索“伦敦酒店”>>点击“查看3810家酒店”>>点击“了解更多”以获得第一家酒店>>点击“价格”>>在“价格”页面上抓取内容。我目前正在尝试单击“价格”,但我无法使用 $x()。你有什么建议吗?
    • 点击不成功时收到的错误信息是什么?
    • 我收到超时错误消息:TimeoutError: waiting for XPath "//*[@id="prices"]/span" failed: timeout 30000ms exceeded
    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2023-02-07
    • 2019-02-09
    • 1970-01-01
    • 2021-07-24
    • 2022-12-29
    • 2019-09-29
    • 1970-01-01
    相关资源
    最近更新 更多