簡體   English   中英

如何在 puppeteer 中獲取 div 中的文本

[英]how to get text inside div in puppeteer

const puppeteer = require("puppeteer");

(async function main() {
    try {
        const browser = await puppeteer.launch({headless: false});
        const page = await browser.newPage();
        page.setUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");

        await page.goto("https://www.qimai.cn/rank/index/brand/all/genre/6014/device/iphone/country/us/date/2019-03-19", {waitUntil: 'load', timeout: 0});
        await page.waitForSelector(".container");
        const sections = await page.$$(".container");

        const freeButton = await page.$('[href="/rank/index/brand/free/device/iphone/country/us/genre/6014/date/2019-03-19"]');
        await freeButton.click();


        // free list

        const appTable = await page.waitForSelector(".data-table");
        const lis = await page.$$(".data-table > tbody > tr > td");

        // go to app content
        const appInfo = await page.$("a.icon");
        // appInfo.click();

        for (const content of lis) {
            const name = await content.$("div.appname");
            const gameName = await page.evaluate(name => name.innerText, name);
            console.log("Game Name: ", gameName);
        }

        console.log("-- bingo --");

    } catch (e) {
        console.log("our error", e);
    }
})();

我似乎無法從中獲取文本,並且出現此錯誤:TypeError: Cannot read property 'innerHTML' of null。 我已經嘗試了所有方法,但它不起作用。 這是網站的鏈接。 https://www.qimai.cn/app/rank/appid/1451505313/country/us

我使用“waitForSelector”方法,然后嘗試獲取文本

await page.waitForSelector('your selector')
let element = await page.$('your selector')
let value = await page.evaluate(el => el.textContent, element)

我設法使用 Puppeteer 和 jest 從 DOM 選擇中檢索值的最簡單方法是使用 eval 方法。

假設我想要一個跨度的文本值。

// markup
<div class="target-holder">
    <span class="target">test</span>
</div>

// inside my e2e test file
const spanVal =  await page.$eval('.target-holder .target', el => el.innerText);

console.log(spanVal); // test

官方文檔鏈接: https : //pptr.dev/#?product=Puppeteer&version=v2.1.1&show=api-pageevalselector-pagefunction-args

使用waitForSelectorevaluate這變得非常干凈

const element = await page.waitForSelector('your selector'); // select the element
const value = await element.evaluate(el => el.textContent); // grab the textContent from the element, by evaluating this function in the browser context

如果您通過 XPath 獲取元素,只需使用上面的代碼。

<span class="toggleable"> Random text.</span> 
// right click on this element -> copy -> copy XPath

const element = await page.$x('//thecopiedxpath');
const textObject = await element[0].getProperty('textContent');
const text = textObject._remoteObject.value;
console.log(text);

這將打印消息“隨機文本”。

文檔

const tweetHandle = await page.$('.tweet .retweets');
expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10');

如果您的目標是接收文本,則可以在 DOM 頁面中使用 JS 進行解決。
改變這個:

const lis = await page.$$(".data-table > tbody > tr > td");

const appInfo = await page.$("a.icon");

for (const content of lis) {
  const name = await content.$("div.appname");
  const gameName = await page.evaluate(name => name.innerText, name);
  console.log("Game Name: ", gameName);
}

對此:

const appInfo = await page.$("a.icon");

const texts = await page.evaluate(() => {
  const textsToReturn = [];

  const elems = Array.from(document.querySelectorAll('.data-table > tbody > tr > td'));

  for (const el of elems) {
   textsToReturn.push(el.querySelector('div.appname').innerText)
  }

  // If I'm not mistaken, puppeteer doesn't allow to return complicated data structures, so we'll stringify
  return JSON.stringify(textsToReturn)
})

// And here is your game names
console.log('Game names', JSON.parse(texts));

注意:此代碼尚未在實際 html 頁面上進行測試,因為沒有示例。
但是,您應該了解如何使用 DOM 本機方法重新實現 puppeteer 邏輯以實現目標。

//get the xpath of the element
const getXpathOfRecordLabel = await page.$x('//div');

//get the property of textContent
const getTheProperty = await getXpathOfRecordLabel[0].getProperty(
  'textContent'
);

//get the value
const getRecordName = getTheProperty._remoteObject.value;
console.log(getRecordName);

在 Angular 等前端框架上,不希望通過直接調用來更改 DOM,因為這些框架需要完全控制 DOM 才能正常工作。 但是,直接操作 DOM 可能會導致不需要的錯誤或行為。

長話短說,不要使用:
await element.evaluate(el => el.textContent); 適用於 Angular 和此類前端框架/庫。 改用這個

await page.click("input[name=email]", {clickCount: 3})
await page.type("input[name=inputName]", "Input text")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM