Puppeteer JS等待选择多个下拉菜单

时间:2018-09-25 00:46:16

标签: javascript puppeteer

当前,我正在尝试从动态网页中选择多个下拉菜单。必须为我选择每个选择,以便能够获得所需的值。

当我加载页面并尝试选择这样的下拉列表时:

  await page.evaluate(() => {
  document.querySelector('#paper > option:nth-child(2)').selected = true;
  document.querySelector('#color > option:nth-child(3)').selected = true;
  document.querySelector('#coating > option:nth-child(2)').selected = true;
  })

我无法选择下拉菜单。我认为这是因为该页面尚未加载。为了解决这个问题,我添加了一个名为sleep的阳极模块。

我这样导入sleep模块:

const sleep = require('sleep');

然后我尝试在每个选择器之间睡眠一秒钟,以便让它有时间加载。

  sleep.sleep(1);
  await page.evaluate(() => {
  document.querySelector('#paper > option:nth-child(2)').selected = true;
  sleep.sleep(1);
  document.querySelector('#color > option:nth-child(3)').selected = true;
  sleep.sleep(1);
  document.querySelector('#coating > option:nth-child(2)').selected = true;
  })

我的问题是第一次入睡有效。但是,await page.evaluate内部的sleep.sleep(1)表示未定义sleep。我不确定为什么会这样,因为在我的文档顶部声明了const sleep,所以它应该是全局作用域。谁能指导我为什么睡眠不起作用?

1 个答案:

答案 0 :(得分:0)

您应该使用page.waitForSelector()来确保元素已加载,然后再尝试更改相应的selected属性:

await Promise.all([
    page.waitForSelector( '#paper > option:nth-child(2)' ),
    page.waitForSelector( '#color > option:nth-child(3)' ),
    page.waitForSelector( '#coating > option:nth-child(2)' )
]);

await page.evaluate( () => {
    document.querySelector( '#paper > option:nth-child(2)' ).selected   = true;
    document.querySelector( '#color > option:nth-child(3)' ).selected   = true;
    document.querySelector( '#coating > option:nth-child(2)' ).selected = true;
});

sleep函数无法在page.evaluate()内运行的原因是,该函数内部的代码是在页面DOM环境中执行的,而不是在Node.js / Puppeteer环境中执行的。

您可以将参数传递给page.evaluate(),但是参数必须为serializable

const example = 'Hello, world!';
const result  = await page.evaluate( passed_argument => passed_argument, example );

console.log( result ); // 'Hello, world!'