5

これは何度も尋ねられていることは知っていますが、div をループして同じクラス名のタグを見つけることについて明確な答えを見たことはありません。

私の最初の質問:

私がこのようなものを持っている場合:

<div id="carousel">
   <div id="images">

       <div class="imageElement">
          <img src="img/image1.jpg">
       </div>

       <div class="imageElement">
          <img src="img/image2.jpg">
       </div>

       <div class="imageElement">
           <img src="img/image3.jpg">
       </div>

   </div>

</div>

したがって、div「画像」のすべての img Src を、imageElement クラス名の他のものと一緒に取得し、それらを Excel のいくつかのセルにコピーしたいと考えています。

2 番目の質問: VBA を使用して Web コンテンツをプルする 2 つの方法を見てきました。1 つは IE を使用し、もう 1 つはブラウザー以外を使用するコードです。

Private Sub pullData_Click()

    Dim x As Long, y As Long
    Dim htm As Object

    Set htm = CreateObject("htmlFile")

    With CreateObject("msxml2.xmlhttp")
        .Open "GET", "http://website.html", False
        .send
        htm.body.innerHTML = .responsetext
    End With

End Sub

そして2番目の方法:

Set ie = New InternetExplorer
    With ie
        .navigate "http://eoddata.com/stockquote/NASDAQ/AAPL.htm"
        .Visible = False
        While .Busy Or .readyState <> READYSTATE_COMPLETE
           DoEvents
        Wend
        Set objHTML = .document
        DoEvents
    End With
    Set elementONE = objHTML.getElementsByTagName("TD")
    For i = 1 To elementONE.Length
        elementTWO = elementONE.Item(i).innerText           
        If elementTWO = "08/10/12" Then
            MsgBox (elementONE.Item(i + 1).innerText)
            Exit For
        End If
    Next i
    DoEvents
    ie.Quit
    DoEvents
    Set ie = Nothing

どちらが優れているのか、その理由は?

あなたが私を助けることができれば、私は感謝します。

前もって感謝します。

4

3 に答える 3

8

最初のオプションは、2 番目の方法よりもはるかに高速であるため、通常は望ましい方法です。リクエストを Web サーバーに直接送信し、レスポンスを返します。これは、Internet Explorer を自動化する (2 番目のオプション) よりもはるかに効率的です。IE の自動化は非常に遅くなります。事実上サイトを閲覧しているだけなので、ページ内のすべてのリソース (画像、スクリプト、css ファイルなど) をロードする必要があるため、必然的により多くのダウンロードが発生します。ページ上で Javascript も実行されます。 - 通常、これらはすべて役に立たず、ページを解析する前に完了するまで待つ必要があります。

ただし、これは両刃の剣のようなものです。HTML 要求に慣れていない場合は、はるかに時間がかかりますが、特に要素が動的に生成される場合やページが AJAX に依存している場合、Internet Explorer の自動化は最初の方法よりもはるかに簡単です。また、ログインが必要なサイトのデータにアクセスする必要がある場合、IE が関連する Cookie を処理するため、IE を自動化するのも簡単です。これは、最初の方法で Web スクレイピングを行うことができないということではなく、Web テクノロジーとサイトのアーキテクチャをより深く理解する必要があるということではありません。

最初の方法よりも優れたオプションは、別のオブジェクトを使用して要求と応答を処理することです。WinHTTP ライブラリを使用すると、MSXML ライブラリよりも回復力が高くなり、通常はすべての Cookie も自動的に処理されます。

データの解析に関しては、最初のアプローチでは遅延バインディングを使用して HTML オブジェクト (htmlfile) を作成しましたが、これにより参照の必要性が減り、機能も低下します。たとえば、遅延バインディングを使用すると、ユーザーが IE9 をインストールしている場合に追加された機能 (特にこの場合は getElementsByClass name 関数) を利用できなくなります。

そのような3番目のオプション(および私の好みの方法)として:

Dim oHtml       As HTMLDocument
Dim oElement    As Object

Set oHtml = New HTMLDocument


With CreateObject("WINHTTP.WinHTTPRequest.5.1")
    .Open "GET", "http://www.someurl.com", False
    .send
    oHtml.body.innerHTML = .responseText
End With

For Each oElement In oHtml.getElementsByClassName("imageElement")
    Debug.Print oElement.Children(0).src
Next oElement

'IE 8 alternative
'For Each oElement In oHtml.getElementsByTagName("div")
'    If oElement.className = "imageElement" Then
'        Debug.Print oElement.Children(0).src
'    End If
'Next oElement

これには への参照設定が必要ですMicrosoft HTML Object Library- ユーザーが IE9 をインストールしていない場合は失敗しますが、これは処理可能であり、ますます関連性が低くなります。

于 2013-09-10T08:24:00.427 に答える
2

要素をセルに出力するには、次のように置き換えます。

For Each oElement In oHtml.getElementsByClassName("imageElement")
    Debug.Print oElement.Children(0).src
Next oElement

と:

Dim wsTarget as Worksheet
dim i as Integer
i=1
set wsTarget=activeworkbook.worksheets("SomeSheet")

For Each oElement In oHtml.getElementsByClassName("imageElement")
    wstarget.range("A" & i)=oElement.Children(0).src
    i=i+1
Next

'For の構文エラーを修正しました

于 2013-11-14T19:23:46.243 に答える