/ / Extrahieren von Bereichswerten aus einer Klasse, VBA - html, excel, vba, excel-vba

Extrahieren von Bereichswerten aus einer Klasse, VBA - html, excel, vba, excel-vba

Nach langem Suchen habe ich Probleme damitKratzen Sie die Daten mit VBA aus dem folgenden HTML-Code. Insbesondere versuche ich, die Werte "DATA ONE" und "DATA THREE" aus jeder Klasse = "_ Xnb _QJ" im folgenden HTML-Code abzurufen:

<div class="results">
<div class="_s2 _wPc">
<div class="_fW _QJ">
<div class="_Xnb _QJ _Z9b">
<div class="_Xnb _QJ">
<div class="_Xnb _QJ">
<div class="_Xnb _QJ">
<a href="//Extracted URL//">
<span class="_fbb">
<img id="uid_3" //Extracted// >
</span>
<span class="_PHb">
<span class="_MHb">DATA ONE</span>
</span>
<span class="_B6e">
<span class="_x2">DATA TWO</span>
<span class="_Fs"> DATA THREE </span>

Ich habe versucht, getElementsByClassName zu verwendenUm eine Sammlung der "_Xnb _QJ" -Klassen abzurufen, verwenden Sie für jede dieser Klassen getElementsByTagName, um nach "_MHb" und "_FS" zu suchen. Ich kann die untergeordneten Elemente nicht in numerischer Reihenfolge auswählen, da sich dies zwischen den Klassen "_Xnb .." ändert, aber an die von mir benötigten Daten ist immer das gleiche Klassen-Tag (_MHb / FS) angehängt.

Ich bin ein absoluter Neuling in VBA / HTML, also dieser Codewurde größtenteils durch Bearbeiten von Beispielen an anderer Stelle im Stapelüberlauf zusammengestellt. Ich frage mich, ob die Tatsache, dass die von mir benötigten Klassen innerhalb der "href" und nicht direkt unter der _Xnb-Klasse liegen, der Grund ist, warum ich nicht die richtigen Daten abrufen kann.

Relevanter Teil meines VBA-Codes unten - wenn ich ihn ausführe, scheint der Code einwandfrei zu laufen, aber es werden keine Daten gesammelt.

Dim RowNumber As Long
Dim DataOne As String
Dim DataThree As String
Dim QuestionList As IHTMLElementCollection
Dim Question As IHTMLElement
Dim QuestionFields As IHTMLElementCollection
Dim QuestionField As IHTMLElement
RowNumber = 1

Set QuestionList = html.getElementsByClassName("_Xnb _QJ")

For Each Question In QuestionList
Set QuestionFields = Question.getElementsByTagName("SPAN")

For Each QuestionField In QuestionFields
If QuestionField.className = "_MHb" Then
DataOne= QuestionField.innerText
Cells(RowNumber, 1).Value = DataOne
End If

If QuestionField.className = "_Fs" Then
DataThree = QuestionField.innerText
Cells(RowNumber, 2).Value = DataThree
End If

Next QuestionField
RowNumber = RowNumber + 1
Next
Set html = Nothing
MsgBox "Done!"

End Sub

Jede Hilfe würde sehr geschätzt werden.

Danke vielmals

Antworten:

0 für die Antwort № 1

Ich würde Ihnen raten, zu recherchieren XPath - eine auf Standards basierende Abfragesprache zum Arbeitenmit XML-Dokumenten. Sie können dies auch für HTML-Dokumente verwenden, bei denen sie gut geformt sind. Es ist ein bisschen arkan, aber sehr nützlich und kann auch in VBA verwendet werden.

Ihr Beispiel-HTML sieht etwas komplex aus, da Sie mehrere haben <div> Tags mit derselben Klasse. Es ist auch kein gültiges XML wegen der //Extracted// in dem <img> Etikett. Außerdem gab es im Beispiel keine schließenden Tags. Wie auch immer, ich habe es im folgenden Codebeispiel aufgeräumt.

Ich habe mir Ihre Frage angesehen und sie so interpretiert:

Extrahieren Sie einen beliebigen Text aus a <span> Tag, wo es von Klasse ist _MHb oder Fs;; und wo es ein Nachkomme von a ist <div> Tag der Klasse _Xnb _QJ

In diesem Fall kann Ihre XPath-Abfrage aus drei Teilen bestehen:

//div[@class="_Xnb _QJ"]

Bedeutung - Holen Sie sich alle div-Tags mit der Klasse von _Xnb _QJ.

(//div[@class="_Xnb _QJ"])[last()]

Bedeutung - holen Sie sich einfach das innerste Element aus dem ersten Satz (denken Sie daran, dass Sie mehrere verschachtelte Elemente haben <div> Tags mit derselben Klasse).

(//div[@class="_Xnb _QJ"])[last()]//span[@class="_MHb" or @class="_Fs"]

Bedeutung - filtern Sie das Innerste <div> zum <span> Tags, die Klasse von haben _Mhb oder _Fs.

Sie können XPath also in VBA verwenden, wenn Sie die MSXML-Bibliothek einschließen (was Sie meiner Meinung nach bereits getan haben). Der Code sieht folgendermaßen aus:

Option Explicit

Sub Test()

Dim strXml As String
Dim objXml As New DOMDocument60
Dim strXPath As String
Dim objXmlNodeList As IXMLDOMNodeList
Dim objXmlNode As IXMLDOMNode

"get the sample XML
strXml = GetXml

"load xml to document
If Not objXml.LoadXML(strXml) Then
Debug.Print "Not parsed"
Exit Sub
End If

"apply XPath
"first just let"s get the last <div> tag of class _Xnb _QJ
strXPath = "(//div[@class="_Xnb _QJ"])[last()]"
"test that query
Set objXmlNodeList = objXml.SelectNodes(strXPath)
For Each objXmlNode In objXmlNodeList
Debug.Print objXmlNode.XML
Next objXmlNode

"now lets append a filter to only get the <span> texts
strXPath = strXPath & "//span[@class="_MHb" or @class="_Fs"]"

"get output nodes by applying query to xml
Set objXmlNodeList = objXml.SelectNodes(strXPath)
For Each objXmlNode In objXmlNodeList
Debug.Print objXmlNode.Text
Next objXmlNode

End Sub

Function GetXml() As String

Dim strXml As String

strXml = ""
strXml = strXml & "<div class=""results"">"
strXml = strXml & "  <div class=""_s2 _wPc"">"
strXml = strXml & "    <div class=""_fW _QJ"">"
strXml = strXml & "      <div class=""_Xnb _QJ _Z9b"">"
strXml = strXml & "        <div class=""_Xnb _QJ"">"
strXml = strXml & "          <div class=""_Xnb _QJ"">"
strXml = strXml & "            <div class=""_Xnb _QJ"">"
strXml = strXml & "              <a href=""//Extracted URL//"">"
strXml = strXml & "                <span class=""_fbb"">"
strXml = strXml & "                  <img id=""uid_3"" />"
strXml = strXml & "                </span>"
strXml = strXml & "                <span class=""_PHb"">"
strXml = strXml & "                  <span class=""_MHb"">DATA ONE</span>"
strXml = strXml & "                </span>"
strXml = strXml & "                <span class=""_B6e"">"
strXml = strXml & "                  <span class=""_x2"">DATA TWO</span>"
strXml = strXml & "                  <span class=""_Fs""> DATA THREE </span>"
strXml = strXml & "                </span>"
strXml = strXml & "              </a>"
strXml = strXml & "            </div>"
strXml = strXml & "          </div>"
strXml = strXml & "        </div>"
strXml = strXml & "      </div>"
strXml = strXml & "    </div>"
strXml = strXml & "  </div>"
strXml = strXml & "</div>"

GetXml = strXml

End Function

Die Debug-Ausgabe sieht folgendermaßen aus:

<div class="_Xnb _QJ">
<a href="//Extracted URL//">
<span class="_fbb">
<img id="uid_3"/>
</span>
<span class="_PHb">
<span class="_MHb">DATA ONE</span>
</span>
<span class="_B6e">
<span class="_x2">DATA TWO</span>
<span class="_Fs"> DATA THREE </span>
</span>
</a>
</div>
DATA ONE
DATA THREE

Es sieht alles etwas komplex aus - aber Sie werden in Ordnung sein, wenn Sie ein paar Versuche damit haben.