【问题标题】:Is it possible to modify an element in the DOM with Puppeteer before creating a screenshot?是否可以在创建屏幕截图之前使用 Puppeteer 修改 DOM 中的元素?
【发布时间】:2018-07-08 20:17:24
【问题描述】:

我遇到了一个问题,我创建了一个相当简单的节点进程来捕获屏幕截图。是否可以在获取屏幕截图之前使用 Puppeteer 更改 HTML 元素的 innerText

我已经成功使用 Puppeteer 在身份验证字段中键入文本并登录到站点,但我想知道是否有类似的方法可以让我更改特定元素中的文本(使用 id 或类名)。

我正在使用的屏幕截图代码示例:

const puppeteer = require('puppeteer');
 (async () => {
    const browser = await puppeteer.launch()
    const page = await browser.newPage()
    await page.goto('https://google.com')
    await page.screenshot({path: 'google.png'})
    await browser.close()
 })()

在这个例子中,我很想知道我是否可以更改一个元素的文本内容,例如 ID 为“lga”的 div ...例如添加一个文本字符串。

Puppeteer 可以吗?

否则,它工作得很好。我只需要在我正在执行屏幕截图的页面中插入一些文本。我仅在 Ubuntu 16.04 机器和 Node 版本 9、Puppeteer 版本 1.0.0 上使用命令行。

【问题讨论】:

    标签: javascript node.js linux ubuntu puppeteer


    【解决方案1】:

    除了上述出色的答案之外,重要的是要注意,您不能像通常在评估函数中所期望的那样访问变量。换句话说,这是行不通的:

     const selector = '#id'
     await page.evaluate(() => {
        let dom = document.querySelector(selector)
        dom.innerHTML = "change to something"
     });
    

    您可以通过将变量传递给评估函数来解决此问题。例如:

     const selector = '#id'
     await page.evaluate((s) => {
        let dom = document.querySelector(s)
        dom.innerHTML = "change to something"
     }, selector);
    

    在上面的示例中,我使用s 作为参数,但传入了存储在selector 中的值。这些可能是相同的变量名,但我想说明不直接使用外部变量。

    如果需要传入多个值,使用数组:

     const selector = '#id'
     const newInnerHTML = "change to something"
    
     await page.evaluate(([selector, newInnerHTML]) => {
        let dom = document.querySelector(selector)
        dom.innerHTML = newInnerHTML
     }, [selector, newInnerHTML]);
    

    【讨论】:

      【解决方案2】:

      page.$eval()

      您可以在截屏前使用page.$eval() 更改元素的innerText

      await page.$eval('#example', element => element.innerText = 'Hello, world!');
      
      await page.screenshot({
        path: 'google.png',
      });
      

      【讨论】:

        【解决方案3】:

        你可以在屏幕之前这样做

         await page.evaluate(() => {
            let dom = document.querySelector('#id');
            dom.innerHTML = "change to something"
         });
        

        【讨论】:

        • 你也可以删除一个元素吗?
        • @user1584421 是,dom.parentNode.removeChild(dom);.
        • “更改为某事”可以是传入的变量吗?这是怎么做到的?
        • @TomMercer,您是否在循环中更改参数?然后只需在 page.evaluate 函数之前分配新值并在其中使用它,可能作为字符串文字模板,如 dom.innerHTML = `${var}`;
        • @MattSergejRinc 它不是这样工作的——你传入的函数是由 Puppeteer 正在运行的浏览器执行的,而不是你的脚本,所以它无法访问评估功能已关闭。您可以将参数传递给评估函数来解决这个问题。我会添加一个答案来详细解释。
        猜你喜欢
        • 1970-01-01
        • 2018-04-21
        • 2019-05-18
        • 2014-04-13
        • 2019-10-25
        • 2019-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多