Skip to content
Code on the Road
Go back

【自動ログイン編】毎朝の2FAログインを無人で突破する — まず検証VMで実装

HTTPS化編で「常駐したのはトンネルだけ。アプリ本体の自動起動は別問題」と書いた。その本体側、いちばんの難所が 証券アプリへの自動ログインだ。

今回はこれを、まず検証用の Windows VM で実装・検証した。本番のさくらVPSへ載せて常駐させるところは、長くなるので**続編(VPS版)**に分ける。

検証環境について

今回(検証)本番(続編)
ハードMac (Apple Silicon) + Parallels の Windows VMさくらの VPS for Windows Server
目的仕組みを作って動かす常駐運用(毎朝自動・無人)

この「検証環境が Apple Silicon + Retina」という点が、後述するハマりの主な発生源になる(本番VPSでは起きないものもある)。が、踏んでおいたおかげで仕組みは頑健になった。

なぜ自動ログインが必要か

自作の自動売買システム Logical225 は、発注先に au カブコム証券の kabuステーションAPI を使う。これは Windows 上のローカルアプリが提供するAPIで、アプリにログインしている間だけ応答する。

やっかいなのは、このアプリが 毎朝6時すぎに強制ログアウトされること。再ログインには:

  1. 口座番号・パスワード
  2. 2要素認証(メールに届く6桁コード)

が必要。無人で売買を回すには、毎朝この再ログインを自動でこなす仕組みが要る。APIにログイン機能は無いので、GUIを自動操作するしかない

方針

毎朝6:30 起動
 └─ kabu_auto_login.py
      1. kabuステーション再起動
      2. 口座番号・パスワード入力 → ログイン(2FAメール送信)
      3. メールから6桁を取得 → 入力
      4. パスキー案内をスキップ → ログイン完了 → API再開

シンプルに見える。が、地雷原だった。特に学びの多かったものを抜粋する。

ハマり①: ウィンドウが「0.4倍」で描画される

テンプレート画像は等倍で撮ったのに、スクリプトから起動するとスクショ上で約0.4倍に縮小描画され、まったく一致しない。しかも実行ごとに倍率が揺れる。

犯人は検証環境(Apple Silicon Mac + Parallels の Retina ミラー)のDPI仮想化。DPIに無頓着なアプリを、DPI-awareな自プロセスから起動すると、スクショ空間と描画スケールがズレる。

対処は合わせ技:

# 起動直後、+2px → 元に戻す。これだけで等倍に再描画される
MoveWindow(hwnd, x, y, w + 2, h + 2, True); time.sleep(0.6)
MoveWindow(hwnd, x, y, w,     h,     True)

これは検証環境(Retina)固有の罠で、本番VPS(通常DPI)では起きない見込み。だが踏んだおかげで、倍率が揺れても耐えるマルチスケール対応まで入り、仕組みが頑健になった。

ハマり②: 状態で見た目が変わるUIは画像マッチに向かない

入力欄は 通常/フォーカス(オレンジ枠)/エラー(赤枠) で見た目が激変する。画像マッチが不安定になる。

対処は 見た目の変わらないボタン(「次へ」等)を基準にして、その上に固定オフセットで欄をクリックする方式。さらに、入力するとエラー表示の増減でレイアウトが上下してボタン座標がズレるので、入力後にボタンを再検出してからクリックする。

ハマり③: 「成功」の誤検知

極めつけ。ログには「ログイン成功」と出るのに、実画面はパスキー案内で止まっていた。画像マッチがログイン後画面のテンプレを別の場所に**誤マッチ(偽陽性)**していた。

対処は、成功判定を画像ではなくウィンドウタイトルで行うこと。ログイン中の窓は「ログイン」、成功後は「kabuステーション …」。確定的な信号なら誤検知しない。

def logged_in_by_title():
    return any("kabuステーション" in w.title for w in get_all_windows() if w.title)

他にも「直近ログイン時は2FAが省略されてパスキー画面に飛ぶ」など分岐が必要な罠があり、2FA画面/パスキー案内/ログイン完了のどれが来ても対応するよう作り込んだ。

検証環境では動いた

最終的に、検証VM上で ログイン → 2FA入力 → ウィンドウタイトルで成功確証 まで一気通貫で動くようになった。「アプリにログインするだけ」が、DPI・UI状態・認証フローの多層の罠でここまで膨らむとは思わなかった。

学び

次回予告: VPS版(本番常駐)

検証で仕組みは固まった。続編では、これを本番のさくらVPSに載せて毎朝・無人で回すところをやる:

「VPSを再起動しても、人が触らずに自動売買が再開する」状態が、いよいよ最後のピースだ。


シリーズ:

  1. VPS構築編
  2. アプリ運用編
  3. HTTPS化編
  4. 自動ログイン編・検証VM(この記事)


Next Post
【HTTPS化編】ngrok から Cloudflare Tunnel へ — 認証付きで trade.codeontheroad.jp を公開する