VBAテクニック集 VBA一覧 ブラウザ・外部連携 ブラウザ操作

【VBA】Chromeスクレイピング環境設定と実務サンプルコード

Excelでの集計やレポート作成が当たり前になった現場ほど、「データ取得だけが手作業」のボトルネックが残りがちです。Webシステムから数字を拾って、Excelに貼って、整形して…という流れを毎日・毎週繰り返していると、どこかでミスも起きます。そこで候補に上がるのが、VBAでChromeを操作して必要な情報を取得する“ブラウザ操作型スクレイピング”です。
ただし、Chrome操作は「コードを書けば終わり」ではありません。環境依存(バージョン差・社内PC制限・プロキシ・MFA)で詰まりやすく、運用設計が甘いとすぐ壊れます。この記事では、環境設定の考え方と、実務で壊れにくいサンプルコードの“型”をまとめます。

✅ まず押さえる:VBA×Chrome操作の現実と前提

Chrome操作をVBAでやると聞くと、「Webページを開いてクリックして、値を取る」だけに見えますが、実務ではそこが一番簡単です。詰まるのは、環境・権限・更新頻度・待機の設計です。特にChromeは自動更新されやすく、昨日動いたものが今日止まることがあります。さらに、ログインが絡むとMFAやCAPTCHAで“自動化できない仕様”にぶつかることもあります。だから最初に決めるべきは、テクニックではなく「どこまでを自動化対象にするか」です。対象を誤ると、作ったマクロが資産ではなく負債になります。まずは前提を揃えたうえで、現実的に回る設計に寄せていきましょう。

・VBAでのWeb取得は大きく2系統

  • ブラウザ操作型(Chromeを実際に動かす):ログイン後の画面、JavaScriptで生成される表などに強い
  • HTTP取得型(XMLHTTP等でHTMLを取る):静的ページやAPI寄りの取得に強い(軽い・速い・壊れにくい)

この記事は「Chromeを動かす」前提で進めつつ、最後に「ブラウザを動かさず済むならそちらが堅い」判断も添えます。


✅ 環境設定:動く状態を“固定”するのが最優先

環境設定で重要なのは「インストール手順」そのものではなく、動作条件を固定して再現できる状態にすることです。Chrome操作はWebDriver(ChromeDriver)に依存し、ブラウザ更新とズレると動かなくなります。つまり、運用で壊れる原因の多くはコードではなく“バージョン差”です。ここを曖昧にしたまま配布すると、他PCで再現しません。さらに社内PCだと、管理者権限・セキュリティソフト・プロキシで導入が止まることもあります。だから実務では「導入の簡単さ」より「運用で壊れない形」を優先します。以下は、その前提での設定観点です。

・最低限そろえるもの(考え方)

  1. Chrome(既に入っていることが多い)
  2. ChromeDriver(Chromeと整合する版)
  3. VBAからWebDriverを操作するためのライブラリ(Selenium系のVBAバインディング等)
  4. 配置ルール(どこにDriverを置くか、パスをどう扱うか)

・運用が壊れない配置の基本

  • PCごとのDownloadsに置かない(人によって場所がバラける)
  • ブックと同じフォルダ配下に固定する(配布・移行がラク)
  • Driverのパスをコードで組み立てる(環境差に強くなる)

✅ 実務で壊れにくい設計のコツ:待機と例外を先に設計する

Chrome操作の失敗原因は、クリックや取得の書き方よりも「待機が甘い」ことがほとんどです。画面の読み込みはネットワーク・PC性能・サイト側負荷で揺れます。固定のSleepを入れても、速い日はムダに遅く、遅い日は間に合わず失敗します。結果、再実行や手作業が混ざり、現場では使われなくなります。だから、待機は“時間”ではなく“状態”で判定する方が安定します。さらに、失敗したときに原因が追えないと運用不能になります。ここを先に固めるだけで、同じコードでも実務耐久が変わります。

・待機の基本方針

  • 原則:要素が出るまで待つ(クリック対象・取得対象)
  • タイムアウトを必ず設ける(永久待ちを防ぐ)
  • リトライは回数を固定(無限ループにしない)

・ログ(最低限)

  • いつ、どのURLで、どの要素待ちで落ちたか
  • 取れた件数/0件だったか
  • エラー内容(Err.Number / Err.Description)

✅ サンプル:Chromeを起動し、一覧テーブルから値を取得する

サンプルは「ログインなし」「テーブルから行を拾う」だけに絞ります。実務でログインが必要な場合でも、まずは“取得の型”を固めてからログインに拡張した方が安全です。いきなりログイン+遷移+取得を全部盛ると、どこが原因で落ちたか分からなくなります。実務では切り分け可能な粒度で作るほど、保守がラクです。ここでは、コードを一発芸にせず、再利用できる関数構成にします。ブック配布を想定し、Driverパスも相対で組み立てます。最後に、別案(待機のやり方)も併記します。

前提:VBAからWebDriverを操作できる参照設定(Selenium系ライブラリなど)が済んでいる想定です。
※ライブラリ名や参照名は環境で異なるため、ここでは「設計と型」を重視して書きます。

Option Explicit

'========================
' エントリーポイント
'========================
Public Sub Scrape_SampleTable()
    Dim driver As Object
    Dim targetUrl As String
    Dim rows As Collection
    Dim i As Long
    
    targetUrl = "https://example.com/list" ' サンプルURL(置き換え前提)
    
    On Error GoTo EH
    
    Set driver = CreateChromeDriver(GetDriverPath())
    driver.Get targetUrl
    
    ' 「テーブルが描画されるまで」待つ(状態待機)
    WaitForElement driver, "css=table.data tbody tr", 15
    
    Set rows = GetTableRows(driver, "css=table.data tbody tr")
    
    If rows.Count = 0 Then
        Debug.Print "取得0件:URL=" & targetUrl
        GoTo FIN
    End If
    
    For i = 1 To rows.Count
        Debug.Print rows(i) ' ここでは取得した文字列を出力(必要に応じてシートへ)
    Next
    
FIN:
    SafeQuitDriver driver
    Exit Sub
    
EH:
    Debug.Print "エラー:" & Err.Number & " / " & Err.Description & " / URL=" & targetUrl
    SafeQuitDriver driver
End Sub

・なぜこの構成か(設計意図)

  • Driver生成・待機・取得・終了を分離して、トラブル箇所を特定しやすくしています。
  • 実務で一番多い失敗(待機不足)を、WaitForElement に集約して“型”で解決します。
  • SafeQuitDriver を必ず通すことで、Chromeが裏で増殖する事故を防ぎます(運用で超重要)。

Chrome操作のスクレイピングでは、
ページの描画やJavaScriptの実行が終わる前に次の処理へ進んでしまい、
「昨日は動いたのに今日は落ちる」といった不安定さが起きがちです。

単なる Sleep ではなく、
処理が完了したタイミングを正しく待つ設計を理解しておくと、
スクレイピングの安定性は大きく変わります。

VBAでの待機・同期制御の考え方と実務での使い分けは、
以下の記事で詳しく整理しています。

【VBA】処理が終わってから次の処理を実行する方法|DoEvents・待機・同期制御の基本と実例


 

✅ 実装:Driverパスを相対で固定し、生成と終了を堅くする

ここを適当にすると「自分のPCでは動く」止まりになります。配布・引き継ぎ・PC交換が発生した時点で破綻します。実務での価値は、動くことより“同じ状態を再現できること”です。特にDriverの置き場所がバラバラだと、問い合わせ対応に時間が溶けます。だから、ブックと同階層に \tools\chromedriver\ のような固定ルールを作るのが安全です。さらに終了処理が漏れると、Chromeプロセスが残ってPCが重くなりクレームになります。運用を想定すると、ここが最重要の土台です。

Private Function GetDriverPath() As String
    ' このブックと同じフォルダ配下にDriverを置く想定
    ' 例:<ブックフォルダ>\tools\chromedriver\chromedriver.exe
    Dim baseDir As String
    baseDir = ThisWorkbook.Path
    
    GetDriverPath = baseDir & "\tools\chromedriver\chromedriver.exe"
End Function

Private Function CreateChromeDriver(ByVal driverPath As String) As Object
    ' 環境により生成方法は異なるため、ここは「生成を1か所に閉じる」のがポイント
    ' 例:Selenium系なら ChromeOptions を渡す、Service を作る等に発展させられる
    Dim drv As Object
    
    ' ここは利用ライブラリに合わせて置換してください
    ' Set drv = New ChromeDriver
    ' drv.SetCapability "webdriver.chrome.driver", driverPath
    
    Set drv = CreateObject("Selenium.ChromeDriver") ' 例(環境差あり)
    drv.AddArgument "--disable-gpu"
    drv.AddArgument "--no-sandbox"
    drv.Start "chrome", driverPath
    
    Set CreateChromeDriver = drv
End Function

Private Sub SafeQuitDriver(ByVal driver As Object)
    On Error Resume Next
    If Not driver Is Nothing Then
        driver.Quit
    End If
    On Error GoTo 0
End Sub

・別案とのメリット差

  • べた書きで driver.Start して driver.Quit を書くより、生成・終了を関数化した方が流用しやすいです。
  • 将来「ヘッドレス」「ダウンロード設定」「プロファイル指定」等を入れたくなったときも、変更箇所が CreateChromeDriver に閉じます。

✅ 待機の型:Sleepではなく“要素が出たか”で待つ

待機はスクレイピングの品質を決めます。固定Sleepは、環境が少し変わるだけで崩れます。実務ではサイトが重い日もあれば軽い日もありますし、社内ネットワークの遅延もあります。見た目が表示されていても、クリックできる状態になっていないこともあります。だから「要素が存在するまで待つ」「タイムアウトしたら失敗として扱う」という型が必要です。これを共通関数にしておくと、全ての処理が安定します。ここをケチると、結局“手動確認”が必要になり自動化の意味が消えます。

Private Sub WaitForElement(ByVal driver As Object, ByVal selector As String, ByVal timeoutSec As Long)
    Dim startTime As Single
    startTime = Timer
    
    Do
        If ExistsElement(driver, selector) Then Exit Sub
        
        DoEvents
        If Timer - startTime > timeoutSec Then
            Err.Raise vbObjectError + 1000, "WaitForElement", "タイムアウト:" & selector
        End If
    Loop
End Sub

Private Function ExistsElement(ByVal driver As Object, ByVal selector As String) As Boolean
    On Error GoTo EH
    
    ' 例:selector形式 "css=..." を想定(運用時に統一すると保守がラク)
    Dim byCss As String
    byCss = Replace(selector, "css=", vbNullString)
    
    Dim el As Object
    Set el = driver.FindElementByCss(byCss)
    
    ExistsElement = Not (el Is Nothing)
    Exit Function
    
EH:
    ExistsElement = False
End Function

✅ データ取得:行を“文字列で返す”ところから始める

いきなりセルに書くと、途中で落ちたときに「どこまで取れたか」が曖昧になります。まずは取得結果をコレクションで返し、呼び出し側で出力先(Debug/Sheet/CSV)を決める方が再利用しやすいです。実務では取得先が変わることがよくあります(別シート、別ブック、DB、CSVなど)。取得関数が“出力まで面倒を見る”と流用しづらくなります。また、HTML構造は変わるので、セレクタは1か所に寄せるのが安全です。最初は「1行=1レコード」のシンプルな形で十分です。安定してから列分解や型変換を足していきましょう。

Private Function GetTableRows(ByVal driver As Object, ByVal rowSelector As String) As Collection
    Dim results As New Collection
    
    Dim byCss As String
    byCss = Replace(rowSelector, "css=", vbNullString)
    
    Dim elements As Object
    Set elements = driver.FindElementsByCss(byCss)
    
    Dim i As Long
    For i = 1 To elements.Count
        results.Add Trim$(elements(i).Text)
    Next
    
    Set GetTableRows = results
End Function

✅ 実務で詰まりやすいポイントと回避策

Chrome操作は、動かすだけなら簡単でも、運用で詰まるポイントが決まっています。たとえばログインが絡むと、MFAやワンタイムコードで“人間の操作”が必須になることがあります。規約や社内監査の観点で、自動ログインが禁止されるケースもあります。また、サイト側のHTMLが少し変わるだけで、セレクタが壊れます。さらに、取得データが0件でも“正常”な日があるなら、0件をエラー扱いすると運用が回りません。こうした現場都合をコード設計に反映しないと、結局「手作業+マクロ」の中途半端になります。ここでは、先に潰しておくべき論点を整理します。

・Chrome更新で突然動かない

  • DriverとChromeの整合が崩れるのが典型原因です
  • 対策:Driverをブック配下に固定し、更新手順(誰が、いつ、どう差し替えるか)を決める

・待機が不安定で落ちる

  • 対策:Sleepではなく WaitForElement のような“状態待機”に統一
  • タイムアウトしたら、URL・セレクタ・時間をログに残す

・HTMLが変わって取れない

  • 対策:セレクタをコード内に散らさず、定数や関数に寄せる
  • 「取得できない=即バグ」ではなく、サイト変更の可能性を前提にする

✅ 応用:ログインや複雑ページは“自動化範囲”を区切る

ここから先は、テクニックより判断の話が重要です。ログインが必要な業務ほど自動化したくなりますが、MFAやCAPTCHAがあると「自動化できないこと」があります。無理に突破しようとすると、運用が危険になったり、規約違反・監査NGにつながります。実務では、ログインは人が行い、その後の繰り返し作業だけ自動化する、という分割が現実的なことも多いです。たとえば「ログイン後の一覧ページへ遷移したらボタン1つで取得」なら、効果は十分出ます。全部自動化できなくても、ボトルネックが減れば勝ちです。自動化は“完璧”より“安定して回る”を優先しましょう。

・現実的な落とし所の例

  • ログインは手動(最初の1回) → 取得・転記・整形は自動
  • 取得は自動 → 最終チェックと送信は人(責任分界)

 

✅ まとめ:Chrome操作スクレイピングは環境と待機が8割

  • Chrome操作は「コード」より「環境固定」と「待機設計」が重要
  • Driverの配置は相対パスで統一し、配布・更新の運用を作る
  • Sleep頼みをやめ、要素の出現を待つ“状態待機”にする
  • 取得ロジックは「取得」と「出力」を分離して再利用性を上げる
  • ログインや監査が絡む場合は、自動化範囲を区切って運用を成立させる

Chromeスクレイピングは、うまく設計すると「毎日の手作業」を確実に減らせます。逆に、環境や待機を軽視すると、壊れて直す時間の方が増えます。まずは小さく安定させ、型を固めてから拡張していくのが、実務で成功しやすい進め方です。

    -VBAテクニック集, VBA一覧, ブラウザ・外部連携, ブラウザ操作