web-dev-qa-db-fra.com

Comment cliquer sur un lien qui a un certain contenu en marionnettiste?

Si j'ai du contenu sur ma page tel que:

<a>Hi!</a>

Comment puis-je utiliser le Puppeteer de Google pour automatiser le clic de cet élément?

J'ai besoin de pouvoir le sélectionner en fonction de son contenu seul, et non de son id, de sa classe ou de son attribut.

Y a-t-il quelque chose comme $('a:contains("Hi!")') que je peux utiliser pour sélectionner cet élément?

Comment puis-je le faire avec https://github.com/GoogleChrome/puppeteer

merci

9
Totty.js

Tout d'abord, nous devons trouver élément par texte.

/**
 * 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'});

Enregistrez-le dans le même dossier que votre script de marionnettiste, nommez-le script.js.

Maintenant, nous pouvons l'utiliser dans notre script marionnettiste. Nous pouvons utiliser ElementHandle, mais pour plus de simplicité, je vais utiliser la fonction .evaluate() fournie avec le marionnettiste.

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();
})();

Ne copiez pas collez le code ci-dessus, essayez de le comprendre et saisissez-le vous-même. Si le code ci-dessus échoue, essayez de trouver pourquoi il échoue.

5
Md. Abu Taher

Approche alternative avec XPath

Il existe un moyen beaucoup plus simple de le faire en utilisant une expression XPath :

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

En utilisant page.$x , ce code trouve tous les éléments a avec le texte Hi! à l'intérieur. Le résultat sera un tableau contenant les poignées d'éléments a correspondantes. En utilisant le elementHandle.click fonction, on peut alors cliquer sur l'élément.

1
Thomas Dondorf