GUI環境がないサーバーでweb scrapingをしようとして以下の問題にぶち当たった。
1. ページの表示内容をページ内で設定できる。が、GUIはない。
2. docker containerでplaywright/pythonを使っているのでブラウザの設定が毎回消える
2については、ホスト側のディレクトリをコンテナで/appにマウントして、そこにブラウザのローカルストレージを確保するようにした。
1については、WindowsのChromeでスクレイピングしたいページを開いて、開発者ツールでローカルストレージの内容をみつつ、ページの設定変更して設定項目と内容をチェックして、ヘッドレスブラウザ上でjavascriptで設定するようにした。
dockerでホスト側のディレクトリをマウントするには以下の引数で。
-v LOCALSTORAGE_DIR:/app
設定項目と値を記録しておき、以下のコードに設定項目と値を書き込んで実行したらよい。
import asyncio
from playwright.async_api import async_playwright
import json
SITE_URL = 'YOUR_SITE_URL'
BROWSER_DATA_DIR = '/app/browser_data'
async def run():
async with async_playwright() as p:
context = await p.chromium.launch_persistent_context(
headless=True, # ヘッドレスブラウザ指定
)
page = await context.new_page()
# URLを開きます
print(f"goto url=[{SITE_URL}]")
response = await page.goto(SITE_URL)
# HTTPステータスコードを確認
if response.status == 200:
print("Page loaded successfully!")
else:
print(f"Failed to load page, status code: {response.status}, status text: {response.status_text}")
await page.wait_for_load_state("load")
#3秒じゃダメだったんで30秒待つことにする
await page.wait_for_selector("table#planesTable", timeout=30000)
#ローカルストレージからデータを読み込む
localStorageData = await page.evaluate("() => { return JSON.stringify(localStorage);}")
print( json.dumps(json.loads(localStorageData), indent=4) )
# ローカルストレージにデータを書き込む
await page.evaluate("() => { localStorage.setItem('ITEM_1', 'true' ); }")
await page.evaluate("() => { localStorage.setItem('ITEM_2', '650' ); }")
print("ローカルストレージに、各種パラメータをセット")
#ローカルストレージからデータを読み込む
localStorageData = await page.evaluate("() => { return JSON.stringify(localStorage);}")
print( json.dumps(json.loads(localStorageData), indent=4) )
await context.close() # ブラウザを閉じる
# 非同期関数を実行
asyncio.run(run())