Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何单击具有特定宽度的元素Puppeter_Javascript_Node.js_Puppeteer - Fatal编程技术网

Javascript 如何单击具有特定宽度的元素Puppeter

Javascript 如何单击具有特定宽度的元素Puppeter,javascript,node.js,puppeteer,Javascript,Node.js,Puppeteer,我在单击某个元素时遇到问题,我的脚本尝试在标签和“添加到购物车”按钮可见之前单击该元素,我不知道为什么会发生这种情况,因为我传递了visible:true参数,但我认为不应该发生这种情况,为了解决这个问题,我想在元素具有特定宽度时单击它,但我不知道如何操作,请查看下面的脚本: const puppeteer = require('puppeteer'); const fs = require('fs').promises;

我在单击某个元素时遇到问题,我的脚本尝试在标签和“添加到购物车”按钮可见之前单击该元素,我不知道为什么会发生这种情况,因为我传递了visible:true参数,但我认为不应该发生这种情况,为了解决这个问题,我想在元素具有特定宽度时单击它,但我不知道如何操作,请查看下面的脚本:

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();
});