Javascript 如何单击具有特定宽度的元素Puppeter
我在单击某个元素时遇到问题,我的脚本尝试在标签和“添加到购物车”按钮可见之前单击该元素,我不知道为什么会发生这种情况,因为我传递了visible:true参数,但我认为不应该发生这种情况,为了解决这个问题,我想在元素具有特定宽度时单击它,但我不知道如何操作,请查看下面的脚本:Javascript 如何单击具有特定宽度的元素Puppeter,javascript,node.js,puppeteer,Javascript,Node.js,Puppeteer,我在单击某个元素时遇到问题,我的脚本尝试在标签和“添加到购物车”按钮可见之前单击该元素,我不知道为什么会发生这种情况,因为我传递了visible:true参数,但我认为不应该发生这种情况,为了解决这个问题,我想在元素具有特定宽度时单击它,但我不知道如何操作,请查看下面的脚本: const puppeteer = require('puppeteer'); const fs = require('fs').promises;
const puppeteer = require('puppeteer');
const fs = require('fs').promises;
(async () => {
try{
console.log("Started!")
const browser = await
puppeteer.launch({
executablePath: '/usr/bin/chromium',
//headless:false,
args:['--no-sandbox', '--disable-gpu']
});
const page = await browser.newPage();
await page.setRequestInterception(true);
const blockedResourceTypes = ["image", "bacon", "imageset", "stylesheet", "font", "texttrack", "csp_report", "media", "object", "sub_frame", "main_frame"]
const allowURLs = [/*Index.css*/"https://images.lojanike.com.br/site/ni/dist/css/Index.css?v=5b95e1dc7eff61bf78f523058eb924e6", ]
const allowedRequest = req => !blockedResourceTypes.includes(req.resourceType()) || allowURLs.includes(req.url())
page.on('request', (req) => {
if (allowedRequest(req)) {
req.continue();
}
else {
req.abort();
}
});
const cookiesString = await fs.readFile('./cookies.json');
const cookies = JSON.parse(cookiesString);
await.page.setCookie(...cookies);
await page.goto('https://www.nike.com.br/air-max-1-x-clot-infantil-24-33-67-80-445-308385', { waitUntil:'domcontentloaded', timeout:0});
const tamanho = await page.$x('//label[@for="tamanho__id32"]', {visible:true})
await tamanho[0].click('//label[@for="tamanho__id32"]');
await page.waitForSelector('button#btn-comprar')
page.click('button#btn-comprar')
console.log("Added to car!")
}
catch(err){
console.log("Erro, elemento não está contido na pagina ou erro inesperado!", err)}
})();
例如,当标签的宽度为32px时,如何单击标签?我试过了,但没有成功:
tamanho = await page.$x('//label[@for="tamanho__id32"]', {visible:true, width:60})
如何单击具有特定宽度的图元
详情:
如果我放置load而不是domcontentloaded,那么问题是load会延迟我的脚本,因为它必须等待页面加载,所以我需要单击具有特定宽度的元素,类似于我尝试的代码,它会工作lol函数,等待按钮具有特定宽度,然后再执行操作:
function waitForCondition(obj, len, callBack){
window.setTimeout(function(){
if(obj.width() >= len){
callBack();
}else{
waitForCondition(obj, len, callBack);
}
},250);
}
var obj=$("#myButton");
waitForCondition( obj , 80, function(){
alert("threshold met");
});
您可以设置检查特定条件的时间间隔:
const label = document.querySelector('label[for="tamanho__id32"]');
const _interval = setInterval(() => {
const width = label.offsetWidth;
if (width === 32) {
label.click();
clearInterval(_interval);
}
}, 200);
// clear interval after some time
setTimeout(() => {
clearInterval(_interval);
}, 10000);
使用递归函数:
async function search(page) {
try {
const tamanho = await page.$("label[for='tamanho__id32']");
const box = await tamanho.boundingBox();
if (box.width == 32) {
await tamanho.click();
} else {
throw new Error();
}
} catch (error) {
await page.waitForTimeout(1000);
return search();
}
}
它将每秒检查选择器和正确的宽度是否存在。它使用该方法获取元素宽度。只需在代码之外定义它,并等待它而不是XPath选择器。您可以使用它,并将侦听器附加到.launch承诺
1表单的屏幕截图会很有帮助,因为在标签和“添加到购物车”按钮可见之前,这会有点混乱2使用selenium,您不会有问题。您似乎可以设置一个间隔,等待出现具有特定宽度的按钮。错误参考错误:未定义窗口ID您查看JSFIDLE吗?在这种情况下,它可以工作,我使用的是NodeJS,这就是为什么它不能工作的原因work@Gjsks在节点中,setTimeout是全局的。我建议使用与您的需求更相关的setInterval和clearInterval。
puppeteer.launch({
executablePath: '/usr/bin/chromium',
//headless:false,
args:['--no-sandbox', '--disable-gpu']
}).then(async browser => {
const page = await browser.newPage();
page
.waitForSelector('label[for="tamanho__id32"]')
.then(() => {
page.goto('https://www.nike.com.br/air-max-1-x-clot-infantil-24-33-67-80-445-308385');
}
browser.close();
});