【问题标题】:Why cant Puppeteer find this link element on page?为什么 Puppeteer 在页面上找不到这个链接元素?
【发布时间】:2020-09-14 20:42:29
【问题描述】:

^^更新^^
愿意花钱请人帮我解决这个问题,codeMentor.io 上发布的问题:https://www.codementor.io/u/dashboard/my-requests/9j42b83f0p

我一直在寻找点击元素:

<a id="isc_LinkItem_1$20j" href="javascript:void" target="javascript" tabindex="2"
onclick="if(window.isc_LinkItem_1) return isc_LinkItem_1.$30i(event);"
$9a="$9d">Reporting</a>

在:https://stackblitz.com/edit/js-nzhhbk (我没有包含实际页面,因为它在用户名和密码后面)

看起来很简单
-------------------------------------------------- --------------------

解决方案1:

page.click('[id=isc_LinkItem_1$20j]') //not a valid selector


解决方案2:

const linkHandlers = await frame.$x("//a[contains(text(), 'Reporting')]");

if (linkHandlers.length > 0) {
    await linkHandlers[0].click();
} else {
    throw new Error('Link not found');
} //link not found

----------------------------------- ------------------------------------

我已经查看了选择和单击它的所有方式,它说它不在文档中,即使它显然是(通过检查 chrome 开发工具中的 html 并调用:page.evaluate(() =&gt; document.body.innerHTML) 来验证)

**试图查看它是否在 iframe 中
**试图通过 id 选择
**尝试按内部文本选择
**试图在浏览器中控制台记录正文(控制台日志记录无法在检查元素上验证)//nothing happens
**尝试使用以下方法创建带有正文的警报​​:
_evaluate(() =&gt; alert(document)) // nothing happens
**尝试创建警报以测试是否可以通过以下方式注入 javascript:
_evaluate(() =&gt; alert('works')) // nothing happens
**也试过这个:How to select elements within an iframe element in Puppeteer// doesn't work

这是我目前构建的代码

const page = await browser.newPage();

const login1url =
    'https://np3.nextiva.com/NextOSPortal/ncp/landing/landing-platform';
await page.goto(login1url);
await page.waitFor(1000);
await page.type('[name=loginUserName', 'itsaSecretLol');
await page.type('[name=loginPassword]', 'nopeHaha');
await page.click('[type=submit]');
await page.waitForNavigation();
const login3url = 'https://np3.nextiva.com/NextOSPortal/ncp/admin/dashboard';
await page.goto(login3url);
await page.click('[id=hdr_users]');
await page.goto('https://np3.nextiva.com/NextOSPortal/ncp/user/manageUsers');
await page.goto('https://np3.nextiva.com/NextOSPortal/ncp/user/garrettmrg');
await page.waitFor(2000);
await page.click('[id=loginAsUser]');
await page.waitFor(2000);
await page.click('[id=react-select-5--value');
await page.waitFor(1000);
await page.click('[id=react-select-5--option-0]');
await page.waitFor(20000);
const elementHandle = await page.$('iframe[id=callcenter]');
const frame = await elementHandle.contentFrame();
const linkHandlers = await frame.$x("//a[contains(text(), 'Reporting')]");

if (linkHandlers.length > 0) {
    await linkHandlers[0].click();
} else {
    throw new Error('Link not found');
}

【问题讨论】:

  • 有效的是'[id="isc_LinkItem_1$20j"]'
  • 你确定await page.waitFor(time) 就够了吗?你试过page.waitForSelector()吗?
  • 我没想到,我会试着坚持下去。
  • 抱歉,如果它在 iframe 中,则应该是 frame.waitForSelector()。但是没有实时页面真的很难说这个问题(
  • 您在代码中的方式似乎正式有效,但没有实时页面,很难理解发生了什么。

标签: node.js google-cloud-functions puppeteer


【解决方案1】:

由于 isc_LinkItem_1$20j 不是一个有效的选择器,也许你可以尝试查找元素 STARTING WITHisc_LinkItem_1 ,像这样

await page.waitForSelector("[id^=isc_LinkItem_1]", {visible: true, timeout: 30000});
await page.click("[id?=isc_LinkItem_1]);

?

【讨论】:

    【解决方案2】:

    关于你的解决方案1:

    await page.click('a[id=isc_LinkItem_1\\$20j]');
    

    或者尝试:

    await page.click('#isc_LinkItem_1\\$20j]');
    

    我有一个小印象,您必须在括号前提供您尝试选择的元素类型,在本例中为 元素。

    在第二种解决方案中,# 字符表示我们正在通过它的 id 选择一个元素

    【讨论】:

    • 我认为无论出于何种原因它不在页面上而是在其他地方,这怎么可能?
    • 我已经编辑了我的答案,在选择器中的 $ 之前提供了两个反斜杠,尝试一下。另外,正如我所见,您传递的链接上的 iframe 在打开后立即关闭,这意味着它们是空的
    • 不工作,如果它更容易我们可以进行屏幕共享,我可以向您展示实时元素树,NDA 不允许我共享凭据
    • 页面加载完毕后,如果尝试通过浏览器控制台选择元素会发生什么?
    • 如果您在访问页面后立即尝试单击该元素,则可能尚未加载 DOM 内容,这可能是您找不到该元素的原因。在执行点击之前尝试设置await page.waifFor(5000)
    【解决方案3】:

    原来上一次点击触发了一个新标签。 Puppeteer 没有移动到新选项卡,所有以前的代码都在旧选项卡上执行。要修复我们所要做的就是找到新选项卡,选择它并执行代码,这是我们为选项卡选择的函数:

    async function getTab(regex, browser, targets) {
    let pages = await browser.pages();
    if (targets) pages = await browser.targets();
    let newPage;
    for (let i = 0; i < pages.length; i++) {
        const url = await pages[i].url();
        console.log(url);
        if (url.search(regex) !== -1) {
            newPage = pages[i];
            console.log('***');
            console.log(url);
            console.log('***');
            break;
        }
    }
    console.log('finished');
    return newPage;
    }
    

    【讨论】:

    • 顺便说一句,对于页面或目标 .url(),您不需要 await
    • 另外,你可以试试const newPage = pages.find(page =&gt; regex.test(page.url()));,而不是循环,
    • 伟大的输入这两个东西使代码更简洁!
    猜你喜欢
    • 2021-05-31
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多