ガイド

Playwrightでログインできない原因:本人の窓と機械の窓でブラウザエンジンが違っていた件

2026-11-04

この記事で切り分けられること

Playwright で持続プロファイル(launch_persistent_context)を使っていて、以下が同時に起きている場合の切り分けです。

症状

別々の不具合だと思っていたが、実際は1つの原因から出ていた3つの症状だった。

原因

本人がログインする窓と、機械が読む窓が、同じプロファイルフォルダを指しながら別のブラウザエンジンで動いていた。

Chromium と Edge は Cookie の暗号鍵(Local State の os_crypt.encrypted_key)が別物。同じフォルダを指していても、片方が入れたログインはもう片方から復号できない。

実測では、Chromium で開くと2サイトが未ログイン、Edge で開くと別の2サイトが未ログイン。どちらのエンジンで開いても全サイト分は揃わない状態だった。

TargetClosedError の方は別の原因。open_login_browser.py は窓が閉じるまで待つ仕様なので、素の Chromium の窓を開いたままにしていると、そのプロセスがプロファイルを掴み続ける。Edge 側は同じフォルダを開けずに即終了していた。実測で掴んでいたのは特定の1プロセス(開始時刻が記録に残っていた)で、Last Browser にも Playwright 同梱 Chromium の実行ファイルパスが残っていた。

切り分け方(遠回りした所)

最初は「Edge のバージョンが古くてプロファイルを拒否している」と考え、プロファイル内の Last Version と Edge の実バージョンを比較した。結果は Edge の方が新しく、この筋は最初から外れていた。

決め手になったのは、プロファイル内の Cookie ファイルをコピーしようとした時の結果だった。

cp "<あなたのプロファイルパス>/Default/Network/Cookies" /tmp/check.db
# => cp: cannot open ... Device or resource busy

Device or resource busy は、誰かがそのファイルを掴んでいる合図。ブラウザが開けない・ログインが消えたように見える時は、バージョンを疑う前に、まず掴んでいるプロセスを探すべきだった。

Get-CimInstance Win32_Process -Filter "Name='msedge.exe' OR Name='chrome.exe'" |
  Where-Object { $_.CommandLine -notmatch '--type=' } |
  Select-Object ProcessId, CreationDate, CommandLine

--type= を含む子プロセスを除くと、プロファイルを実際に掴んでいる親プロセスだけが残る。

直し方

scripts/lib/apply_browser.py を新規に作り、持続プロファイルを開く処理を1箇所にまとめた。

from scripts.lib.apply_browser import launch, assert_free

assert_free(profile_dir)  # 掴まれていればここで日本語1行を出して止まる
context = launch(profile_dir)

あわせて次の修正を行った。

再発防止

それでも駄目なときに次に見る場所

症状先に疑ったこと実際に効いた確認
機械だけ未ログインEdge のバージョンが古いLast Version と実バージョンの比較(今回は外れ)より、本人の窓と機械の窓で channel が同じか
TargetClosedError で落ちるプロファイル破損cp で Cookie ファイルを開き、Device or resource busy が出るか
誰が掴んでいるか不明再起動して様子を見るGet-CimInstance Win32_Process で --type= を除いた親プロセスを確認

プロファイルが壊れたように見える時、まずエンジンの一致(Chromium か Edge か)とプロセスの掴み合いの2点を確認すると、原因の切り分けが早い。

同じような作業を自動にできるかどうか、無料でお返しします。いまのファイルと手順を見せてください。

お問い合わせ →