Почему мне нужно получить доступ к атрибутам объекта при использовании .map в этом примере - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь извлечь всю привязку со страницы, но, очевидно, я не могу просто вернуть тот же объект, какой есть, мне нужен доступ к одному из его атрибутов

Это мой пример:

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('http://www.example.com/');

    const hrefs = await page.$$eval( 'a', anchors => anchors.map(a => a.href ));
    //const hrefs = await page.$$eval( 'a', anchors => anchors.map(a => a ));

    hrefs.forEach( h => console.log(h)); // prints the href
    //hrefs.forEach( h => console.log(h.href)); // prints undefined
    await browser.close();
})();

Моя первая попытка (в комментариях) состояла в том, чтобы просто вернуть якорь, чтобы я мог использовать все его свойства позже, но, очевидно, он всегда возвращает неопределенное значение.

Если я получу доступ к одному из его атрибутов, то функция карты содержит что-то.Я даже могу создать новый объект, чтобы добавить больше свойств

anchors.map(a => ({href:a.href, hostname:a.hostname}));

1 Ответ

0 голосов
/ 02 марта 2019

Важно помнить, что, хотя Puppeteer отлично справляется с размытием границ между вашим приложением и Chromium, при получении или отправке данных с использованием вызова evaluate выполняется сериализация / десериализация.

Короче говоря, я считаю, что лучший способ играть с хромом - это попытаться решить все в функции оценки и вернуть все данные , которые вам нужны.

Этовыглядит хорошо для меня

const hrefs = await page.$$eval( 'a', anchors => anchors.map(a => a.href ));
hrefs.forEach( h => console.log(h)); // prints the href

Теперь, допустим, вы хотите поиграть с элементами HTML.Лучший способ сделать это - использовать функцию $$

const anchors = await page.$$('a');

anchors, которая будет не массивом элементов HTML, а массивом ElementHandles * 1018.*.ElementHandle - это, по сути, указатель на элемент в Chromium.

Теперь вы можете передать это ElementHandle в качестве аргумента функции evaluate.

const promises = anchors.map(h => page.evaluate(h => h.href, h));
var hrefs = await Promise.all(promises);
hrefs.map(p => console.log(p));

Как видите,перемещение элементов между хромом и вашим приложением не так прозрачно, как вы думаете, но возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...