特定のimg要素の画像ファイルをダウンロード
<< エクセルVBAで画像データを連想配列に格納するサブルーチン :前の記事
前回は、Collectionオブジェクトを利用して特定のimg要素データを連想配列に格納するサブルーチンの作成について解説していきます。一度連想配列に格納すれば自由に利用することができますのでとても便利です。
今回は画像をダウンロードして保存する方法について説明していきます。こちらでは、指定した画像を指定した名前で保存することもできますが、保存した画像を無断で公開すると著作権法に引っかかりますのでご注意ください。
また、今回画像ファイルをダウンロードするためにWindwos APIの「URLDownloadToFile」と「DeleteUrlCacheEntry」を利用します。画像ファイル以外にもpdfファイルやエクセルファイルなどもダウンロードできますので、非常に便利な機能です。
目次
- DOM(Document Object Model)とは
- HTML(HyperText Markup Language)とは
- タグと要素(エレメント)の違い
- 利用するサブルーチン・プロパティ・VBA関数について
- 指定した画像要素の画像ファイルをダウンロードする処理の流れ
- 指定した画像要素の画像ファイルをダウンロードするサンプルコード
- まとめ
DOM(Document Object Model)とは
DOMとは「Document Object Model」の略称で、html・head・body・p・aなどのHTMLドキュメント要素にアクセスして取得や操作ができる仕組みのことです。
以下はHTMLドキュメントをツリー構造に表したものでDOMツリーと呼ばれます。階層状のツリー構造でHTMLドキュメントを表現します。
HTML(HyperText Markup Language)とは
HTMLとは「HyperText Markup Language」の略称で、Webページを作成するために開発された言語です。世の中に公開されているWebページのほとんどがHTMLで作成されています。こちらのサイトもHTMLで作成されています。
HTMLは基本的に以下のような構成でできており「<タグ名>★テキスト★</タグ名>」が1つの要素(エレメント)になります。この中の特定の要素に対してデータの取得や操作を行っていきます。
<html>
<head>
<title>VBAのIE制御</title>
</head>
<body>
<p>こちらはpタグのテキストです。</p>
<a href="★リンクURL★">リンクのアンカーテキストです。</a>
</body>
</html>
タグと要素(エレメント)の違い
HTML言語では、「タグ」と呼ばれる仕組みを利用して構築していきます。以下のイメージを確認すると分かりやすいと思いますが、タグとは「<」と「>」で構成されており、開始タグと終了タグまでの括りで1つの要素を形成します。
具体例で説明するとWebページのタイトルを表す「titleタグ」を利用して開始タグの「<title>」と終了タグの「</title>」で括り、タグの中の文字列が「要素内容」となります。こちらでは「VBAのIE制御入門」の文字列が要素内容となります。
そして、こちらの「開始タグ+要素内容+終了タグ」の全体を「要素」と呼びます。また、別名では「エレメント」と呼ばれますので、どちらも同じ意味であることを理解してください。
利用するサブルーチン・プロパティ・VBA関数について
今回利用するサブルーチン・プロパティ・VBA関数は以下になります。
- ieViewサブルーチン
- ieCheckサブルーチン
- Documentプロパティとは
- Imagesプロパティとは
- srcプロパティとは
- Pathプロパティとは
- Windows APIとは
- URLDownloadToFile関数とは
- DeleteUrlCacheEntry関数とは
- Mid関数とは
- InStrRev関数とは
- MsgBox関数とは
ieViewサブルーチンとは
ieViewサブルーチンは指定したURLをInternetExplorerで起動させ、Webページが完全に読み込まれるまで待機処理をするマクロです。
ieCheckサブルーチンとは
ieCheckサブルーチンは指定したInternetExplorerオブジェクトのWebページが完全に読み込まれるまで待機処理をするマクロです。
Documentプロパティとは
InternetExplorerオブジェクトのDocumentプロパティはHTMLドキュメントのオブジェクトを返すプロパティです。これによりHTMLドキュメントを操作することができます。
Imagesプロパティとは
DocumentオブジェクトのImagesプロパティはHTMLドキュメント内の画像要素オブジェクトのコレクションを返すメソッドです。
srcプロパティとは
Imagesオブジェクトのsrcプロパティは指定した画像要素の画像URLを取得するプロパティです。
objIE.document.images(添え字).src = "設定する画像URL"
Pathプロパティとは
Pathプロパティは指定されたオブジェクトの絶対パスを文字列で返すプロパティです。パス末尾の円記号(\)とオブジェクト名は含みません。
Windows APIとは
API(Application Programming Interface)は、アプリケーションからOSやプログラム言語を操作するためのライブラリです。このAPIを利用することでファイル制御やウインドウ制御などを行うことが出来ます。また、Windows APIはMicrosoft WindowsのAPIのことで、Windowsのバージョン毎に拡張されており16ビットは「Win16 API」32ビットは「Win32 API」と呼ばれます。
URLDownloadToFile関数とは
Windows APIのURLDownloadToFile関数は、インターネット上のファイル(画像ファイル、pdfファイルなど)をダウンロードするAPI関数です。
result = URLDownloadToFile(0, "画像ファイルURL", "画像保存先", 0, 0)
DeleteUrlCacheEntry関数とは
Windows APIのDeleteUrlCacheEntry関数は、指定したファイルのキャッシュを削除するAPI関数です。
DeleteUrlCacheEntry("キャッシュを削除するファイルのURL")
Mid関数とは
Mid関数は文字列から指定した文字数分の文字列を返します。
InStrRev関数とは
InStr関数はある文字列(string1)の中から指定した文字列(string2)を後ろから検索して最初に見つかった文字位置を返します。
MsgBox関数とは
MsgBox関数はダイアログボックスにメッセージとボタンを表示し、どのボタンが押されたかを示す整数型の数値を返します。
指定した画像要素の画像ファイルをダウンロードする処理の流れ
以下が今回の処理の流れになります。
- ①変数宣言
- ②ieViewサブルーチンを利用して指定したURLをIEで起動
- ③HTMLドキュメントのオブジェクトを取得
- ④HTMLドキュメント内のimg要素コレクションを取得
- ⑤コレクションの中から特定のimg要素オブジェクトを取得
- ⑥特定のimg要素オブジェクトの画像URLを取得
- ⑦特定の画像のキャッシュを削除
- ⑧特定の画像を指定したフォルダへダウンロード
指定した画像要素の画像ファイルをダウンロードするサンプルコード
こちらのVBAコードは、指定した画像要素の画像ファイルをダウンロードするマクロです。
Declare 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
Declare Function DeleteUrlCacheEntry Lib "wininet" _
Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As String) As Long
Sub sample()
Dim objIE As InternetExplorer
Dim imgURL As String, fileName As String, savePath As String
Dim cacheDel As Long, result As Long
'InternetExplorerで本サイトを起動
Call ieView(objIE, "http://www.vba-ie.net/library/index.html")
'画像URL取得
imgURL = objIE.document.images(0).src
'画像ファイル名
fileName = Mid(imgURL, InStrRev(imgURL, "/") + 1)
'画像保存先(+画像ファイル名)
savePath = ActiveWorkbook.Path & "\image\" & fileName
'キャッシュクリア
cacheDel = DeleteUrlCacheEntry(imgURL)
'画像ダウンロード
result = URLDownloadToFile(0, imgURL, savePath, 0, 0)
If result = 0 Then
MsgBox "ダウンロードできました"
Else
MsgBox "ダウンロードできませんでした"
End If
End Sub
ダウンロードする画像要素のHTMLコード
<img src="/img/vbaproject.png" alt="VBAの参照設定" width="400" height="275" />
実行結果
解説
Declare 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
まず、画像をダウンロードするWindows APIのURLDownloadToFile関数を使用できるようにAPIの宣言をします。宣言する場合は、宣言セクション内に記述します。宣言ステートメントは、最初のプロシージャ宣言の前に配置する必要がありますので、一番上に記述してください。
Declare Function DeleteUrlCacheEntry Lib "wininet" _
Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As String) As Long
次に画像のキャッシュを削除するWindows APIのDeleteUrlCacheEntry関数を使用できるようにこちらもAPIの宣言をします。画像をダウンロードする際にキャッシュが存在するとキャッシュから読み込むので、最新の画像をダウンロードするためにキャッシュを削除してからダウンロードを行います。
Sub sample()
Dim objIE As InternetExplorer
Dim imgURL As String, fileName As String, savePath As String
Dim cacheDel As Long, result As Long
こちらはSubステートメントに引数の設定がないsampleプロシージャになります。 まずは、変数宣言でメモリ領域を割り当てるDimステートメントを利用してオブジェクト変数objIEにInternetExplorer型を、変数imgURL・fileName・savePathに「文字列型(String)」を、変数cacheDel・resultに「長整数型(Long)」を変数宣言しています。
URLDownloadToFile関数を利用する際によくあるトラブルが変数宣言の間違いです。戻り値の変数に整数型(Integer)を宣言している場合は「オーバーフローしました。」とエラーになります。理由としては、ダウンロードが失敗した場合の戻り値は「-2146697210 」となるため、整数型では許容範囲を超えるためです。ですので、URLDownloadToFile関数とDeleteUrlCacheEntry関数の戻り値の変数には、長整数型を宣言しましょう。
'InternetExplorerで本サイトを起動
Call ieView(objIE, "http://www.vba-ie.net/library/index.html")
次に他のプロシージャを呼び出すCallステートメントを利用してieViewサブルーチンを呼び出しています。それぞれの第一引数にはオブジェクト変数の「objIE」を第二引数には表示させるURLの「http://www.vba-ie.net/library/index.html」を設定しています。これによりInternetExplorerで本サイトのページが表示されます。
'画像URL取得
imgURL = objIE.document.images(0).src
ここからはImagesプロパティを利用して指定したimg要素のURLを取得する部分になります。以下は理解しやすい様にVBAコードとキーワードの関連性を列挙したものです。あくまで関連性ですので必ずしも「=(イコール)」ではありません。
- 【objIE.document.images(0).src】
- objIE = InternetExplorerオブジェクト
- document = HTMLドキュメントのオブジェクト(Documentオブジェクト)
- images = HTMLドキュメント内のすべてのimg要素(Imagesプロパティ)
- images(0) = img要素コレクションの1番目のimg要素オブジェクト
- src = 1番目のimg要素オブジェクトの画像URL
まず、InternetExplorerオブジェクトのdocumentプロパティを利用してHTMLドキュメントのオブジェクト(Documentオブジェクト)を取得します。
次にすべてのimg要素を取得するDocumentオブジェクトのImagesプロパティを利用してすべてのimg要素を取得します。この要素コレクションから1番目のimg要素オブジェクトを取得しますが、1番目のimg要素オブジェクトとは「images(0)」の部分で、括弧内の数字(添え字)は「0」から数えるため、1番目のimg要素オブジェクトの添え字は「0」となります。
そして、srcプロパティを利用して、1番目のimg要素オブジェクトの画像URLを取得し変数imgURLに格納されます。
'画像ファイル名
fileName = Mid(imgURL, InStrRev(imgURL, "/") + 1)
こちらはMid関数とInStrRev関数を利用して画像URLから画像ファイル名の部分だけを抽出しています。
InStrRev関数は文字列の中から指定した文字列が後ろから何番目にあるかを返す文字列処理関数です。指定した文字列は「/(スラッシュ)」になりますので、一番後ろの「/(スラッシュ)」の位置を返します。
Mid関数は文字列から指定した文字数分の文字列を返す関数です。画像ファイル名は、一番後ろの「/(スラッシュ)」の位置から右側部分になりますので、抽出開始位置は「/(スラッシュ)」の位置から「+1」としています。これにより画像ファイル名のみを抽出することができます。
そして、抽出した画像ファイル名を変数fileNameに格納します。尚、今回格納される値は「vbaproject.png」になります。
savePath = ActiveWorkbook.Path & "\image\" & fileName
こちらは画像の保存先(+画像ファイル名)の設定ですが、今回は実行ファイルと同じディレクトリにあるimageフォルダに格納していきます。サンプルコードを実行する場合は、事前にimageフォルダを作成する必要がありますので作成しておいてください。
また、こちらはURLDownloadToFile関数で利用する引数になりますが、同じ名前のファイルが存在したい場合は、上書き保存されますので注意が必要です。
cacheDel = DeleteUrlCacheEntry(imgURL)
こちらはWindows APIのDeleteUrlCacheEntry関数を利用してキャッシュをクリアしています。引数には、変数imgURLを設定します。
こちらの処理はキャッシュがあった場合、古い画像を誤ってダウンロードしてしまう可能性もあるため、画像をダウンロードする前に一旦キャッシュを削除しています。
result = URLDownloadToFile(0, imgURL, savePath, 0, 0)
こちらはURLDownloadToFile関数を利用して画像をダウンロードする処理になります。引数はいくつかありますが、第二引数に「画像URL」を第三引数に「画像の保存先(+画像ファイル名)」を設定します。これで画像をダウンロードすることができます。
If result = 0 Then
MsgBox "ダウンロードできました"
Else
MsgBox "ダウンロードできませんでした"
End If
こちらは正常にダウンロードされたかのチェック部分になります。URLDownloadToFile関数はダウンロードに成功すると「0」を返すので、条件分岐ができるIf~Then~Elseステートメントを利用して変数resultが「0」の場合は「ダウンロードできました。」と表示されます。
まとめ
今回は画像をダウンロードして保存する方法について解説しました。今回は、IEを開いてから画像URLを取得しましたが、取得済みの画像URL一覧がある場合は、指定した回数同じ処理を繰り返すFor~Nextステートメントなどを利用して一括ダウンロードすることも可能です。次回は、ファイルをダウンロードして保存するサブルーチンの作成について解説していきます。
次の記事: エクセルVBAでファイルをダウンロードして保存するサブルーチン >>
近田 伸矢, 植木 悠二, 上田 寛
IEのデータ収集&自動操作のプログラミング本はこの1冊だけ!IEの起動やポップアップウィンドウ、表示を制御する基本的なコードはもちろん、テキストボックスやラジオボタン、表、ハイパーリンクなどのHTML部品を制御する方法など、自動操作に欠かせないノウハウを丁寧に解説。