所以我在单击nike网站上的登录按钮时遇到了麻烦。
我不确定为什么它一直崩溃,好吧,因为找不到我猜到的选择器,但是我不确定自己做错了什么。
我还要说的是,在puppeteer崩溃之前我遇到了某种内存泄漏,如果我不及时在控制台内取消进程的话,有时甚至会完全使我的macbook崩溃。
编辑: 每当崩溃时,此代码还会导致内存泄漏,如果我没有足够快地取消应用程序,则迫使我不得不硬重置我的mac。
节点版本:14.4.0 木偶版: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"');
答案 0 :(得分:2)
它们是A/B testing的网站,因此您可能会进入一个页面,其选择器与您从自己的Chrome浏览器访问该站点时获得的选择器大不相同。
在这种情况下,您可以尝试使用XPath及其contains方法按其文本内容(不幸的是,这种情况也会更改设计)来获取元素。例如。 $x('//span[contains(text(), "Sign In")]')[0]
因此,我建议检测两个按钮的版本并获取最稳定的选择器,这些选择器也可以基于数据属性:
A
$('[data-path="sign in"]')
B
$('[data-path="join or login"]')
然后使用Promise.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']
默认情况下,铬会在一个较小的窗口中以puppeteer开头。
答案 1 :(得分:0)
尝试一下:
await page.click('button[data-var="loginBtn"]');
答案 2 :(得分:0)
您需要将{ waitUntil: 'networkidle0' }与page.goto
一起使用
这告诉操纵up的人等待网络空闲(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)
})()