VBレスキュー(花ちゃん)
VB2005用トップページへVBレスキュー(花ちゃん)のトップページVB6.0用のトップページ各掲示板

リンク元へ戻ります。 インターネット関係のメニュー
1.VB6.0でハイパーリンクを作成するには
2.指定のURLのHTMLファイルをダウンロードする
3.HTMLファイルの内容をテキスト形式及びHTML形式で取得して表示
4.インターネット一時ファイルを削除する
5.InternetExplorer を使っての HTM ファイル内の要素を取得・操作例
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.


5.InternetExplorer を使っての HTM ファイル内の要素を取得・操作例 
1.InternetExplorer を使っての HTM ファイル内の全ての要素を調査
2.上記プログラム使用上の留意点
3.要素を取得してのその活用例(Yahoo メールへのログイン)
4. 
5. 
6. 

 下記プログラムコードに関する補足・注意事項 
動作確認:Windows Vista・Windows 7 (32bit) / VB6.0(SP6)
Option :[Option Explicit]
参照設定:Microsoft Internet controls 参照設定方法参照
使用 API:

その他 :プロジェクト→コンポーネント→コントロールで Microsoft Rich Textbox Control 6.0 にチェックを入れ、
    :そして、表示された Rich Textbox コントロールをフォームに貼り付けて下さい。
このページのトップへ移動します。 1.InternetExplorer を使っての HTM ファイル内の全ての要素を調査

Option Explicit

Private WithEvents IE As SHDocVw.InternetExplorer
Private myURL     As String

Private Sub Form_Load()
  Command2.Enabled = False  '表示されるまでは使用できないように
  Command3.Enabled = False
  Command4.Enabled = False
  Text1.Text = "https://login.yahoo.co.jp/config/login_verify2?.src=ym"
  RichTextBox1.Text = "" 'テキストボックスでは、メモリオーバーになるので
  Text3.Text = "ALL"
End Sub

Private Sub Command1_Click()
  Command2.Enabled = False
  Command3.Enabled = False
  Command4.Enabled = False

  RichTextBox1.Text = ""
  myURL = Text1.Text
  '起動中のIEを閉じる場合
  If Not IE Is Nothing Then
    IE.Quit
    Set IE = Nothing
  End If
  Set IE = New SHDocVw.InternetExplorer
  '指定のURLを表示
  IE.Navigate2 myURL
  IE.Visible = True  'IE を表示
End Sub

Private Sub IE_DocumentComplete(ByVal pDisp As Object, URL As Variant)
  Debug.Print "[ " & URL & " ]"   '同時にどのようなものが表示されるか確認して下さい。
  If CStr(URL) <> myURL Then
    '指定のURL以外は除外する(広告のページやフレーム等が表示されるので)
    Exit Sub
  End If
  '指定のURLが表示されるまで待つ(待機関数等で表示待ちをしない事)
  Command2.Enabled = True
  Command3.Enabled = True
  Command4.Enabled = True
End Sub

Private Sub Command2_Click()
  Dim Element As Object
  Dim i    As Long
  Dim myText As String
  myText = fStrCut("No.", 10) & fStrCut("要素名", 20) & fStrCut("http://www.nikkansports.com/Type", 20) & _
         fStrCut("NAME", 26) & fStrCut("ID", 26) & fStrCut("value", 30) & vbCrLf
  Dim No As String, TN As String, ty As String, na As String, id As String, va As String

  With IE
    i = 0
    '全ての要素を取得
    If Text3.Text = "ALL" Then
      For Each Element In .Document.All
        '要素によっては、エラーが発生するので別処理で
        If TypeName(Element) = "HTMLIFrame" Then
          No = fStrCut(CStr(i), 10)
          TN = fStrCut(Element.tagName, 20)
          ty = fStrCut("【Error】", 20)
          na = fGetType(Element.getAttribute("NAME"), 26)
          id = fGetType(Element.getAttribute("ID"), 26)
          va = fGetType(Element.getAttribute("value"), 30)
          myText = myText & No & TN & ty & na & id & va & vbCrLf
          i = i + 1
        Else
          No = fStrCut(CStr(i), 10)
          TN = fStrCut(Element.tagName, 20)
          ty = fGetType(Element.getAttribute("Type"), 20)
          na = fGetType(Element.getAttribute("NAME"), 26)
          id = fGetType(Element.getAttribute("ID"), 26)
          va = fGetType(Element.getAttribute("value"), 30)
          myText = myText & No & TN & ty & na & id & va & vbCrLf
          i = i + 1
        End If
      Next
    Else
      '指定の要素だけ取得する
      For Each Element In .Document.All.tags(Text3.Text)
        '取得したデータを表示する為に加工
        No = fStrCut(CStr(i), 10)
        TN = fStrCut(Element.tagName, 20)
        ty = fGetType(Element.getAttribute("Type"), 20)
        na = fGetType(Element.getAttribute("NAME"), 26)
        id = fGetType(Element.getAttribute("ID"), 26)
        va = fGetType(Element.getAttribute("value"), 30)
        myText = myText & No & TN & ty & na & id & va & vbCrLf
        i = i + 1
      Next
    End If
  End With
  RichTextBox1.Text = myText
End Sub

Private Function fStrCut(ByRef CutTxt As String, _
             ByVal CutLen As Long) As String
'半角・全角の混在する文字列を半角換算文字長で取り出し
  Dim myLen As Long, SysCodeTxt As String
  SysCodeTxt = StrConv(CutTxt, vbFromUnicode)   '文字列を変換
  myLen = LenB(SysCodeTxt)  '半角換算のバイト数を取得
  If myLen <= CutLen Then   '指定の長さより短い場合
    fStrCut = CutTxt & Space$(CutLen - myLen)  '足りない分はスペースで
  Else  '該当の文字列の方が長い場合、指定のバイトでカットする
    fStrCut = StrConv(LeftB$(SysCodeTxt, CutLen), vbUnicode)
    If InStr(fStrCut, vbNullChar) > 0 Then
      '漢字1バイト目で分断された場合の処理
      fStrCut = Left$(fStrCut, InStr(fStrCut, vbNullChar) - 1) & " "
    End If
  End If
End Function

Private Function fGetType(ByVal MyType As Variant, _
                  ByVal myLen As Integer) As String
'取得したデータの検査と表示する為の文字列の加工
  Dim st As String
  If Len(MyType) = 0 Or IsNull(MyType) Then
    fGetType = String$(myLen, " ")
  Else
    '取得したデータを指定の文字数にカットする
    fGetType = fStrCut(CStr(MyType), myLen)
  End If
End Function

Private Sub IE_OnQuit()
  'ユーザーがIEを閉じた場合
  Set IE = Nothing
  Command2.Enabled = False
  Command3.Enabled = False
  Command4.Enabled = False
End Sub

Private Sub Form_Unload(Cancel As Integer)
  'IE が起動中なら閉じる
  If Not IE Is Nothing Then
    IE.Quit
    Set IE = Nothing
  End If
End Sub

 上記、実行結果及び使用コントールと配置図
 

上記は、Yahoo!メールのログイン画面の要素を取得した場面です。
これで、アクセスしたい要素がどのようになっているか調べる事ができます。
タグ名を指定すれば、そのタグだけが取得できます。

但し、サイトの作りによっては、エラーが発生してうまく取得できない要素が含まれている場合がありますので、その場合は、エラー処理を追加願います。

このページのトップへ移動します。 2.上記プログラム使用上の留意点
このように要素を取得するには、Documentプロパティへの読み込みが完了してからでないと取得する事ができません。
 従って、以前は、この読み込み完了を取得するのに下記のようなコードが多く使用されていましたが、これにはいくつかの問題があります。

Do While IE.ReadyState <> READYSTATE_COMPLETE
  DoEvents
  Sleep 50
Loop

 一番の問題は、これでは読み込み完了を確実に取得できない点にあります。例えば、私のサイトのトップページを読み込んだ場合、[ http://hanatyan.sakura.ne.jp/menu.htm ]と[ http://hanatyan.sakura.ne.jp/top.htm ]と[ http://hanatyan.sakura.ne.jp/ ]が同時(同じ時に順次複数のページが読み込(表示)まれる)に読み込まれます。
 従って、一番最初に読み込まれた時に上記のコードでは通過してしまい、目的のページが表示される前に次のコードが実行されエラーが発生したりします。
 この他、ブランクのページが読み込まれたり、広告のページが同時に読み込まれたりもしますし、サーバーの状態や通信状態等でも影響を受けやすくエラーの発生の元になります。
 又、VBは、イベント駆動型の言語なので、イベントで処理するのが望ましい、例えば、キーボードからのキー入力に対して上記のような待機処理でキー入力の有無を判断しませんよね。
 それと、指定時間待つ、待機関数のところでも解説しておりましたが、Sleep 関数やDoEvents の多用に対する問題等もあり、ページ遷移の完了を待つのであれば、NavigateComplete2 イベントを Documentプロパティへの読み込み完了を待つのなら、DocumentComplete イベントで取得するようにしましょう。
(斯く言う私も、WEB上の多くのサンプルを習って最近まで使っておりました。)
VB上から、IE(InternetExplorer) のイベントを取得するには、参照設定しただけでは取得する事ができません。

下記のように、WithEvents キーワード を使って宣言すると IE のイベントを取得する(拾う)事ができます。
Private WithEvents IE As SHDocVw.InternetExplorer

 又、DocumentComplete イベントでは、下記のように取得したい Document が表示されている URL かどうかを調べるようにすればより確実に判断ができます。(他のサンプルでの使用例も参考にして下さい。)
Private Sub IE_DocumentComplete(ByVal pDisp As Object, URL As Variant)
  Debug.Print "[ " & URL & " ]"   '同時にどのようなものが表示されるか確認して下さい。
  If CStr(URL) <> myURL Then
    '指定のURL以外は除外する(広告のページやフレーム等が表示されるので)
    Exit Sub
  End If
Debug.Print でどのようなページが同時に表示されているのかも調べておくのもいいかと思います。

このページのトップへ移動します。 3.要素を取得してのその活用例(Yahoo メールへのログイン)
今回の場合は、ID が付けられているので、ID 属性は、その要素の一意識別子なので同じIDで複数ないのでこれで特定できます。

Private Sub Command3_Click()
  IE.Document.getElementById("username").Value = "myID"
  IE.Document.getElementById("passwd").Value = "myPasswd"
  IE.Document.getElementById(".save").Click
End Sub

同様に、Name で特定できるならば、下記のようにしても同じ事です。
IE.Document.getElementsByName("login").Item(0).Value = "myID"
IE.Document.getElementsByName("passwd").Item(0).Value = "myPasswd"
IE.Document.Forms(0).submit

又、下記のようにすることもできます。
Private Sub Command4_Click()
  With IE
    .Document.Forms(0).Elements("login").Value = "myID"
    .Document.Forms(0).Elements("passwd").Value = "myPasswd"
    'IDとパスワードを記憶用のチェックボックスにチェックを入れる
    If .Document.Forms(0).Elements(".persistent").Checked = False Then
      .Document.Forms(0).Elements(".persistent").Click
    End If
    'ログインボタンをクリック
    .Document.Forms(0).submit
  End With
End Sub

下記でも同様に実行できます。
Private Sub Command5_Click()
  IE.Document.All.tags("INPUT").Item(30).Value = "myID"
  IE.Document.All.tags("INPUT").Item(31).Value = "myPasswd"
  IE.Document.Forms(0).submit
End Sub

上記の要素の取得で、要素名とかIDで、

基本的には、ID とか Name とか ボタンとかリンクの所に書かれている文字等でどの要素かを特定して、その要素に対して操作する事になります。
従って、書かれている内容によって識別の方法が違うし操作も変わってきます。
出来るだけ、変更されても影響を受けにくくて操作が簡単な方法を選んで下さい。
ID → name → 表面等に書かれている文字 → 複数の条件の組み合わせ → 取得順 のように。

但し、サイトのレイアウトや記入項目等変更された場合は、当然のことながらこちらも同様に変更しないと操作できません。

このページのトップへ移動します。 4.


このページのトップへ移動します。 5.


このページのトップへ移動します。 6.


このページのトップへ移動します。 検索キーワード及びサンプルコードの別名(機能名)





このページのトップへ移動します。