の続きです。
今回は”インラインフレーム構造”の説明と、その場合のデータ取得方法について紹介致します。
インラインフレームとは?
“フレーム”構造の場合は表示させたいページAとB、そして一つのページをフレームで分割し、ページA、Bを読み込む様に指定していたページCが存在しました。
しかしインラインフレームの場合は、このCのページを用意することなく実装することができます。記述する際は以下の様に<iframe>タグを用います。
<iframe src="sample.html"></iframe>
インラインフレームを使用すると、ページ内の『任意の場所』に『任意のサイズ』で他のページの情報を表示することが可能となります。
イメージとしては以下の様な形です。
それではこの記事内にも試しに表示してみましょう。
<frameset>等を記述する専用のページが必要無いため、この様にかんたんにフレーム用のページを表示させることができます。
フレームとインラインフレームの違いは?
フレーム | インラインフレーム |
---|---|
ウェブページを上下、または左右に分割し、その中に別ファイルを読み込む。 | ウェブページ内の好きな場所にフレーム領域を作り、その中に別ファイルを読み込む。 |
大まかにはこの様な違いとなっています。
<フレームのメリット>
ウェブページを長く運営していると、その分扱っているコンテンツも増えてくると思います。フレームを用いないページの場合、コンテンツメニューやリンクなどを各ページに記述しなければいけないため、その分更新に手間が掛かります。
一方フレームでページを分割し、メニュー専用のページを用意している場合は、メニューページのみの更新で良いため管理が非常に楽になります。
その他、メイン画面のコンテンツを見ながらメニュー画面の確認ができるため、ページの構成や流れも分かりやすくなります。
<フレームのデメリット>
どのページにリンクしてもURLが変わらないため、特定のコンテンツのみを宣伝しようと思ってもできない。
<インラインフレームのメリット>
広告の表示など、全てのページで同じ内容のコンテンツを表示させたい場合に非常に便利です。各ページで広告用のページを呼び出す処理を記述するだけで、後の更新作業は呼び出し先のページの更新のみで済むからです。
ページの一角を利用したコンテンツの表示に向いています。
<インラインフレームのデメリット>
この辺はあまり良く知りませんが、ブラウザや通信環境によって読み込みにだいぶ時間が掛かることがあるそうです。
後はDOM操作が面倒臭くなる所でしょうか。
インラインフレームの要素を取得する
インラインフレームの特徴、フレームとの違いを確認した所で本題に入りましょう。
先ほどページ内に表示させたインラインフレームのページから、それぞれのページのタイトル名を取得してみます。
<iframe width="500" height="100" src="https://rabbitfoot.xyz/sample/frame-c.html"></iframe>
インラインフレーム部分のソースはこの様になっています。
ではフレームの時のソースコードを確認してみましょう。
Set objFrame = objIE.document.frames For iFrameCnt = 0 To objFrame.length - 1 Debug.Print objFrame(iFrameCnt).document.title Next
フレームの時は「frames」というプロパティから操作することができましたが、インラインフレームの場合は同様の操作は行えません。「iframe」の中身に直接アクセスすることは不可能です。
ではどうすれば良いか?
インラインフレームとして表示されているから対象のページが操作できないだけであって、ページ自体が特殊だから操作ができない訳ではありません。
ですので、インラインフレームの中に表示されているページの”URL”を取得し、そのURLのページを”VBAから新規IEで開いてあげればいい”んです。
早速試してみましょう。
Sub main() Dim objIE As InternetExplorer Dim objChildIE As InternetExplorer Dim objFrame As Object Dim strIFrameSrc As String Dim iFrameCnt As Integer 'まずはこのブログのページを開く Set objIE = getTargetUrlIE("https://rabbitfoot.xyz/vba-inlineframe2/") 'インラインフレームタグのオブジェクトから、"src"のデータを取得する strIFrameSrc = objIE.document.getElementsByTagName("iframe")(0).src '取得したインラインフレームのURLから、対象のページを新規に開く Set objChildIE = getTargetUrlIE(strIFrameSrc) Set objFrame = objChildIE.document.frames For iFrameCnt = 0 To objFrame.length - 1 Debug.Print objFrame(iFrameCnt).document.title Next End Sub '指定したURLのサイトを返す Function getTargetUrlIE(url As String) As InternetExplorer Dim objIE As InternetExplorer 'IE格納 Dim objSh As Object 'shellオブジェクト格納 Dim objWindow As Object 'ウィンドウを格納 Dim sWindowName As String 'ウィンドウタイトルを格納 Set objSh = CreateObject("Shell.Application") For Each objWindow In objSh.Windows On Error Resume Next sWindowName = "" sWindowName = objWindow.FullName On Error GoTo 0 'IEウィンドウかどうかの判定 If LCase(Right(sWindowName, 12)) = "iexplore.exe" Then 'URLが指定のものかどうかを判定 If InStr(objWindow.LocationURL, url) > 0 Then Set objIE = objWindow Exit For End If End If Next '目的のIEが開かれていない場合は作成する If objIE Is Nothing Then Set objIE = CreateObject("InternetExplorer.Application") objIE.Visible = True objIE.Navigate2 url Do While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE DoEvents Loop End If Set getTargetUrlIE = objIE End Function
いかがでしょうか。
上記コードを実行することで、インラインフレームで表示されているページの要素が取得できたのでは無いかと思います。
上記コードではインラインフレーム要素は一つしか無いため「getElementsByTagName(“iframe”)(0).src」としましたが、複数存在する場合やid値等、識別可能な値が振られている場合は、その値を指定しましょう。
コメント
教示いただきたい。
複数フレームで構成するホームページがあります。ブラウザがIEのときは、.Document.frames が使用できたのですが、ブラウザがedgeのIEモードで表示ではエラーになります。edgeのIEモード表示で表示しているときのフレーム数、特定フレームを指定する方法を教示願います。