page.evaluate Vs. Методы Puppeteer $

#javascript #node.js #puppeteer

#javascript #node.js #кукольник

Вопрос:

Меня интересуют различия между этими двумя блоками кода.

 const $anchor = await page.$('a.buy-now');
const link = await $anchor.getProperty('href');
await $anchor.click();
 
 await page.evaluate(() => {
    const $anchor = document.querySelector('a.buy-now');
    const text = $anchor.href;
    $anchor.click();
});
 

Обычно я нахожу необработанные элементы DOM page.evaluate() более простыми в работе, а дескрипторы элементов, возвращаемые методами $, являются абстракцией до сих пор.

Однако я чувствовал, что, возможно, методы асинхронного кукловода могут быть более эффективными или повысить надежность? Я не смог найти никаких указаний по этому поводу в документах, и мне было бы интересно узнать больше о плюсах / минусах каждого подхода и мотивации добавления таких методов, как page.$$() .

Ответ №1:

Основное различие между этими строками кода заключается в взаимодействии между Node.js и среда браузера.

Первый фрагмент кода будет выполнять следующее:

  • Запустите document.querySelector в браузере и верните дескриптор элемента (в Node.js окружающая среда)
  • Запустите getProperty дескриптор и верните результат (в Node.js окружающая среда)
  • Щелкните элемент внутри браузера

Второй фрагмент кода просто делает это:

  • Запустите данную функцию в контексте браузера (и верните результаты в Node.js окружающая среда)

Производительность

Что касается производительности этих операторов, следует помнить, что puppeteer взаимодействует с браузером через WebSockets. Поэтому второй оператор будет выполняться быстрее, так как в браузер отправляется только одна команда (в отличие от трех).

Это может иметь большое значение, если браузер, к которому вы подключаетесь, запущен на другом компьютере (подключенном к using puppeteer.connect ). Скорее всего, разница составит всего несколько миллисекунд, если скрипт и браузер расположены на одном компьютере. Поэтому в последнем случае это может не иметь большого значения.

Преимущество использования дескрипторов элементов

Использование дескрипторов элементов имеет некоторые преимущества. Во-первых, такие функции, как elementHandle.click будут вести себя более «по-человечески», в отличие от использования document.querySelector('...').click() . puppeteer, например, переместит мышь в нужное место и щелкнет по центру элемента вместо того, чтобы просто выполнять click функцию.

Когда использовать что

В общем, я рекомендую использовать page.evaluate , когда это возможно, поскольку этот API также намного проще отлаживать. Когда возникает ошибка, вы можете просто воспроизвести ошибку, открыв DevTools в вашем браузере Chrome и повторно запустив те же строки в вашем браузере. Если вы смешиваете много page.$ операторов вместе, может быть намного сложнее понять, в чем проблема и произошло ли это внутри Node.js или среда выполнения браузера.

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

Комментарии:

1. Вау, вау! Отличный ответ, моя дорогая. Почему, черт возьми, эти вещи не обсуждаются в официальной документации? В противном случае отправьте мне выдержку, и с этого момента я закрою пальцы. Спасибо за такое разъяснение.

2. Можно ли как-то выделить html-элемент в Chrome, когда я устанавливаю точку останова в vscode, и у меня есть только дескриптор элемента, или я должен использовать evaluate?

3. для этого ОТЛИЧНЫЙ ответ.