定期的にブラウザー操作を自動化して処理するため、Azure Functions の Timer トリガーで Playwright を動かす方法を紹介します。
当初は Azure Functions の Flex Consumption もしくは Consumption ホスティングを利用して、Python で Playwright を動かす方法を検討しましたが、Playwright をインストールして動かすのがうまくいきませんでした。
今回の用途としては、1 日 1 回の実行で、動作時間も数分程度しかかからないため、待機時間にもコストがかかる Premium プランや App Service プランはオーバースペックでした。また、コンテナーイメージに Playwright をインストールすれば動作可能だろうという理由から、Azure Functions の Container Apps 環境でのホスティングを選択しました。
Azure リソースの作成
Azure Portal から Function app を作成します。
その際ホスティングオプションで、「Container Apps environment」を選択します。
配置するリソースグループとリソースの名称を決めて作成します。
以下の構成が生成されます
続いて、この後作成する Azure Functions の Python プロジェクトのコンテナーイメージをデプロイするために必要な Container Registry を作成しておきます。
Container Registry が作成されました。
Azure Functions プロジェクトの作成
Visual Studio Code で Azure Functions プロジェクトを作成します。
事前に Azure CLI と Azure Functions Core Tools をインストールしておきます。
今回は WSL2、Python 3.12.8 の環境で作業を行いました。
新規ディレクトリを作成し、移動します。
mkdir containerfunc01
cd containerfunc01
venv 環境を作成し Activate します。
python -m venv venv
source venv/bin/activate
そのディレクトリで Visual Studio Code を開きます。
code .
Visual Studio Code を開いたら、コマンドパレットで、Azure Functions: Create New Containerized Project...
を選択します。
指示に従って、言語 Python
、Programming Model を Model V2 (Recommended)
で作成します。
最初のトリガーを作成するかも聞かれるため、テストのため HTTP トリガーの Function を http_trigger
という名前で作成します。
以下のファイルが作成されます。
作成直後の状態でローカルで動作確認
作成直後の function_app.py
と、Dockerfile
、requirements.txt
は以下のようになっていました。
import azure.functions as func
import logging
app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)
@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
name = req.params.get('name')
if not name:
try:
req_body = req.get_json()
except ValueError:
pass
else:
name = req_body.get('name')
if name:
return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
else:
return func.HttpResponse(
"This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
status_code=200
)
# To enable ssh & remote debugging on app service change the base image to the one below
# FROM mcr.microsoft.com/azure-functions/python:4-python3.12-appservice
FROM mcr.microsoft.com/azure-functions/python:4-python3.12
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
COPY requirements.txt /
RUN pip install -r /requirements.txt
COPY . /home/site/wwwroot
# DO NOT include azure-functions-worker in this file
# The Python Worker is managed by Azure Functions platform
# Manually managing azure-functions-worker may cause unexpected issues
azure-functions
ローカルでの動作確認のため、function_app.py
の承認レベルを anonymous に変更します。
- app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)
+ app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
Docker イメージをビルドします。
docker build --tag containerfunc01 .
Docker イメージを実行します。
docker run -p 8080:80 -it containerfunc01
ブラウザーで、 http://localhost:8080/api/http_trigger?name=test
にアクセスし、Hello, test. This HTTP triggered function executed successfully.
と表示されれば成功です。
動作確認用の Playwright の処理を作成
ローカルで Playwright が動くことを確認するための処理を作成します。
venv 環境に Playwright をインストールします。
pip install playwright
python -m playwright install --with-deps
次のコマンドで現在の環境で requirements.txt
を更新します。
pip freeze > requirements.txt
Dockerfile に Playwright をインストールするための python -m playwright install --with-deps
を追加します。
# To enable ssh & remote debugging on app service change the base image to the one below
# FROM mcr.microsoft.com/azure-functions/python:4-python3.12-appservice
FROM mcr.microsoft.com/azure-functions/python:4-python3.12
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
COPY requirements.txt /
RUN pip install -r /requirements.txt && \
python -m playwright install --with-deps
COPY . /home/site/wwwroot
指定した URL のページの内容を取得しログに出力する関数を作成します。
from playwright.sync_api import sync_playwright
import logging
def exec_playwright(url: str):
try:
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto(url)
logging.info(f"URL: {page.url}")
logging.info(f"Title: {page.title()}")
logging.info(f"Content: {page.content()}")
browser.close()
except Exception as e:
logging.error(f"Error crawling {url}: {e}")
その関数を HTTP トリガーの Function から呼び出します。
import azure.functions as func
import logging
from exec_playwright import exec_playwright
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
exec_playwright("https://www.example.com")
return func.HttpResponse("This HTTP triggered function executed successfully.")
ローカルで Playwright の動作確認
ローカルで Playwright の動作確認を行います。
先ほどと同様に Docker イメージをビルドして実行します。
docker build --tag containerfunc01 .
Docker イメージを実行します。
docker run -p 8080:80 -it containerfunc01
ブラウザーで、 http://localhost:8080/api/http_trigger?name=test
にアクセスし、ログに取得したページの内容が表示されれば成功です。
Azure 環境にデプロイ
承認レベルを function に戻します。
- app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
+ app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)
コンテナーイメージをビルドし Azure Container Registry に登録します。
az acr build --registry containerfunc01cr --image containerfunc01:v0.0.1 .
次に、Function App で上記イメージを使用するように構成します。
ただし、その前に次の設定をしないと登録したイメージを指定できませんでした。
Container Registry の管理者権限が有効か確認します。
az acr show --name containerfunc01cr --query "adminUserEnabled"
無効(false)になっている場合は、次のコマンドで管理者権限を有効にします。
az acr update --name containerfunc01cr --query "adminUserEnabled" --admin-enabled true
Function App にて、登録したコンテナーイメージを指定します。
Function App の Settings > Configuration にて、登録したイメージを指定します。
- Image source: Azure Container Registry
- Registry: containerfunc01cr
- Image: containerfunc01
- Image tag: v0.0.1
Azure Portal 上から HTTP トリガーの Test/Run を実行するため、CORS を有効にし、Allowed Origin に https://portal.azure.com
を追加します。
Azure Portal 上から HTTP トリガーの Test/Run を利用しない場合は、CORS の設定は不要です。
Function App の Overview にて、作成した Function が表示されていることを確認します。
http_trigger にアクセスし、 Test/Run から実行します。
結果に This HTTP triggered function executed successfully.
が表示され、ログに取得したページの内容が表示されれば成功です。
これで、コンテナ環境の Azure Functions 上で Playwright が動くことが確認できました。
あとは、必要な処理を追加したり、Timer トリガーで定期実行するように設定することで、自動化処理をスケジュール化できます。