ExcelVBAで画像ダウンロードを自動化する手順
仕事で色々なウェブサイトにアップされている複数の画像をダウンロードする必要があり、その手順を自動化するのにどうすればよいかネットで調べていたところ、WindowsAPIのURLDownloadToFileを使う方法を見つけました。
今回はURLDownloadToFileを用いてウエブページの画像やファイルをダウンロードする方法をご紹介します。
WindowsAPIのURLDownloadToFile関数について
WindowsAPIはWindowsで行う処理をプログラム上で実行するために用意されている機能です。
私もほんの数種類しか把握できていないのですが、WindowsAPIには色々な分野にわたり便利な機能がたくさんあります。
導入にはコツが必要で、慣れないと使うハードルが高いのですが、このWindowsAPIはExcelをはじめとするVBAでも使用することができ、使いこなすことでVBA単独では難しい様々な処理をすごく簡単に実行できるようになります。
今回ご紹介するのはWindowsAPIのURLDownloadToFileという関数で、これはウェブサイトからファイル・画像などをダウンロードするための専用の関数です。
(他にもWindowsAPIを用いて表示されているウインドウを取得したり、ボタンをクリックしたり、テキストボックスに文字を入力したりする方法、待ち時間を設定する方法などをご紹介していますので興味あればこちらのカテゴリページから見てみてください。)
スポンサーリンク
VBAでURLDownloadToFile関数を使う事前準備について
VBAでURLDownloadToFile関数を使うためには、実行させるコードにURLDownloadToFile(〇〇)という内容を記載するだけでなく、URLDownloadToFileとはAPIのこの関数ですよというのを事前に登録しておく必要があります。
具体的には宣言セクションに下記の内容を記載します。
(ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
一応ざっくりと説明すると「urlmon」というライブラリファイルに用意されている「URLDownloadToFileA」という関数を「URLDownloadToFile」という名前で使用しますという意味らしいですが、おまじないのようなものなので詳しく意味を把握していなくても問題ありません。
画像のダウンロードに関しては現実的な方法として、対象のページを開くことが多いと思いますので、宣言セクションに下記も併せて記述してSleep関数も使用できるようにしておく方が良いと思います。
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib “kernel32” (ByVal ms As Long)
#End If
End Sub
その他に準備としてIEを用いてウェブページを開いて操作するので、「ツール」→「参照設定」から下記2つのチェックを付けて利用できるようにしましょう。
URLDownloadToFileの使い方について
上記のURLDownloadToFileの事前準備をしておけばVBAで使用する自体は簡単です。
ダウンロードを実行したいプロシージャ内に「URLDownloadToFile(0, ウェブ上のURL, 保存先フォルダ, 0, 0)」と書けばOKです。
引数は対象ファイルのウェブ上のURL、ダウンロード先のフォルダ名になります。
あとダウンロードがうまくいった場合、URLDownloadToFile関数は「0」という数字を返すので戻り値を取得できるように下記のように記述するのが一般的だと思います。
VBA界の権威であるOfficeTANAKAの田中先生もご自身のサイトで記載されていましたが、URLDownloadToFile関数自体の使い方は簡単ですが、ウェブの対象ファイルのURLをどうやって取得してくるかの方がはるかに難しいと思います。
URLDownloadToFileの実行サンプル
URLDownloadToFile関数の使い方を各だけではこの関数の使い方や便利さを実感しにくいと思ったので、下記のようにサンプルを考えてみました。
これはワークシートのA1列に表示されているURLのページに埋め込まれている画像ファイルをすべてデスクトップの「画像」というフォルダに格納するVBAコードになります。
この方法だと多少強引で無駄も多いのですが、対象サイトの構造をあまり詳しく調べなくても全部の画像データを取得できるので汎用性は高いと思います。
また特定のファイルだけダウンロードしたい場合にもファイル名の規則などを調べるのにも役立ちます。
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib “kernel32” (ByVal ms As Long)
#End If
Private Declare PtrSafe Function URLDownloadToFile Lib “urlmon” Alias “URLDownloadToFileA” _
(ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Sub IE表示()
Dim IE As Object
Set IE = CreateObject(“InternetExplorer.application”)
IE.Visible = True
Sleep 1000
IE.navigate (Cells(1, 1).Text)
’ページが表示されるまで待つ
Dim x
x = 0
Do While (IE.Busy Or IE.readyState < READYSTATE_COMPLETE) And x <= 10
DoEvents
Sleep 1000
Loop
Sleep 1000
Dim WSH As Object
Set WSH = CreateObject(“Wscript.Shell”)
Dim FSO As Object
Set FSO = CreateObject(“Scripting.FileSystemObject”)
Dim DesktopPath As String
DesktopPath = WSH.SpecialFolders(“Desktop”)
’ダウンロード先のフォルダがあるか存在確認
If FSO.FolderExists(DesktopPath & “画像”) = False Then
’存在しなければ作成する
FSO.CreateFolder DesktopPath & “画像”
End If
Dim imgSrc As String
Dim imgName As String
Dim strPath As String
Dim lngRes As Long
Dim txtInput
Set txtInput = IE.document.getElementsByTagName(“img”)
For x = 0 To txtInput.Length - 1
imgSrc = txtInput(x).src
imgName = Mid(imgSrc, InStrRev(imgSrc, “/”) + 1)
’ファイル名に使えない文字列を除外する
imgName = Replace(Replace(imgName, “:”, “”), “?”, “”)
’ダウンロード先のパスを指定する
strPath = DesktopPath & “画像” & x & “_” & imgName
’ウェブ上に格納されているファイル名が拡張子の後に文字列が追加されている場合の処理
If Left(Right(strPath, 4), 1) <> “.” Then
’画像ファイル名に.jpgが含まれているなら
If InStr(strPath, “.jpg”) <> 0 Then
strPath = Left(strPath, InStr(strPath, “.jpg”) + 3)
’gifに対しての処理
ElseIf InStr(strPath, “.gif”) <> 0 Then
strPath = Left(strPath, InStr(strPath, “.gif”) + 3)
’pngに対しての処理
ElseIf InStr(strPath, “.png”) <> 0 Then
strPath = Left(strPath, InStr(strPath, “.png”) + 3)
End If
End If
’ファイルのダウンロード実行
lngRes = URLDownloadToFile(0, imgSrc, strPath, 0, 0)
’ワークシートに情報残す
Cells(x + 1, 2) = x
Cells(x + 1, 3) = imgSrc
Cells(x + 1, 4) = imgName
Cells(x + 1, 5) = lngRes
’ダウンロードがうまくいかなかったら色付けする
If lngRes <> 0 Then
Range(Cells(x + 1, 2), Cells(x + 1, 5)).Interior.Color = RGB(255, 200, 200)
End If
imgSrc = “”
imgName = “”
Next x
IE.Quit
Set FSO = Nothing
Set WSH = Nothing
Set txtInput = Nothing
Set IE = Nothing
End Sub
私は楽天のサイトで商品検索結果が表示されているページで画像を取得するイメージでコードを作りました。
楽天のサイトの場合、SVG拡張子のロゴなどが大量に含まれていたり、対象ファイル名にWindows上で使用できない文字が含まれているためにダウンロードが進まなかったりしました。
そのあたりは少しページごとに調整が必要になります。
あとはダウンロードをする際にJPGのみにするとかPNGのみにするとか特定の文字を含むものにするかなど検討するとムダなダウンロードをせずに済みますので、工夫次第でより便利なコードにできると思います。
コメント