为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Puppeteer 单击选择器

使用 Puppeteer 单击选择器

肥皂起泡泡 2023-02-17 10:17:11
所以我在点击耐克网站上的登录按钮时遇到了问题。我不确定为什么它一直崩溃,好吧,因为它找不到我猜的选择器,但我不确定我做错了什么。我还想说我在 puppeteer 崩溃之前遇到了某种内存泄漏,如果我不及时在控制台内取消进程,有时它甚至会使我的 macbook 完全崩溃。编辑:如果我没有足够快地取消应用程序,此代码也会在崩溃时导致内存泄漏,迫使我不得不硬重置我的 mac。节点版本:14.4.0 Puppeteer 版本:5.2.1当前代码:const puppeteer = require('puppeteer');(async () => {    const browser = await puppeteer.launch({        headless: false,        defaultViewport: null,        args: ['--start-maximized']    })    const page = await browser.newPage()    await page.goto('https://www.nike.com/')    const winner = await Promise.race([        page.waitForSelector('[data-path="join or login"]'),        page.waitForSelector('[data-path="sign in"]')    ])    await page.click(winner._remoteObject.description)})()我也试过:await page.click('button[data-var]="loginBtn"');
查看完整描述

3 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

尝试一下:

await page.click('button[data-var="loginBtn"]');


查看完整回答
反对 回复 2023-02-17
?
12345678_0001

TA贡献1802条经验 获得超5个赞

他们正在对他们的网站进行 A/B 测试,因此当您从自己的 chrome 浏览器访问该网站时,您可能会登陆一个选择器与您检索到的选择器截然不同的页面。

在这种情况下,您可以尝试使用 XPath 及其contains方法通过文本内容获取元素(不幸的是,在这种特定情况下也会更改设计) 。例如$x('//span[contains(text(), "Sign In")]')[0]

所以我建议检测两个按钮版本并获得它们最稳定的选择器,这些也可以基于数据属性:

A

$('[data-path="sign in"]')

$('[data-path="join or login"]')

然后使用 aPromise.race你可以检测到哪个按钮存在,然后从JSHandle@node这样的中提取它的选择器._remoteObject.description::

{

  type: 'object',

  subtype: 'node',

  className: 'HTMLButtonElement',

  description: 'button.nav-btn.p0-sm.body-3.u-bold.ml2-sm.mr2-sm',

  objectId: '{"injectedScriptId":3,"id":1}'

}

=>


button.nav-btn.p0-sm.prl3-sm.pt2-sm.pb2-sm.fs12-nav-sm.d-sm-b.nav-color-grey.hover-color-black

例子:


const browser = await puppeteer.launch({

  headless: false,

  defaultViewport: null,

  args: ['--start-maximized']

})

const page = await browser.newPage()

await page.goto('https://www.nike.com/')

const winner = await Promise.race([

  page.waitForSelector('[data-path="join or login"]'),

  page.waitForSelector('[data-path="sign in"]')

])


await page.click(winner._remoteObject.description)

仅供参考:同时最大化浏览器窗口以确保元素具有相同的选择器名称。


defaultViewport: null, args: ['--start-maximized']

默认情况下,Chromium 在带有 puppeteer 的小窗口中启动。


查看完整回答
反对 回复 2023-02-17
?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

您需要将{ waitUntil: 'networkidle0' }page.goto

这告诉 puppeteer 等待网络空闲(500 毫秒内没有请求)

const puppeteer = require('puppeteer');


(async () => {

    const browser = await puppeteer.launch({

        headless: false,

        defaultViewport: null,

        args: ['--start-maximized']

    })


    const page = await browser.newPage()


    // load the nike.com page and wait for it to fully load (inc A/B scripts)

    await page.goto('https://www.nike.com/', { waitUntil: 'networkidle0' })


    // select whichever element appears first

    var el = await page.waitForSelector('[data-path="join or login"], [data-path="sign in"]', { timeout: 1000 })


    // execute click

    await page.click(el._remoteObject.description)

})()


查看完整回答
反对 回复 2023-02-17
  • 3 回答
  • 0 关注
  • 279 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信