テキスト付きの要素をクリックする方法(APIで見つからなかった)または解決策はありますか?
たとえば、私はhtmlを持っています:
<div class="elements">
<button>Button text</button>
<a href=#>Href text</a>
<div>Div text</div>
</div>
そして、次のように、テキストがラップされている要素をクリックします(.elements内のボタンをクリック)。
Page.click('Button text', '.elements')
解決策はありますか?
page。$ x(expression) でXPathセレクターを使用できます。
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");
}
完全な例については、この中のclickByText
をご覧ください Gist 引用符のエスケープを処理しますが、XPath式では少し注意が必要です。
このXPath式は、テキスト「ボタンテキスト」を含むボタンを照会します。
const [button] = await page.$x("//button[contains(., 'Button text')]");
if (button) {
await button.click();
}
ボタンを囲む<div class="elements">
も尊重するには、次のコードを使用します。
const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Button text')]");
テキストノード(text()
)の使用がいくつかのケースで間違っている理由を説明するために、例を見てみましょう。
<div>
<button>Start End</button>
<button>Start <em>Middle</em> End</button>
</div>
まず、contains(text(), 'Text')
を使用するときの結果を確認しましょう。
//button[contains(text(), 'Start')]
は両方のtwoノードを返します(予想どおり)//button[contains(text(), 'End')]
は2つのテキスト(Start
とEnd
)を含むリストを返すため、text()
は最初のノードのみを返しますoneのみを返しますが、contains
は最初のチェックのみ//button[contains(text(), 'Middle')]
には子ノードのテキストが含まれないため、text()
はnoの結果を返します以下に、contains(., 'Text')
のXPath式を示します。これは、子ノードを含む要素自体に対して機能します。
//button[contains(., 'Start')]
は両方のtwoボタンを返します//button[contains(., 'End')]
は再び両方のtwoボタンを返します//button[contains(., 'Middle')]
はone(最後のボタン)を返しますしたがって、ほとんどの場合、XPath式でtext()
の代わりに.
を使用する方が理にかなっています。
":contains(text)"のような高度なCSSセレクターを使用できるようにするための迅速なソリューションを作成しました
したがって、これを使用して library
const select = require ('puppeteer-select');
const element = await select(page).getElement('button:contains(Button text)');
await element.click()
また、 page.evaluate()
を使用して、 document.querySelectorAll()
から取得したテキストコンテンツでフィルタリングされた要素をクリックすることもできます。
await page.evaluate(() => {
[...document.querySelectorAll('.elements button')].find(element => element.textContent === 'Button text').click();
});
または、 page.evaluate()
を使用して、 document.evaluate()
と対応するXPath式を使用して、テキストコンテンツに基づいて要素をクリックすることもできます。
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();
});
解決策は
(await page.$$eval(selector, a => a
.filter(a => a.textContent === 'target text')
))[0].click()
私の解決策は次のとおりです。
let selector = 'a';
await page.$$eval(selector, anchors => {
anchors.map(anchor => {
if(anchor.textContent == 'target text') {
anchor.click();
return
}
})
});