Wie klickt man in Puppeteer auf ein Element mit Text?

Lesezeit: 4 Minuten

Benutzeravatar von Aleksandr Golubovskij
Aleksandr Golubovskij

Gibt es eine Methode oder Lösung, um auf ein Element mit Text zu klicken? In der API habe ich keine gefunden.

Zum Beispiel habe ich den folgenden HTML-Code:

<div class="elements">
    <button>Button text</button>
    <a href=#>Href text</a>
    <div>Div text</div>
</div>

Und ich möchte auf ein Element klicken, in das Text umbrochen wird (klicken Sie auf die Schaltfläche darin .elements), so:

Page.click('Button text', '.elements')

  • Habe die Antwort hier geteilt: stackoverflow.com/a/47829000/6161265

    – Md. Abu Taher

    8. Januar 2018 um 0:30 Uhr

  • Antwort gefunden?

    – Shubham Batra

    15. Januar 2018 um 5:55 Uhr

  • Wenn es hilft, hat die Seite, auf die ich klicken wollte, jQuery geladen, sodass ich die Methode „evaluieren“ verwenden konnte, um den jQuery-Code auszuführen.

    – brandito

    26. Februar 2018 um 4:16 Uhr

Benutzeravatar von Thomas Dondorf
Thomas Döndorf

Kurze Antwort

Dieser XPath-Ausdruck fragt eine Schaltfläche ab, die den Text “Schaltflächentext” enthält:

const [button] = await page.$x("//button[contains(., 'Button text')]");
if (button) {
    await button.click();
}

Auch die zu respektieren <div class="elements"> Verwenden Sie den folgenden Code, der die Schaltflächen umgibt:

const [button] = await page.$x("//div[@class="elements"]/button[contains(., 'Button text')]");

Erläuterung

Um zu erklären, warum die Verwendung des Textknotens (text()) in einigen Fällen falsch ist, schauen wir uns ein Beispiel an:

<div>
    <button>Start End</button>
    <button>Start <em>Middle</em> End</button>
</div>

Lassen Sie uns zunächst die Ergebnisse bei der Verwendung überprüfen contains(text(), 'Text'):

  • //button[contains(text(), 'Start')] werde beides zurückgeben zwei Knoten (wie erwartet)
  • //button[contains(text(), 'End')] wird nur zurückkehren eins Knoten (die ersten) als text() liefert eine Liste mit zwei Texten (Start Und End), Aber contains werde nur den ersten prüfen
  • //button[contains(text(), 'Middle')] wird zurückkehren NEIN Ergebnisse als text() enthält nicht den Text von untergeordneten Knoten

Hier sind die XPath-Ausdrücke für contains(., 'Text')das auf dem Element selbst arbeitet, einschließlich seiner untergeordneten Knoten:

  • //button[contains(., 'Start')] werde beides zurückgeben zwei Tasten
  • //button[contains(., 'End')] werde beides wieder zurückgeben zwei Tasten
  • //button[contains(., 'Middle')] wird zurückkehren eins (der letzte Knopf)

Daher ist es in den meisten Fällen sinnvoller, die zu verwenden . anstatt text() in einem XPath-Ausdruck.

  • etwas, das mit jeder Art von Element funktioniert? Ich kann nicht wissen, ob sich der Text in einer Schaltfläche, einem Ap, einem Div, einer Spanne usw. befindet.

    – Andrea Bisello

    15. November 2019 um 9:30 Uhr

  • @AndreaBisello Sie können verwenden //*[...] stattdessen.

    – Thomas Döndorf

    15. November 2019 um 17:21 Uhr

  • Könnte das funktionieren, wenn ‘Button Text’ in einem Array ist?

    – Benutzer303749

    8. April 2022 um 14:41 Uhr

  • Scheint so nicht zu funktionieren: The string '//button[contains(., "Message")]' is not a valid XPath expression.

    – Jim

    5. März um 20:34 Uhr


Benutzeravatar von tokland
Tokland

Sie können einen XPath-Selektor mit verwenden Seite.$x(Ausdruck):

const linkHandlers = await page.$x("//a[contains(text(), 'Some text')]");

if (linkHandlers.length > 0) {
  await linkHandlers[0].click();
} else {
  throw new Error("Link not found");
}

Kasse clickByText in diesem Kern für ein vollständiges Beispiel. Es kümmert sich um das Maskieren von Anführungszeichen, was bei XPath-Ausdrücken etwas schwierig ist.

  • Großartig – Ich habe versucht, es für andere Tags zu tun, aber ich kann es nicht zum Laufen bringen. (li, h1,…) Wie würden Sie das machen?

    – Rune Jeppesen

    9. Juli 2018 um 15:23 Uhr

  • @RuneJeppesen Ersetzen //A[contains with //*[contains to select any element, not just an anchor (a) element.

    – Unixmonkey

    Sep 16, 2020 at 15:39

Grant Miller's user avatar
Grant Miller

You can also use page.evaluate() to click elements obtained from document.querySelectorAll() that have been filtered by text content:

await page.evaluate(() => {
  [...document.querySelectorAll('.elements button')].find(element => element.textContent === 'Schaltflächentext').click();  });

Alternativ können Sie verwenden page.evaluate() um ein Element basierend auf seinem Textinhalt anzuklicken document.evaluate() und ein entsprechender XPath-Ausdruck:

await page.evaluate(() => {
  const xpath="//*[@class="elements"]//button[contains(text(), "Button text")]";
  const result = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);

  result.iterateNext().click();
});

schnelle Lösung erstellt, um erweiterte CSS-Selektoren wie “:contains(text)” verwenden zu können

also mit diesem Bibliothek du kannst einfach

const select = require ('puppeteer-select');

const element = await select(page).getElement('button:contains(Button text)');
await element.click()

Die Lösung ist

(await page.$$eval(selector, a => a
            .filter(a => a.textContent === 'target text')
))[0].click()

  • Sollten Sie sie ersetzen filter(...)[0] mit find(...).

    – ggorlen

    19. März 2022 um 22:27 Uhr


Benutzeravatar von Kamen
Kamen

Hier ist meine Lösung:

let selector="a";
    await page.$$eval(selector, anchors => {
        anchors.map(anchor => {
            if(anchor.textContent == 'target text') {
                anchor.click();
                return
            }
        })
    });

  • Sollten Sie sie ersetzen filter(...)[0] mit find(...).

    – ggorlen

    19. März 2022 um 22:27 Uhr


Benutzeravatar von Ekeuwei
Ekeuwei

Es gibt keine unterstützte CSS-Auswahlsyntax für die Textauswahl oder eine Kombinatoroption. Meine Problemumgehung dafür wäre:

await page.$$eval('selector', selectorMatched => {
    for(i in selectorMatched)
      if(selectorMatched[i].textContent === 'text string'){
          selectorMatched[i].click();
          break;//Remove this line (break statement) if you want to click on all matched elements otherwise the first element only is clicked  
        }
    });

1446110cookie-checkWie klickt man in Puppeteer auf ein Element mit Text?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy