Playwrightでスクレイピングをできるようにしよう。
参考にして頂いているか分からないので、
積極的に「いいね!」を押して頂けるならば記事メンテナンスを継続していこうと思います!
2024年4月2日追記
Playwrightでスクレイピングするための知識を大量に盛り込んだ記事を書きました!
基礎的な内容からCanvasKitのサイトのスクレイピングというマニアックなものまで扱っています。
スクレイピング関連の記事としてはかなり豊富な情報量となっています。
プロキシを刺しながら低コストでスクレイピングするためのアイデアも取り扱っています。
ぜひご覧ください!
▲2024年4月2日全文書き直しました!
記事を気に入って頂けましたらチップとして WebShare のアフィリエイトリンクを踏んで頂けるとすごく嬉しいです!(プロキシ使う予定がある場合。)
はじめに
スクレイピングをする際にPlaywrightが最善かどうかを判断しましょう。
従来のHTTPリクエストだけでHTML取得できる場合はPlaywright不要です。node-fetchとか色々な方法で試してみてください。
SPAなどのJS経由で動くものはPlaywrightを用いてスクレイピングを行いましょう。
また、SSRしてくれるようなNext.jsのページであればPlaywright無しでもスクレイピング可能です。この方法とか使えると思います。
Playwirghtでスクレイピングを行うための準備(Playwrightをインストールする)
スクレイピング用のプロジェクトフォルダで下記コマンドを実行します。
npm init playwright@latest
色々と聞かれるので、そのまま Enter で進んで頂いて大丈夫です。
上記のようなファイル群が生成されます。
削除してもいいもの
- testsディレクトリ
- tests-examplesディレクトリ
は不要なので削除して頂いて問題ありません。
ファイルの説明
playwright.config.ts
Playwright の test
関数で実行したときに適用される設定ファイルです。
スクレイピングにおいてはtest関数を使う必要はないので、ここでは触れません。
TypeScriptが動く環境を作ろう
npm install ts-node @types/node
ts-node は、TypeScriptのファイルをnode.jsで動かすためのものです。
ターミナルから npx ts-node hoge.ts
のように叩くことで利用できます。
Playwrightで Hello World! しよう
とりあえず開発環境が整ったのか確認したいと思います。
プロジェクトのルートディレクトリに index.ts というファイルを作り、
下記の記述をしておきましょう。
import { chromium } from "playwright";
(async () => {
const browser = await chromium.launch({
headless: false,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("https://yahoo.co.jp");
await page.close(); // ページを閉じる
await browser.close(); // ブラウザを閉じる
})();
そして、ターミナルから下記を叩きます。
npx ts-node index.ts
※ ts-node経由でindex.tsを実行するというコマンドです。
Chromeっぽいブラウザ(Chromium)で Yahoo!JAPAN のページが表示されれば準備OKです!
ターミナル上でタスクが実行されたままになっていると思うので、Ctrl + Cで止めておきましょう。
これでスクレイピングの環境が整いました。
Playwright の基礎知識
async関数で実行する必要がある
Playwrightはブラウザに指示を出して、その結果をブラウザから受け取ります。
そのため、基本的には await
で結果を待つことになるので、 async関数で実行する必要があります。
(async () => {
const browser = await chromium .... // 省略
})()
のように記述しましょう。
最低限必要な記述
import { chromium } from "playwright";
(async () => {
const browser = await chromium.launch({
headless: false,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("https://yahoo.co.jp");
await browser.close();
})();
使いたいブラウザを指定する
import { chromium } from "playwright";
Chromiumブラウザの他に、import { firefox }
や import { webkit }
も使えます。
ブラウザを立ち上げる
const browser = await chromium.launch({
headless: false,
});
最短の記述は const browser = await await chromium.launch()
です。
スクレイピングにおいてはブラウザ上の動きも見えていた方が便利なので、オプションで headless: false
によって、ヘッドレスブラウザを無効化しています。パフォーマンスが気になるようであれば、ヘッドレスブラウザを利用すると良いでしょう。
コンテキストを分ける
const context = await browser.newContext();
この記述は必須ではありませんが、一応書くようにしています。
コンテキストの動きとしては、新しいウィンドウのブラウザのようなイメージです。
ウィンドウを指定して作業を振り分けることができますね。
タブを開く
const page = await context.newPage();
指定したウィンドウのブラウザに新しいタブを開きます。
対象のURLをブラウザで開く
await page.goto("https://yahoo.co.jp");
指定したURL( この例では https://yahoo.co.jp )を指定したタブで開きます。
作業を完了する
await page.close(); // 指定したタブだけを閉じる
await context.close(); // 指定したウィンドウだけを閉じる
await browser.close(); // 全てのブラウザを閉じて完全に終了
作業の完了はいくつか方法があります。
完全に終わるのは最後の await browser.close()
です。
この辺りは動かしながら色々試してみてください。(ターミナルが終了を検出してくれるのはどれか、とか。)
スクレイピングに必要な知識
1. プロキシを使おう
自宅のネット環境でそのままスクレイピングをすると最悪ブロッキングされてしまいます。
普段利用するサービスでブロックされてしまうと、かなり怠い(VPNなどで回避する必要が出てしまう)ので、最初からプロキシを適用した状態でスクレイピングするようにしましょう。
プロキシを適用することで、自分のIPアドレスを露出することなくサイトにアクセスできるので、ブロッキングされたとしてもプロキシのIPアドレスが犠牲になるだけで済みます。プロキシを切り替えればIPアドレスも切り替わります。
2. プロキシを使うときは帯域幅を意識しよう
有料のプロキシサービスでは、帯域幅によって追加課金が必要なケースがほとんどです。
低コストでスクレイピングするためにも、帯域幅は意識しておきましょう。
スクレイピングに不要な特に重いデータ(画像、Webフォント)を無効化しておくことをオススメします。
const browser = await chromium.launch({
args: ["--blink-settings=imagesEnabled=false", "--disable-remote-fonts"],
})
このオプションを付けておけば画像とWebフォントを無効化できます。