puppeteer で Web ページを操作する

 今回は、簡単な web ページを puppeteer で操作して見ます。

操作対象の html と php

次のような html と php を web サイトに準備します。

puppeteer_test.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name='robots' content='noindex,nofollow'>
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
  <title>puppeteer のテストページ</title>
  <style>
    body { background-color: #efefef; }
  </style>
</head>
<body>
<h1>puppeteer の操作テスト</h1>
<h2>フォーム操作のテスト</h2>
複数の submit ボタンが有った場合でもクリック操作を区別できます。
<form method="get" neme="add" action="test.php">
  <input type="text" name="a" size="15" value="" placeholder="数字を入力" required>
  <input type="text" name="b" size="15" value="" placeholder="数字を入力" required>
  <button type="submit" name="action" value="add">足す</button>
  <button type="submit" name="action" value="sub">引く</button>
</form>
<h2>details タグのクリックテスト</h2>
<details>
  <summary>クリックで詳細表示</summary>
  この文章が表示されれば、details タグがクリックされたことになります。
</details>
</body>
</html>

test.php

<?php
$a = $_REQUEST['a'];
$b = $_REQUEST['b'];
if( $_REQUEST['action'] == "add" ) {
    $ans = $a + $b;
    $op = '+';
} else {
    $ans = $a - $b;
    $op = '-';
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name='robots' content='noindex,nofollow'>
  <title>\u8a08\u7b97\u7d50\u679c</title>
</head>
<body>
<?php echo $a . " " . $op . " " . $b; ?> は <?php echo $ans; ?> です。
</body>
</html>

 確認できるように、これらのファイルは、このサイトに 置きました。

puppeteer のコード

 テスト用の html は、足し算と引き算をするフォームと、details タグを使った詳細表示があります。これを puppetter で操作したいと思います。以下のコードになります。

#!/usr/bin/node

const puppeteer = require("puppeteer-core");

const URL = "https://sirius10.net/SampleCode/Puppeteer/puppeteer_test.html";

(async () => {
  console.log("*** Start ***");

  console.log("Chromium 起動");
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 50,
    executablePath: "/usr/bin/chromium-browser"
  });

  const page = await browser.newPage();

  await page.setViewport({
    width: 640,
    height: 400
  });

  console.log(URL + " へ移動");
  await page.goto(URL);
  await page.screenshot({ path: "1,開いた直後の画面.png" });

  // detail を開く
  await page.click('details');
  await page.screenshot({ path: "2,detail タグを開く.png" });

  // テキストボックスに入力
  await page.type('input[name="a"]', '12');
  await page.type('input[name="b"]', '13');
  await page.screenshot({ path: "3,text ボックスに入力.png" });

  // submit ボタンを押す
  await page.click('button[value="sub"]');
  await page.screenshot({ path: "4,引き算の結果.png" });

  console.log("Chromium 終了");
  await browser.close();

  console.log("*** End ***");
})();

コードの説明

 まず、html を開きます。

await page.goto(URL);

の部分です。

html を開いたところ

 次に details タグをクリックさせて詳細を表示します。puppeteer では次のコードの部分です。

await page.click('details');

 この html の中に、details タグは一つしか無いので、タグ名だけ指定してクリックすることができます。

details タグをクリックさせた

 次にフォームのテキストボックスに数字を入力します。input 要素ですが、複数あるので、name 属性を使って区別します。次の部分です。

await page.type('input[name="a"]', '12');
await page.type('input[name="b"]', '13');
テキストボックスに入力

 次にフォームのボタンをクリックするのですが、ボタンが2つあるので、区別する必要があります。html では次のようになっているので、value 属性で区別します。

  <button type="submit" name="action" value="add">足す</button>
  <button type="submit" name="action" value="sub">引く</button>

 puppeteer のコードでは次の部分です。引くのボタンをクリックします。

await page.click('button[value="sub"]');
引き算の結果

 id や class がなくても、他の属性を使って要素を特定できれば操作することができました。もっと複雑な場合の指定方法はまた別の記事にします。

pupeeteer,Raspberry Pi

Posted by sirius