特定のimg要素の画像ファイルをダウンロード

<< エクセルVBAで画像データを連想配列に格納するサブルーチン :前の記事

前回は、Collectionオブジェクトを利用して特定のimg要素データを連想配列に格納するサブルーチンの作成について解説していきます。一度連想配列に格納すれば自由に利用することができますのでとても便利です。

今回は画像をダウンロードして保存する方法について説明していきます。こちらでは、指定した画像を指定した名前で保存することもできますが、保存した画像を無断で公開すると著作権法に引っかかりますのでご注意ください。

また、今回画像ファイルをダウンロードするためにWindwos APIの「URLDownloadToFile」と「DeleteUrlCacheEntry」を利用します。画像ファイル以外にもpdfファイルやエクセルファイルなどもダウンロードできますので、非常に便利な機能です。

目次

DOM(Document Object Model)とは

DOMとは「Document Object Model」の略称で、html・head・body・p・aなどのHTMLドキュメント要素にアクセスして取得や操作ができる仕組みのことです。

以下はHTMLドキュメントをツリー構造に表したものでDOMツリーと呼ばれます。階層状のツリー構造でHTMLドキュメントを表現します。

DOMツリー

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ページが完全に読み込まれるまで待機処理をするマクロです。

ieView("IEオブジェクト","表示させたいURLの文字列","IE表示・非表示の値[省略可]","Y位置の値[省略可]","X位置の値[省略可]","幅の値[省略可]","高さの値[省略可]")

ieCheckサブルーチンとは

ieCheckサブルーチン指定したInternetExplorerオブジェクトのWebページが完全に読み込まれるまで待機処理をするマクロです。

ieCheck("IEオブジェクト")

Documentプロパティとは

InternetExplorerオブジェクトのDocumentプロパティHTMLドキュメントのオブジェクトを返すプロパティです。これによりHTMLドキュメントを操作することができます。

objIE.document.プロパティ/メソッド

Imagesプロパティとは

DocumentオブジェクトのImagesプロパティHTMLドキュメント内の画像要素オブジェクトのコレクションを返すメソッドです。

objIE.document.images(添え字).プロパティ/メソッド

srcプロパティとは

Imagesオブジェクトのsrcプロパティ指定した画像要素の画像URLを取得するプロパティです。

変数 = objIE.document.images(添え字).src
objIE.document.images(添え字).src = "設定する画像URL"

Pathプロパティとは

Pathプロパティ指定されたオブジェクトの絶対パスを文字列で返すプロパティです。パス末尾の円記号(\)とオブジェクト名は含みません。

オブジェクト(アプリケーション).Path

Windows APIとは

API(Application Programming Interface)は、アプリケーションからOSやプログラム言語を操作するためのライブラリです。このAPIを利用することでファイル制御やウインドウ制御などを行うことが出来ます。また、Windows APIMicrosoft 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関数文字列から指定した文字数分の文字列を返します

変数 = Mid("抽出する文字列","抽出する先頭位置")

InStrRev関数とは

InStr関数ある文字列(string1)の中から指定した文字列(string2)を後ろから検索して最初に見つかった文字位置を返します

変数 = InStrRev(string1, string2)

MsgBox関数とは

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" />

実行結果

URLDownloadToFileのダウンロード画像

解説

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ステートメントを利用してオブジェクト変数objIEInternetExplorer型を、変数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でファイルをダウンロードして保存するサブルーチン >>

Excel VBAでIEを思いのままに操作できるプログラミング術 Excel 2013/2010/2007/2003対応

近田 伸矢, 植木 悠二, 上田 寛

IEのデータ収集&自動操作のプログラミング本はこの1冊だけ!IEの起動やポップアップウィンドウ、表示を制御する基本的なコードはもちろん、テキストボックスやラジオボタン、表、ハイパーリンクなどのHTML部品を制御する方法など、自動操作に欠かせないノウハウを丁寧に解説。

  • このエントリーをはてなブックマークに追加
VBAのIE制御についてのQ&A掲示板

↑エクセルVBAのIE(InternetExplorer)操作で分からない事があればこちらの掲示板よりご質問ください^^

ExcelのVBA初心者入門

↑こちらはExcelのVBAをマスターできるよう初心者向けのエクセルVBA入門コンテンツになります^^

VBAのIE制御入門RSS

RSSフィードを登録すると最新記事を受け取ることができます。

VBAIE操作のスカイプレッスン

VBAでIE(InternetExplorer)制御の準備

【ダウンロード】IE操作に便利なツール

こちらでは、これまでに紹介したIE(InternetExplorer)操作で便利な機能をツール化しています。無償でダウンロードできますので、目的に合わせたご利用ください。

IEオブジェクトのメソッド・プロパティ

こちらでは、IE(InternetExplorer)オブジェクトのメソッド・プロパティをまとめています。

IE操作に利用されているVBA関数

こちらでは、エクセルVBAのIE(InternetExplorer)操作で利用されたVBA関数をまとめています。

IE操作に利用されているステートメント

こちらでは、エクセルVBAのIE(InternetExplorer)操作で利用されたステートメントをまとめています。ExcelのVBAで基本的な部分になりますので、しっかり理解しましょう。

IE(InternetExplorer)制御のVBAコード

こちらでは、これまでに作成したIE(InternetExplorer)操作で役立つサブルーチンをまとめています。
全てをコピーする必要はありませんが、目的に合わせたサブルーチンをご利用ください。