3 回答
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 的小窗口中启动。
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)
})()
添加回答
举报