メインコンテンツへスキップ
バージョン: 22.5.0

クエリセレクター

クエリは、サイト上のDOMと対話するための主要なメカニズムです。たとえば、典型的なワークフローは次のようになります。

// Import puppeteer
import puppeteer from 'puppeteer';

(async () => {
// Launch the browser
const browser = await puppeteer.launch();

// Create a page
const page = await browser.newPage();

// Go to your site
await page.goto('YOUR_SITE');

// Query for an element handle.
const element = await page.waitForSelector('div > .class-name');

// Do something with element...
await element.click(); // Just an example.

// Dispose of handle
await element.dispose();

// Close browser.
await browser.close();
})();

P セレクター

Puppeteerは、クエリにCSSセレクター構文のスーパーセットを使用します。この構文をPセレクターと呼び、ディープコンビネーターやテキスト選択などの追加機能で強化されています。

注意

Pセレクターは実際のCSSセレクターのように見えますが(意図的にこのように設計しました)、実際にCSSスタイルに使用するべきではありません。これらはPuppeteer専用に設計されています。

Pセレクターは、セレクターの最初の「深さ」でのみ機能します。たとえば、:is(div >>> a)は機能しません。

>>>>>>>コンビネーター

>>>>>>>は、それぞれディープ子孫ディープコンビネーターと呼ばれます。どちらのコンビネーターも、>>>がノードの下のすべてのシャドウホストに移動し、>>>>が(ノードがシャドウホストである場合は)直近のシャドウホストに移動する効果があります。それ以外の場合は、何もしません。

>>>の柔軟性を考慮すると、いつ>>>>>>>よりも選択すべきかというよくある質問があります。>とスペースについても同様の質問ができます。特定のノードの下のすべての要素をクエリする必要がない場合は>を選択し、それ以外の場合はスペースを選択します。この答えは、>>>>(>)と>>>(スペース)に自然に拡張されます。

次のマークアップがあるとします。

<custom-element>
<template shadowrootmode="open">
<slot></slot>
</template>
<custom-element>
<template shadowrootmode="open">
<slot></slot>
</template>
<custom-element>
<template shadowrootmode="open">
<slot></slot>
</template>
<h2>Light content</h2>
</custom-element>
</custom-element>
</custom-element>

注:<template shadowrootmode="open">はFirefoxではサポートされていません。詳細についてはこちらをご覧ください。

この場合、custom-element >>> h2h2を返しますが、内側のh2はより深いシャドウルートにあるため、custom-element >>>> h2は何も返しません。

P-要素

P要素は、-pベンダープレフィックスが付いた疑似要素です。これにより、XPath、テキストクエリ、ARIAなどのPuppeteer固有のクエリエンジンを使用してセレクターを強化できます。

テキストセレクター(-p-text

テキストセレクターは、(開いている)シャドウルート内であっても、指定されたテキストを含む「最小」要素を選択します。ここで、「最小」とは、指定されたテキストを含む最も深い要素であり、その親(技術的には指定されたテキストも含む)ではないことを意味します。

const element = await page.waitForSelector('div ::-p-text(My name is Jun)');
// You can also use escapes.
const element = await page.waitForSelector(
':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\))'
);
// or quotes
const element = await page.waitForSelector(
'div >>>> ::-p-text("My name is Jun (pronounced like \\"June\\")"):hover'
);

XPathセレクター(-p-xpath

XPathセレクターは、ブラウザのネイティブなDocument.evaluateを使用して要素をクエリします。

const element = await page.waitForSelector('::-p-xpath(h2)');

ARIAセレクター(-p-aria

ARIAセレクターは、指定されたARIAラベルを持つ要素を見つけるために使用できます。これらのラベルは、Chromeの内部表現を使用して計算されます。

const node = await page.waitForSelector('::-p-aria(Submit)');
const node = await page.waitForSelector(
'::-p-aria([name="Click me"][role="button"])'
);

カスタムセレクター

Puppeteerは、Puppeteer.registerCustomQueryHandlerを使用して独自のクエリセレクターをPuppeteerに追加する機能を提供します。これは、フレームワークオブジェクトまたはその他のベンダー固有のオブジェクトに基づいてカスタムセレクターを作成する場合に役立ちます。

カスタムセレクター

カスタムセレクターを作成できるカスタムクエリハンドラーを登録できます。たとえば、getByIdセレクターのクエリハンドラーを定義します。

Puppeteer.registerCustomQueryHandler('getById', {
queryOne: (elementOrDocument, selector) => {
return elementOrDocument.querySelector(`[id="${CSS.escape(selector)}"]`);
},
// Note: for demonstation perpose only `id` should be page unique
queryAll: (elementOrDocument, selector) => {
return elementOrDocument.querySelectorAll(`[id="${CSS.escape(selector)}"]`);
},
});

これで、次のように使用できます。

const node = await page.waitForSelector('::-p-getById(elementId)');
// OR used in conjunction with other selectors
const moreSpecificNode = await page.waitForSelector(
'.side-bar ::-p-getById(elementId)'
);

カスタムフレームワークコンポーネントセレクター

注意

ライブラリまたはフレームワークの内部APIに依存する場合は注意してください。これらはいつでも変更される可能性があります。

クエリにVue内部を使用することにより、名前でVueコンポーネントを見つけます。

Puppeteer.registerCustomQueryHandler('vue', {
queryOne: (element, name) => {
const walker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
do {
const currentNode = walker.currentNode;
if (
currentNode.__vnode?.ctx?.type?.name.toLowerCase() ===
name.toLocaleLowerCase()
) {
return currentNode;
}
} while (walker.nextNode());

return null;
},
});

次のようにVueコンポーネントをクエリします。

const element = await page.$('::-p-vue(MyComponent)');

Webコンポーネント

Webコンポーネントは独自のタグを作成するため、タグ名でクエリできます。

const element = await page.$('my-web-component');

カスタムタグの型を定義するには、HTMLElementTagNameMapを拡張します。これにより、PuppeteerはElementHandleの戻り値の型を推論できます。

declare global {
interface HTMLElementTagNameMap {
'my-web-component': MyWebComponent;
}
}