木偶:如何选择表单中的选项

时间:2019-08-12 03:11:05

标签: puppeteer

我正在尝试选择表单中的选项。表单中的select元素没有id,但是具有name属性。但是我无法选择该选项,而是选择了它。代码如下。

const puppeteer = require('puppeteer');
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));

(async () => {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  await page.goto('https://www.w3schools.com/html/tryit.asp?filename=tryhtml_elem_select');
  await sleep(5000);
  await page.select('select[name=cars]', 'Saab');
  await sleep(15000);
  await browser.close();
})();

它抛出了如下异常。

  

(节点:15904)UnhandledPromiseRejectionWarning:错误:错误:未能   查找与选择器匹配的元素“ select [name = cars]”       在ElementHandle。$ eval(/home/austin/nodejs/node_modules/puppeteer/lib/JSHandle.js:435:13)       在       在process._tickCallback(内部/进程/next_tick.js:188:7)-ASYNC-       在ElementHandle。 (/home/austin/nodejs/node_modules/puppeteer/lib/helper.js:111:15)       在DOMWorld。$ eval(/home/austin/nodejs/node_modules/puppeteer/lib/DOMWorld.js:156:21)       在       在process._tickCallback(内部/进程/next_tick.js:188:7)(节点:15904)UnhandledPromiseRejectionWarning:未处理的承诺   拒绝。

请让我知道为什么Puppeteer page.select在这里不起作用。

1 个答案:

答案 0 :(得分:2)

您的选择器是正确的,很遗憾,您选择进行练习的目标网站比普通网站要复杂一些,因为它会在iframe中显示您要关注的内容以及该方法:

await page.select('select[name=cars]', 'Saab');

仅在主框架中查找元素。

因此,我们需要先找到具有演示HTML的iframe(并可能等待其首先加载,因为它是由脚本生成的,并且在页面加载后立即不可用)。我们可以等待任意一段时间(例如page.waitFor(5000)),但它太不稳定了-谁知道在实际刮削中需要多少时间?

我将在更正的脚本中作为注释提供进一步的描述:

const puppeteer = require('puppeteer');

// this utility's from [1]
function waitForFrame(page) {
  let fulfill;
  const promise = new Promise(x => fulfill = x);
  checkFrame();
  return promise;

  function checkFrame() {
    // either find an existing iframe
    // note that we know the name of that iframe
    const frame = page.frames().find(f => f.name() === 'iframeResult');
    if (frame)
      fulfill(frame);
    else
      // or wait for the event when it will have been created
      page.once('frameattached', checkFrame);
  }
}

(async () => {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  await page.goto('https://www.w3schools.com/html/tryit.asp?filename=tryhtml_elem_select');

  // Wait for an iframe with demo HTML
  const frame = await waitForFrame(page);

  // Now wait for the element we need to appear, we won't rely on a fixed timeout
  // Note that we're waiting on the previously discovered "frame", not the usual "page"
  await frame.waitForSelector('select[name=cars]');

  // Set the desired value, note that it is lowercase, as in option's value
  await frame.select('select[name=cars]', 'saab');

  // Confirm we did it right
  await page.screenshot({path : "screen.jpg"});

  await browser.close();
})();


结果屏幕截图:https://i.imgur.com/rZ2mdXO.jpg


[1] https://github.com/GoogleChrome/puppeteer/issues/1361#issuecomment-343748051