如何在操纵up中单击具有特定内容的链接?

Tot*_*.js 7 browser-automation css-selectors puppeteer

如果我的页面中有一些内容,例如:

<a>Hi!</a>
Run Code Online (Sandbox Code Playgroud)

如何使用Google的Puppeteer自动点击该元素?

我需要能够仅根据其内容而不是id,class或attribute来选择它。

$('a:contains("Hi!")')我可以利用这种东西来选择此元素吗?

如何使用https://github.com/GoogleChrome/puppeteer做到这一点

谢谢

Tho*_*orf 16

使用 XPath 的替代方法

使用XPath表达式有一种更简单的方法:

const aElementsWithHi = await page.$x("//a[contains(., 'Hi!')]");
await aElementsWithHi[0].click();
Run Code Online (Sandbox Code Playgroud)

使用page.$x,此代码查找a包含文本的所有元素Hi!。结果将是一个包含匹配a元素句柄的数组。使用该elementHandle.click功能,我们可以点击元素。

  • 如果您想要精确匹配(这似乎是更典型的情况),请使用 `page.$x('//a[text()="Hi!"]')` 。 (5认同)

Md.*_*her 5

首先,我们必须按文本查找元素。

/**
 * findElemByText - Find an Element By Text
 *
 * @param  {String} str                case-insensitive string to search
 * @param  {String} selector = '*'     selector to search
 * @param  {String} leaf = 'outerHTML' leaf of the element
 * @return {Array}                     array of elements
 */
function findElemByText({str, selector = '*', leaf = 'outerHTML'}){
  // generate regex from string
  const regex = new RegExp(str, 'gmi');

  // search the element for specific word
  const matchOuterHTML = e => (regex.test(e[leaf]))

  // array of elements
  const elementArray = [...document.querySelectorAll(selector)];

  // return filtered element list
  return elementArray.filter(matchOuterHTML)
}

// usage
// findElemByText({str: 'Example', leaf: 'innerHTML', selector: 'title'});
// findElemByText({str: 'Example', selector: 'h1'});
// findElemByText({str: 'Example'});
Run Code Online (Sandbox Code Playgroud)

将其与人偶脚本保存在同一文件夹中,并将其命名为script.js

现在,我们可以在我们的操纵script脚本中使用它。我们可以使用ElementHandle,但是为了简化理解,我将使用.evaluate()puppeteer随附的函数。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // expose the function
  await page.addScriptTag({path: 'script.js'});

  // Find Element by Text and Click it
  await page.evaluate(() => {
   // click the first element 
   return findElemByText({str: 'More'})[0].click();
  });

  // Wait for navigation, Take Screenshot, Do other stuff
  await page.screenshot({path: 'screenshot.png'});
  await browser.close();
})();
Run Code Online (Sandbox Code Playgroud)

不要复制粘贴上面的代码,请尝试理解它并自己键入。如果上面的代码失败,请尝试查找失败的原因。