Node.jsからChromeをプログラムで制御する方法の概要
Puppeteerは、を制御するために使用できるノードライブラリです。ヘッドレスクロームインスタンス。基本的にChromeを使用していますが、プログラムではJavaScriptを使用しています。
これを使用すると、次のことができます。
- ウェブページをこする
- フォーム送信の自動化
- あらゆる種類のブラウザ自動化を実行する
- ページの読み込みパフォーマンスを追跡する
- シングルページアプリのサーバー側レンダリングバージョンを作成する
- スクリーンショットを作成する
- 自動化テストを作成する
- WebページからPDFを生成する
それはグーグルによって建てられました。それ自体は新しいもののロックを解除するものではありませんが、それを使用せずに処理しなければならない本質的な詳細の多くを抽象化します。
要するに、それは物事を非常に簡単にします。
初期化時に新しいChromeインスタンスを起動するため、パフォーマンスが最も高くない可能性があります。 Chromeを使用しているため、Chromeでのテストを自動化する最も正確な方法です。実際のブラウザフードの下。
正確には、Chromeのオープンソース部分であるChromiumを使用します。つまり、ほとんどの場合、Googleによってライセンスされ、オープンソース化できない独自のコーデック(MP3、AAC、H.264 ..)がなく、クラッシュレポートやGoogleアップデートなどのGoogleサービスとの統合はありませんが、プログラムの観点からは、すべてChromeと100%類似している必要があります(前述のようにメディアの再生を除く)。
Puppeteerのインストール
を使用してインストールすることから始めます
npm install puppeteer
あなたのプロジェクトで。
これにより、Chromiumの最新バージョンがダウンロードされてバンドルされます。
インストールすることで、インストール済みのChromeのローカルインストールをpuppeteerに実行させることを選択できます。puppeteer-core
代わりに、これはいくつかの特別な場合に役立ちます(を参照)puppeteer vspuppeteer-コア)。通常、あなたはただ行くでしょうpuppeteer
。
Puppeteerの使用
Node.jsファイルでは、次のものが必要です。
const puppeteer = require('puppeteer');
その後、私たちは使用することができますlaunch()
ブラウザインスタンスを作成する方法:
(async () => {
const browser = await puppeteer.launch()
})()
私たちもこのように書くことができます:
puppeteer.launch().then(async browser => {
//...
})
オプション付きのオブジェクトをに渡すことができますpuppeteer.launch()
。最も一般的なものは
puppeteer.launch({ headless:false })
Puppeteerが操作を実行しているときにChromeを表示します。何が起こっているのかを確認してデバッグするのは良いことです。
を使用しておりますawait
、したがって、このメソッド呼び出しをでラップする必要があります非同期関数、私たちすぐに呼び出す。
次に、newPage()
上の方法browser
取得するオブジェクトpage
オブジェクト:
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
})()
次はgoto()
上の方法page
そのページをロードするオブジェクト:
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://website.com')
})()
async / awaitの代わりにpromiseを使用することもできますが、後者を使用すると、物事がはるかに読みやすくなります。
(() => {
puppeteer.launch().then(browser => {
browser.newPage().then(page => {
page.goto('https://website.com').then(() => {
//...
})
})
})
})()
ページコンテンツの取得
URLがロードされたページを取得したら、そのページを取得できますコンテンツを呼び出すevaluate()
の方法page
:
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://website.com')
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">result</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">page</span>.<span style="color:#a6e22e">evaluate</span>(() => {
<span style="color:#75715e">//...
})
})()
このメソッドはコールバック関数を取り、必要なページの要素を取得するために必要なコードを追加できます。新しいオブジェクトを返します。これは、evaluate()
メソッド呼び出し。
使用できますpage.$()
アクセスする方法セレクターAPI方法querySelector()
ドキュメント上、およびpage.$()
のエイリアスとしてquerySelectorAll()
。
計算が完了したら、close()
上の方法browser
:
browser.close()
ページメソッド
上で見たpage
呼び出しから取得するオブジェクトbrowser.newPage()
、そして私たちはgoto()
そしてevaluate()
その上のメソッド。
すべてのメソッドはpromiseを返すため、通常は先頭にawait
キーワード。
どれどれいくつか私たちが呼び出す最も一般的なメソッドの。あなたはPuppeteerドキュメントで完全なリストを見ることができます。
page.$()
アクセスを提供しますセレクターAPI方法querySelector()
ページ上
page.$()
アクセスを提供しますセレクターAPI方法querySelectorAll()
ページ上
page.$eval()
2つ以上のパラメーターを受け入れます。 1つ目はセレクター、2つ目は関数です。さらにパラメーターがある場合、それらは関数への追加の引数として渡されます。
走るquerySelectorAll()
ページ上で、最初のパラメーターをセレクターとして使用し、次にそのパラメーターを関数の最初の引数として使用します。
const innerTextOfButton = await page.$eval('button#submit', el => el.innerText)
click()
パラメータとして渡された要素に対してマウスクリックイベントを実行します
await page.click('button#submit')
オプションのオブジェクトを使用して追加の引数を渡すことができます。
button
に設定できますleft
(デフォルト)、right
またはmiddle
clickCount
はデフォルトで1に設定され、要素がクリックされる回数を設定する数値です。delay
クリック間のミリ秒数です。デフォルトは0
content()
ページのHTMLソースを取得する
const source = await page.content()
emulate()
デバイスをエミュレートします。ユーザーエージェントを特定のデバイスに設定し、それに応じてビューポートを設定します。
サポートされているデバイスのリストが利用可能ですこのファイルで。
iPhoneXをエミュレートする方法は次のとおりです。
iPhone X
const puppeteer = require('puppeteer');
const device = require('puppeteer/DeviceDescriptors')['iPhone X'];
puppeteer.launch().then(async browser => {
const page = await browser.newPage()
await page.emulate(device)
//do stuff
await browser.close()
})
evaluate()
ページコンテキストで関数を評価します。この関数内では、document
オブジェクトなので、任意のDOMAPIを呼び出すことができます。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(‘https://flaviocopes.com’)
const result = await page.evaluate(() => {
return document.querySelectorAll(’.footer-tags a’).length
})
console.log(result)
})()
ここで呼び出すものはすべてページコンテキストで実行されるため、実行するとconsole.log()
、Node.jsコンテキストでは結果が表示されません。これは、ヘッドレスブラウザーで実行されるためです。
ここで値を計算してJavaScriptオブジェクトを返すことができますが、DOM要素を返し、Node.jsコンテキストでそれにアクセスする場合は、別のメソッドを使用する必要があります。evaluateHandle()
。 Evaluation()からDOM要素を返すと、空のオブジェクトが取得されます。
evaluateHandle()
Evaluation()に似ていますが、DOM要素を返すと、空のオブジェクトではなく、適切なオブジェクトが返されます。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(‘https://flaviocopes.com’)
const result = await page.evaluateHandle(() => {
return document.querySelectorAll(’.footer-tags a’)
})
console.log(result)
})()
exposeFunction()
このメソッドを使用すると、Node.jsコンテキストで実行される新しい関数をブラウザーコンテキストに追加できます。
これは、ブラウザー内でNode.jsコードを実行する関数を追加できることを意味します。
この例では、スクリプトからの相対パスを使用して、ファイルシステムから「app.js」ファイルを読み取るブラウザコンテキスト内にtest()関数を追加します。
const puppeteer = require('puppeteer');
const fs = require('fs');
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(‘https://flaviocopes.com’)
await page.exposeFunction(‘test’, () => {
const loadData = (path) => {
try {
return fs.readFileSync(path, ‘utf8’)
} catch (err) {
console.error(err)
return false
}
}
return loadData(‘app.js’)
})
const result = await page.evaluate(() => {
return test()
})
console.log(result)
})()
focus()
パラメーターとして渡されたセレクターに焦点を当てます
await page.focus('input#name')
goBack()
ページナビゲーション履歴に戻ります
await page.goBack()
goForward()
ページナビゲーション履歴を進めます
await page.goForward()
goto()
新しいページを開きます。
await page.goto('https://flaviocopes.com')
オプションを使用して、オブジェクトを2番目のパラメーターとして渡すことができます。ザ・waitUntil
オプション、合格した場合networkidle2
値は、ナビゲーションが完了するまで待機します。
await page.goto('https://flaviocopes.com', {waitUntil: 'networkidle2'})
hover()
パラメータとして渡されたセレクターにマウスオーバーします
await page.hover('input#name')
pdf()
ページからPDFを生成します。あなたはできる
await page.pdf({ path: 'file.pdf })
このメソッドに多くのオプションを渡して、生成されたPDFの詳細を設定できます。公式ドキュメントを参照してください。
reload()
ページをリロードする
await page.reload()
screenshot()
ページのPNGスクリーンショットを撮り、を使用して選択したファイル名に保存しますpath
。
await page.screenshot({path: 'screenshot.png'})
select()
パラメーターとして渡されたセレクターによって識別されるDOM要素を選択します
await page.select('input#name')
setContent()
既存のWebページを開くのではなく、ページのコンテンツを設定できます。
既存のHTMLを使用してPDFまたはスクリーンショットをプログラムで生成するのに便利です。
const html = '<h1>Hello!</h1>'
await page.setContent(html)
await page.pdf({path: 'hello.pdf'})
await page.screenshot({path: 'screenshot.png'})
setViewPort()
デフォルトでは、ビューポートは800x600pxです。別のビューポートが必要な場合、スクリーンショットを撮る場合は、setViewport
でオブジェクトを渡すwidth
そしてheight
プロパティ。
await page.setViewport({ width: 1280, height: 800 })
title()
ページタイトルを取得する
await page.title()
type()
フォーム要素を識別するセレクターに入力します
await page.type('input#name', 'Flavio')
ザ・delay
オプションを使用すると、実際のユーザーのようにタイピングをシミュレートして、各文字の間に遅延を追加できます。
await page.type('input#name', 'Flavio', {delay: 100})
url()
ページのURLを取得する
await page.url()
viewport()
ページビューポートを取得する
await page.viewport()
waitFor()
特定のことが起こるのを待ちます。次のショートカット機能があります。
waitForFunction
waitForNavigation
waitForRequest
waitForResponse
waitForSelector
waitForXPath
例:
await page.waitFor(waitForNameToBeFilled)
const waitForNameToBeFilled = () => page.$('input#name').value != ''
ページの名前空間
ページオブジェクトを使用すると、いくつかの異なるオブジェクトにアクセスできます。
それらのそれぞれは、たくさんの新しい機能のロックを解除します。
keyboard
そしてmouse
おそらく、物事を自動化しようとするときに最もよく使用するものです。
たとえば、これは要素(以前に選択されているはずです)への入力をトリガーする方法です。
await page.keyboard.type('hello!')
他のキーボードメソッドは
keyboard.down()
キーダウンイベントを送信するにはkeyboard.press()
キーダウンに続いてキーアップを送信します(通常のキータイプをシミュレートします)。主に修飾キー(shift、ctrl、cmd)に使用されますkeyboard.sendCharacter()
キープレスイベントを送信しますkeyboard.type()
キーダウン、キープレス、キーアップイベントを送信しますkeyboard.up()
キーアップイベントを送信するには
これらはすべて、USキーボードレイアウトファイルで定義されているキーボードキーコードを受け取ります。https://github.com/GoogleChrome/puppeteer/blob/master/lib/USKeyboardLayout.js。通常の文字と数字はそのまま入力されますが、特殊キーにはそれらを定義するための特別なコードがあります。
mouse
4つの方法を提供します:
mouse.click()
クリックをシミュレートするには:mousedown
そしてmouseup
イベントmouse.down()
をシミュレートするmousedown
イベントmouse.move()
別の座標に移動するにはmouse.up()
をシミュレートするmouseup
イベント