Playwrightの使い方 - 基本操作

ブラウザ起動&Webページの表示

Playwrightでは、操作するブラウザを指定して起動することができます。
const browser = await pw.chromium.launch();の部分を起動するブラウザの定義に書き換えます。
ヘッドレスモードで起動したい場合はlaunch()の引数に定義を追加します。
ページを表示するにはpage.gotoメソッドを使用します。

						const pw = require('playwright');

						(async () => {
						  //Chromium
						  const browser = await pw.chromium.launch();
						  //Firefox 
						  //  const browser = await pw.firefox.launch();
						  //Safari
						  //  const browser = await pw.webkit.launch();
						  //Edge
						  //  const browser = await pw.chromium.launch({
						  //    channel: 'msedge',
						  //  });
						  //headless
						  //  const browser = await pw.chromium.launch({ headless: false, slowMo: 100 });
						  const context = await browser.newContext();
						  const page = await context.newPage();
						
						  await page.goto('https://web.biz-prog.net/');
						
						  await browser.close();
						})();
					
						private async void btnOpen_Click(object sender, EventArgs e)
						{
							var playwright = await Playwright.CreateAsync();
							//Chromium
							var browser = await playwright.Chromium.LaunchAsync();
							//Firefox
							//    var browser = await playwright.Firefox.LaunchAsync();
							//Safari
							//    var browser = await playwright.Webkit.LaunchAsync();
							//Edge
							//    var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() { Channel = "msedge" });
							//headless
							//    var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() { Headless = false });
							var page = await browser.NewPageAsync();

							await page.GotoAsync("https://web.biz-prog.net/");
							
							await browser.CloseAsync();
						}
					
						from playwright.sync_api import sync_playwright

						with sync_playwright() as p:
							# Chromium
							browser = p.chromium.launch()
							# Firefox
							browser = p.firefox.launch()
							# Safari
							browser = p.webkit.launch()
							# Edge
							browser = p.chromium.launch(channel="msedge")
							# Chrome
							browser = p.chromium.launch(channel="chrome")
							# headless
							#  browser = p.chromium.launch(headless=False)

							page = browser.new_page()
							
							page.goto("https://web.biz-prog.net/")
						
							browser.close()
					
C#(.NET6)であればusingを使えばclose()の実行は不要です。
private async void btnNew_Click(object sender, EventArgs e)
{
  using var playwright = await Playwright.CreateAsync();
  await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() { Headless = false });
  var page = await browser.NewPageAsync();
  await page.GotoAsync("https://web.biz-prog.net/test/testpage.html");
}

読み込み待ち

自動待機

Playwrightには、アクション実行時に要素が確認できるまで自動で待機する機能がありますので、
基本的には待機処理を記述しなくても操作が行えます。
locatorを使って要素にアクセスすれば待機が行われます。
page.goto("https://web.biz-prog.net/test/testpage.html")
await page.locator("#buttonid1").click() //要素が読み込めるようになってから実行される
参考:Auto-waiting

タイムアウト

時間内に読み込みが終わらなければタイムアウトエラー(TimeoutError)が発生します。(デフォルト30秒)
タイムアウト時間(ミリ秒)を指定することもできます。
参考:TimeoutError(Node.js)
参考:TimeoutError(C#)
参考:TimeoutError(Python)
							const pw = require('playwright');

							(async () => {
							  const browser = await pw.chromium.launch({ headless: false });
							  const context = await browser.newContext();
							  const page = await context.newPage();
							
							  await page.goto('https://web.biz-prog.net/testpage.html');
							
							  try {
								await page.locator("text=Foo").click({
								  timeout: 100,
								})
							  } catch (error) {
								if (error instanceof pw.errors.TimeoutError)
								  console.log("Timeout!")
							  }
							
							  await browser.close();
							})();
						
							private async void btnTimeout_Click(object sender, EventArgs e)
							{
								var playwright = await Playwright.CreateAsync();
								var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() { Headless = false });
								var page = await browser.NewPageAsync();
								await page.GotoAsync("https://web.biz-prog.net/test/testpage.html");
					
								try
								{
									await page.Locator("text=Foo").ClickAsync(new LocatorClickOptions() { Timeout = 100 });
								}
								catch (TimeoutException ex)
								{
									Console.WriteLine(ex.Message);
								}
					
								await browser.CloseAsync();
							}
						
							from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError

							with sync_playwright() as p:
								browser = p.chromium.launch(headless=False)
								page = browser.new_page()
								page.goto("https://web.biz-prog.net/test/testpage.html")
							
								try:
								  page.locator("text=Example").click(timeout=100)
								except PlaywrightTimeoutError:
								  print("Timeout!")
								
								browser.close()
						

明示的な待機

指定した時間を待機をする場合はpage.waitForTimeoutを使用します。
Submit直後やAjaxによる非同期描画の場合、page.waitForSelectorにより要素が描画されるのを待ちます。

その他の待機処理

上記以外にも色々な待機処理があります。
  • page.waitForEvent・・・指定したイベントが発生するまで待機
  • page.waitForFunction・・・記述したJavaScriptのコードがTrueになるまで待機
  • page.waitForLoadState・・・ブラウザの読み込み状態が指定した状態になるまで待機
  • page.waitForRequest・・・指定した内容(URLやMethod)のリクエストが発生するまで待機
  • page.waitForResponse・・・指定した内容のレスポンスを受信するまで待機
  • page.waitForSelector・・・指定した要素が確認できるまで待機
  • page.waitForTimeout・・・指定したミリ秒を待機
  • page.waitForURL・・・指定したURLに遷移するまで待機

戻る/進む/更新

						//ページを戻る
						await page.goBack()

						//ページを進む
						await page.goForward()

						//ページを更新
						await page.reload()
					
						//ページを戻る
						await page.GoBackAsync();

						//ページを進む
						await page.GoForwardAsync();

						//ページを更新
						await page.ReloadAsync();
					
						# ページを戻る
					    page.go_back()

						# ページを進む
						page.go_forward()

						# ページを更新
						page.reload()
					

タイトル/URL/ソースコードの取得

現在表示しているサイトのタイトルとURLを取得します。

						//titleの取得
						console.log(await page.title())
					  
						//URLの取得
						console.log(await page.url())
						
						//ソースコードの取得
						console.log(await page.content())
					
						//titleの取得
						Console.WriteLine(await page.TitleAsync());
						
						//URLの取得
						Console.WriteLine(page.Url);
						
						//ソースコードの取得
						Console.WriteLine(await page.ContentAsync());
					
						# titleの取得
						print(page.title())

						# URLの取得
						print(page.url)
						
						# ソースコードの取得
						print(page.content())		
					

alert/confirm/promptの操作

alert/confirm/promptのダイアログを操作する方法です。
ダイアログを表示する処理を行うより前に、ダイアログのボタンを押す処理をイベントハンドラに登録します。
参考:Dialogs(Node.js)
参考:Dialogs(.NET)
参考:Dialogs(Python)

						const pw = require('playwright');

						(async () => {
						  const browser = await pw.chromium.launch({ headless: false });
						  const context = await browser.newContext();
						  const page = await context.newPage();
						
						  await page.goto('https://web.biz-prog.net/test/testpage.html');
						
						  //alertは自動で閉じられる
						  await page.locator("#btnalert").click()
						
						  //confirmは事前にdialogのイベントハンドラにOKクリックを定義
						  page.once('dialog', dialog => dialog.accept());
						  await page.locator('#btnconfirm').click();
						
						  //prompt事前にdialogのイベントハンドラに入力&OKクリックを定義
						  page.once('dialog', dialog => dialog.accept('prompt test'));
						  await page.locator('#btnprompt').click();
						
						  await page.waitForTimeout(5000);
						  await browser.close();
						})();
					
						private async void btnDialog_Click(object sender, EventArgs e)
						{
							var playwright = await Playwright.CreateAsync();
							var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() { Headless = false });
							var page = await browser.NewPageAsync();
				
							await page.GotoAsync("https://web.biz-prog.net/test/testpage.html");
				
							//alertは自動で閉じられる
							await page.Locator("#btnalert").ClickAsync();
				
							//confirmは事前にdialogのイベントハンドラにOKクリックを定義
							EventHandler<IDialog> handler = null;
							handler = (_, dialog) => { dialog.AcceptAsync(); page.Dialog -= handler; };
							page.Dialog += handler;
							await page.Locator("#btnconfirm").ClickAsync();
				
							//prompt事前にdialogのイベントハンドラに入力&OKクリックを定義
							handler = (_, dialog) => { dialog.AcceptAsync("prompt test"); page.Dialog -= handler; };
							page.Dialog += handler;
							await page.Locator("#btnprompt").ClickAsync();
						}
					
						from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError

						with sync_playwright() as p:
							browser = p.chromium.launch(headless=False)
							page = browser.new_page()
							page.goto("https://web.biz-prog.net/test/testpage.html")
						
							# alertは自動で閉じられる
							page.locator("#btnalert").click()
						
							page.wait_for_timeout(3000)
						
							# confirmは事前にdialogのイベントハンドラにOKクリックを定義
							page.once("dialog", lambda dialog: dialog.accept())
							page.locator('#btnconfirm').click()
						
							page.wait_for_timeout(3000)
						
							# prompt事前にdialogのイベントハンドラに入力&OKクリックを定義
							page.once("dialog", lambda dialog: dialog.accept("prompt test"))
							page.locator('#btnprompt').click()
						
							page.wait_for_timeout(3000)
						
							browser.close()
					

参考


JavaScriptの実行

表示しているページに対してJavaScriptのコードを実行することができます。
evaluate()メソッドを使用します。
参考:Evaluating JavaScript(Node.js)
参考:Evaluating JavaScript(.NET)
参考:Evaluating JavaScript(Python)

						const pw = require('playwright');

						(async () => {
						  const browser = await pw.chromium.launch({ headless: false });
						  const context = await browser.newContext();
						  const page = await context.newPage();
						
						  await page.goto('https://web.biz-prog.net/test/testpage.html');
						
						  //ブラウザ側で実行するJavaScriptを記述する
						  await page.evaluate(() => { document.body.style.backgroundColor = 'Red'; });
						
						  //returnでブラウザ側から値を返却できる。値・JSON・配列を指定可能。
						  console.log(
							await page.evaluate(() => {
							  //ブラウザで実行する
							  const ret = {
								  title: document.title, //titleの取得
								  url: location.href  //URLの取得
							  };
							  return ret;
							})
						  );
						  
						  //ブラウザ側のJavaScriptに引数を渡す。値・JSON・配列を指定可能。
						  console.log(
							await page.evaluate((arg) => {
							  const ret = {
								  number: arg.param1,
								  string: arg.param2
							  };
							  return ret;
							}, 
							{ param1: 1234, param2: 'abcd' })
						  );
						
						  await browser.close();
						})();
					
						private async void btnCallJS_Click(object sender, EventArgs e)
						{
							var playwright = await Playwright.CreateAsync();
							var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions() { Headless = false });
							var page = await browser.NewPageAsync();
				
							await page.GotoAsync("https://web.biz-prog.net/test/testpage.html");
				
							//ブラウザ側で実行するJavaScriptを記述する
							await page.EvaluateAsync("document.body.style.backgroundColor = 'Red';");
							Console.WriteLine(await page.EvaluateAsync<string>("document.location.href"));
				
							//returnでブラウザ側から値を返却できる。値・JSON・配列を指定可能。
							dynamic result = new ExpandoObject();
							result.title = "";
							result.url = "";
							result = await page.EvaluateAsync<object>(@"() => {
									//ブラウザで実行する
									const ret = {
										title: document.title, //titleの取得
										url: location.href  //URLの取得
									};
									return ret;}"
								);
							Console.WriteLine(result.title + "," + result.url);
				
							//ブラウザ側のJavaScriptに引数を渡す。値・JSON・配列を指定可能。
							dynamic result2 = new ExpandoObject();
							result2.num = 0;
							result2.str = "";
							result2 = await page.EvaluateAsync<object>(@"arg => {
									const ret = {
										num: arg.param1,
										str: arg.param2
									};
									return ret;}
								",
								new { param1 = 1234, param2 = "abcd" });
							Console.WriteLine(result2.num + "," + result2.str);
						}
					
						from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError

						with sync_playwright() as p:
							browser = p.chromium.launch(headless=False)
							page = browser.new_page()
							page.goto("https://web.biz-prog.net/test/testpage.html")
						
							#ブラウザ側で実行するJavaScriptを記述する
							page.evaluate("() => { document.body.style.backgroundColor = 'Red'; }")
						
							#returnでブラウザ側から値を返却できる。値・JSON・配列を指定可能。
							print(
								page.evaluate("""() => {
									//ブラウザで実行する
									const ret = {
										title: document.title, //titleの取得
										url: location.href  //URLの取得
									};
									return ret;
								}""")
							)
						  
							#ブラウザ側のJavaScriptに引数を渡す。値・JSON・配列を指定可能。
							print(
								page.evaluate("""(arg) => {
									const ret = {
										number: arg.param1,
										string: arg.param2
									};
									return ret;
								}""",
								{ "param1": 1234, "param2": 'abcd' })
							)
						
							browser.close()
					

ブラウザ終了

browser.close()メソッドでウィンドウを閉じます。

					  	await browser.close();
					
						await browser.CloseAsync();
					
						browser.close()