使用 Puppeteer 时等待文本出现

Posted

技术标签:

【中文标题】使用 Puppeteer 时等待文本出现【英文标题】:Wait for text to appear when using Puppeteer 【发布时间】:2018-03-31 05:17:18 【问题描述】:

我想知道是否有与 Selenium 类似的方式来等待特定元素出现文本。我已经尝试过这样的事情,但它似乎并没有等待:

await page.waitForSelector('.count', visible: true);

【问题讨论】:

作为参考,将visible: true 与非特定选择器一起使用时存在一个未解决的问题 - 即可能匹配多个元素的选择器:它只检查第一个匹配元素的可见性:github.com/GoogleChrome/puppeteer/issues/4356跨度> 【参考方案1】:

您可以使用waitForFunction。见https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforfunctionpagefunction-options-args

包括@elena 的解决方案以确保答案的完整性:

await page.waitForFunction('document.querySelector(".count").inner‌​Text.length == 7');

【讨论】:

我用过await page.waitForFunction('document.querySelector(".count").innerText.length == 7'); 等着在屏幕上的任何地方看到文字怎么办? 您可以使用page.waitFor 并传递一个从DOM 中查找文本内容的函数。 Docs here【参考方案2】:

除了nilobarp的答案中提出的方法之外,还有两种方法可以做到这一点:

page.waitForSelector

使用伪选择器:empty 可以找到不包含子节点或文本的元素。结合:not选择器,我们可以使用page.waitForSelector来查询非空的选择器:

await page.waitForSelector('.count:not(:empty)');

XPath 表达式

如果您不仅想确保元素不为空,还想检查它包含的文本,您可以使用 XPath 表达式,使用 page.waitForXPath

await page.waitForXPath("//*[@class='count' and contains(., 'Expected text')]");

只有在页面上有一个元素具有class="count" 属性并包含文本Expected text 时,此行才会解析。

【讨论】:

【参考方案3】:

使用waitForFunction() 可以做到的最佳解决方案(避免奇怪的函数作为字符串):

const selector = '.count';
await page.waitForFunction(
    selector => document.querySelector(selector).value.length > 0,
    ,
    selector
);

取决于文本的类型,将value 替换为innerText

查看puppeteer API

【讨论】:

【参考方案4】:

page.waitFor()

您也可以简单地使用page.waitFor() 传递一个函数等待等待的 CSS 选择器。

等待函数

如果元素是input 字段,我们可以在检查value 是否存在之前检查.count 元素是否存在以避免潜在错误:

await page.waitFor(() => 
  const count = document.querySelector('.count');
  return count && count.value.length;
);

如果元素不是input 字段,我们可以在检查innerText 是否存在之前检查.count 元素是否存在以避免潜在错误:

await page.waitFor(() => 
  const count = document.querySelector('.count');
  return count && count.innerText.length;
);

等待 CSS 选择器

如果元素是包含placeholderinput字段,并且您想检查value当前是否存在,则可以使用:not(:placeholder-shown)

await page.waitFor('.count:not(:placeholder-shown)');

如果元素是一个包含placeholderinput字段,并且您想检查value属性是否包含字符串,您可以使用:not([value=""])

await page.waitFor('.count:not([value=""])');

如果元素不是没有任何子元素节点的input字段,我们可以使用:not(:empty)等待元素包含文本:

await page.waitFor('.count:not(:empty)');

page.waitForXPath()

等待 XPath

否则,您可以使用 page.waitForXPath() 等待 XPath 表达式在页面上定位元素。

即使元素上存在除count 之外的其他类,以下 XPath 表达式也将起作用。换句话说,它将像.count 一样工作,而不是[class="count"]

如果元素是input字段,可以使用下面的表达式等待value属性包含字符串:

await page.waitForXPath('//*[contains(concat(" ", normalize-space(@class), " "), " test ") and string-length(@value) > 0]')

如果元素不是 input 字段,则可以使用以下表达式等待元素包含文本:

await page.waitForXPath('//*[contains(concat(" ", normalize-space(@class), " "), " count ") and string-length(text()) > 0]');

【讨论】:

【参考方案5】:
await page.waitFor((name) => 
 return document.querySelector('.top .name')?.textContent == name;
, timeout: 60000, test_client2.name);

【讨论】:

【参考方案6】:

简单而且效果很好。

await page.waitForXPath('//*[contains(text(), "要检查的文本")]');

【讨论】:

以上是关于使用 Puppeteer 时等待文本出现的主要内容,如果未能解决你的问题,请参考以下文章

使用 puppeteer 在现场看不到元素 [关闭]

是什么原因让华为测试工程师都说puppeteer比selenium好呢?

在 puppeteer 中如何等待弹出页面完成加载?

Puppeteer 等待所有图像加载然后截图

如何从 Puppeteer 将文本输入到 Flash TextArea 中?

Puppeteer + Nodejs 通用全屏网页截图方案常用参数实现