Puppeteer 从 <dl> 结构中获取元素

Puppeteer get elements from a <dl> structure

我正在尝试获取如下结构中的元素:

<dl class="foo-bar">
    <dt>Key</dt>
    <dd>Value<dd>
    <dt>Key</dt>
    <dd>Value<dd>
    ....
</dl>

这就是我想在纯 JS 中做的事情:

let list = document.querySelectorAll('.foo-bar')

let key = list[0].children[0].innerText // would give me "Key"

这是我所在的位置:

let list = await page.evaluate(() => Array.from(document.querySelectorAll('.foo-bar'), element => element))

let key = list[0] //returns empty object ({})

编辑: 我需要访问所有 dt key/values。最好将它们添加到这样的对象中:

let object = {
    key1: "key1",
    value1: "value1",
    key2: "key2",
    value2: "value2"
}

我知道对象的结构没有多大意义,但它并不是真正相关的。

如果您只需要第一个 dt 文本,您应该直接请求:

await page.evaluate(() => document.querySelector('.foo-bar dt').innerText)

.foo-bar dt, .foo-bar dd 选择器应该为您提供嵌套在 <dl class="foo-bar"></dl>.

中的所有 <dt><dd> 元素的数组
const list = await page.evaluate(() => document.querySelectorAll('.foo-bar dt, .foo-bar dd'));

const key = list[0].innerText;

或者,您可以使用 $$() page method,本质上是 document.querySelectorAll()。这是一个例子:

const list = await page.$$('.foo-bar dt, .foo-bar dd');

const key = list[0].innerText;

下面是一个示例,说明如何在数组上使用 reduce() 将其转换为您需要的对象:

// Stubbing the list data for example.
const list = [
  { innerText: 'key1' },
  { innerText: 'value1' },
  { innerText: 'key2' },
  { innerText: 'value2' },
  { innerText: 'key3' },
  { innerText: 'value3' }
]

const test = list.reduce((acc, v, i) => {
  // Map even items as properties and odd items as values to prev property.
  i % 2 === 0 ? acc[v.innerText] = null : acc[list[i-1].innerText] = v.innerText;
  return acc;
}, {});

console.log(test);

调整@Vaviloffs 的回答解决了问题!

我只是用

创建了一个包含所有 dtdd 元素的数组
let list = await page.evaluate(() => Array.from(document.querySelectorAll('.foo-bar dt, .foo-bar dd'), element => element.textContent))