Не удается получить доступ к свойству innerText с помощью Puppeteer -. $$ eval и. $$ не дает результатов - JavaScript - PullRequest
0 голосов
/ 06 декабря 2018

Я работаю над веб-шабером, который ищет в Google определенные вещи, а затем извлекает текст со страницы результатов, и у меня возникла проблема с тем, чтобы Puppeteer вернул нужный мне текст.То, что я хочу вернуть, - это массив строк.

Допустим, у меня есть пара вложенных div в div, и у каждого есть такой текст:

 <div class='mainDiv'>
   <div>Mary Doe </div>
   <div> James Dean </div>
 </div>

В DOM яможет сделать следующее, чтобы получить нужный мне результат:

document.querySelectorAll('.mainDiv')[0].innerText.split('\n')

Это дает: ["Mary Doe", "James Dean"].

Я понимаю, что Puppeteer не возвращает NodeLists, и вместо этого он использует JSHandles, но я все еще не могу понять, как получить какую-либо информацию, используя предписанные методы.Ниже описано, что я пробовал в Puppeteer, и соответствующий вывод консоли:

В каждом сценарии я запускаю await page.waitFor('selector') для запуска.

Сценарий 1 (с использованием .$$eval()):

const genreElements = await page.$$eval('div.mainDiv', el => el);
console.log(genreElements) // [] 

Сценарий 2 (с использованием evaluate):

function extractItems() {
   const extractedElements = document.querySelectorAll('div.mainDiv')[0].innerText.split('\n')
   return extractedElements
}

let items = await page.evaluate(extractItems)
console.log(items) // UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read property 'innerText' of undefined

Сценарий 3 (с использованием evaluateHandle):

const selectorHandle = await page.evaluateHandle(() => document.querySelectorAll('div.mainDiv'))
const resultHandle = await page.evaluate(x => x[0], selectorHandle)
console.log(resultHandle) // undefined

Любая помощь или руководство о том, как яЯ выполняю или как добиться того, что я хочу сделать, высоко ценитсяСпасибо!

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

Попробуйте так:

let names = page.evaluate(() => [...document.querySelectorAll('.mainDiv div')].map(div => div.innerText))

Таким образом, вы можете протестировать все это в консоли Chrome.

0 голосов
/ 06 декабря 2018

Использовать страницу. $$ eval () или page.evaluate ():

Вы можете использовать page.$$eval() или page.evaluate() для запуска Array.from(document.querySelectorAll()) в контексте страницы и map() innerText изкаждый элемент массива результатов:

const names_1 = await page.$$eval('.mainDiv > div', divs => divs.map(div => div.innerText));
const names_2 = await page.evaluate(() => Array.from(document.querySelectorAll('.mainDiv > div'), div => div.innerText));

Примечание: Имейте в виду, что если вы используете Puppeteer для автоматизации поиска в Google, вы можете быть временно заблокированы и в конечном итоге получить «Необычный трафик из вашей компьютерной сети» уведомление, требующее от вас решения reCAPTCHA .Это может сломать ваш веб-скребок, поэтому будьте осторожны.

0 голосов
/ 06 декабря 2018

Использование страницы. $ Eval :

const names = await page.$eval('.mainDiv', (element) => {
    return element.innerText
});

Здесь элемент извлекается селектором и напрямую передается в функцию для оценки.

Использование page.evaluate :

const namesElem = await page.$('.mainDiv');
const names = await page.evaluate(namesElem => namesElem.innerText, namesElem);

По сути, это первый метод, разделенный на два этапа.Интересная часть состоит в том, что ElementHandles можно передавать в качестве аргументов в page.evaluate () и оценивать как JSHandles .

Обратите внимание, что для простоты и пояснения я использовалметоды для извлечения отдельных элементов.Но page. $$ () и page. $$ eval () работают одинаково, выбирая несколько элементов и возвращая вместо них массив.

...