LoginSignup
5
4

Lambda(node18)でplaywrightを動作させるコードをtypescriptで書いたメモ

Last updated at Posted at 2023-11-08

概要

aws lambdaでPlaywrightを動作させた。
ローカルで動作させる場合と異なり、Lambdaにはブラウザがない。
ヘッドレスブラウザを含んだLayerを利用することにした。

ソースコード

ソース

cdk/lib/playwright-stack.ts
import { Aspects, Duration, Stack, StackProps, Tag } from 'aws-cdk-lib';
import { LayerVersion, Runtime } from 'aws-cdk-lib/aws-lambda';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Construct } from 'constructs';

export class PlayWrightStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);
    new NodejsFunction(this, 'playWrightLambda', {
      runtime: Runtime.NODEJS_18_X,
      memorySize: 1024,
      timeout: Duration.seconds(10),
      entry: `../src/handler/invoke/playwright.ts`,
      bundling: { externalModules: ['@sparticuz/chromium'] },
      layers: [
        LayerVersion.fromLayerVersionArn(
          this,
          'chromium-lambda-layer',
          'arn:aws:lambda:ap-northeast-1:764866452798:layer:chrome-aws-lambda:39',
        ),
      ],
    });

    Aspects.of(this).add(new Tag('Stack', 'PlayWrightStack'));
  }
}
packege.json
{
  "name": "aws-cdk-v2",
  "dependencies": {
    "playwright-core": "^1.39.0"
  },
  "devDependencies": {
    "@sparticuz/chromium": "^118.0.0",
    "@types/aws-lambda": "^8.10.126",
    "typescript": "^5.2.2"
  }
}

src/handler/invoke/playwright.ts
import { Handler } from 'aws-lambda';
import { chromium } from 'playwright-core';

const sparticuzChromium = require('@sparticuz/chromium');

sparticuzChromium.setHeadlessMode = true;
sparticuzChromium.setGraphicsMode = false;

export const handler: Handler = async (event, context) => {
  let browser;
  try {
    const executablePath = await sparticuzChromium.executablePath();
    browser = await chromium.launch({
      args: sparticuzChromium.args,
      executablePath,
      headless: sparticuzChromium.headless,
    });

    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://talto.cc/');
    const locators = await page.locator('section ul li').all();
    const promises = locators.map(async (locator) => {
      const elment = await locator.elementHandle();
      const imgElement = await elment?.$('img');
      if (!imgElement) return;
      const alt = await imgElement.getAttribute('alt');
      if (!alt) return;
      console.log(alt);
    });
    await Promise.all(promises);
  } catch (e) {
    console.error(e);
    throw e;
  } finally {
    if (browser) await browser.close();
  }
};

デプロイ

レイヤーが設定されていることを確認
image.png

テスト実行

コンソールからテスト実行を行った。
今回のplaywrightは https://talto.cc/ のトップの新着シナリオの名前を取得するコードとなっている。
Lambdaのログに下記が出力されており、成功したことが確認できた。

START RequestId: 063e5b24-735e-45d6-a7aa-5ad74648879f Version: $LATEST
2023-11-08T13:45:58.005Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	第二次遍歴遠征異聞:開かれたる館
2023-11-08T13:45:58.020Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	邂逅する真像
2023-11-08T13:45:58.021Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	怪談白物語シナリオ 『カッパの手』
2023-11-08T13:45:58.022Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	怪談白物語シナリオ 『アパートの壁』
2023-11-08T13:45:58.022Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	スレイヤー・オブ・ドラゴンスレイヤー 或いは少女リサと雨降りな日々
2023-11-08T13:45:58.024Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	『キャスリング ☆ すぴりっと』
2023-11-08T13:45:58.024Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	マシュマロプラネット
2023-11-08T13:45:58.024Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	白雷  -ハクライ-
2023-11-08T13:45:58.025Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	新約・きさらぎ駅
2023-11-08T13:45:58.025Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	おっと!!そっちは二次創作のKPCだ
2023-11-08T13:45:58.042Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	客演裁判 スクランブる逆転
2023-11-08T13:45:58.043Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	Twins
2023-11-08T13:45:58.043Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	banner
2023-11-08T13:45:58.044Z	063e5b24-735e-45d6-a7aa-5ad74648879f	INFO	banner
END RequestId: 063e5b24-735e-45d6-a7aa-5ad74648879f
REPORT RequestId: 063e5b24-735e-45d6-a7aa-5ad74648879f	Duration: 9592.31 ms	Billed Duration: 9593 ms	Memory Size: 1024 MB	Max Memory Used: 769 MB	Init Duration: 450.23 ms	

設定ミスで起きたエラーのメモ

chromiumがない

ERROR	[Error: Executable doesn't exist at /home/sbx_user1051/.cache/ms-playwright/chromium-1084/chrome-linux/chrome
╔═════════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just installed or updated. ║
║ Please run the following command to download new browsers:              ║
║                                                                         ║
║     npx playwright install                                              ║
║                                                                         ║
║ <3 Playwright Team                                                      ║
╚═════════════════════════════════════════════════════════════════════════╝]
ERROR	[Error: ENOENT: no such file or directory, open '/var/task/bin/chromium.br'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/var/task/bin/chromium.br'
}
ERROR	[Error: spawn ETXTBSY
=========================== logs ===========================
<launching> /tmp/chromium --disable-field-trial-config --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --no-sandbox --autoplay-policy=user-gesture-required --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-update --disable-default-apps --disable-dev-shm-usage --disable-domain-reliability --disable-extensions --disable-features=AudioServiceOutOfProcess --disable-hang-monitor --disable-ipc-flooding-protection --disable-notifications --disable-offer-store-unmasked-wallet-cards --disable-popup-blocking --disable-print-preview --disable-prompt-on-repost --disable-renderer-backgrounding --disable-setuid-sandbox --disable-speech-api --disable-sync --disk-cache-size=33554432 --hide-scrollbars --ignore-gpu-blacklist --metrics-recording-only --mute-audio --no-default-browser-check --no-first-run --no-pings --no-sandbox --no-zygote --password-store=basic --use-gl=swiftshader --use-mock-keychain --single-process --user-data-dir=/tmp/playwright_chromiumdev_profile-YJz7Hd --remote-debugging-pipe --no-startup-window
============================================================]
============================================================]
ERROR	Error: The input directory "/var/bin" does not exist.
    at Chromium.executablePath (/var/task/index.js:68049:17)
    at Runtime.handler (/var/task/index.js:68135:52)
    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)

ヘッドレスブラウザの設定不足

 ERROR [ValidationError: headless: expected boolean, got string]

参考

@sparticuz/chromium
chrome-aws-lambda-layer
playwright
これだけはおさえておきたいPlaywrightコマンド集
2020年: PuppeteerとPlaywrightの激動の1年。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4