/ / Estrazione dei valori di span dall'interno di una classe, VBA - html, excel, vba, excel-vba

Estrazione di valori di span da una classe, VBA - html, excel, vba, excel-vba

Dopo molte ricerche, sto lottando per farloraschia i dati dall'HTML di seguito utilizzando VBA. In particolare, sto cercando di estrarre i valori "DATA ONE" e "DATA THREE" da ciascuna classe = "_ Xnb _QJ" nel codice HTML seguente:

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

Ho provato a utilizzare getElementsByClassNameper ottenere una raccolta delle classi "_Xnb _QJ" e per ciascuna di queste classi utilizzare getElementsByTagName per cercare "_MHb" e "_FS". Non riesco a selezionare i bambini in ordine numerico poiché questo cambia tra le classi "_Xnb ..", ma i dati che richiedo hanno sempre lo stesso tag di classe (_MHb / FS) allegato.

Sono un principiante completo di VBA / HTML quindi questo codiceè stato in gran parte assemblato modificando esempi altrove su stackoverflow. Mi chiedo se il fatto che le classi che richiedo siano all'interno di "href" anziché direttamente sotto la classe _Xnb sia la ragione per cui non riesco a estrarre i dati corretti?

Parte rilevante del mio codice VBA di seguito: quando lo eseguo, il codice sembra funzionare correttamente ma non vengono raccolti dati.

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

Qualsiasi aiuto sarebbe molto apprezzato.

Grazie molto

risposte:

0 per risposta № 1

Ti consiglierei di fare delle ricerche XPath - un linguaggio di query basato su standard per lavorarecon documenti XML. Puoi anche usarlo con documenti HTML in cui sono ben formati. È un po 'arcano, ma super utile e può essere utilizzato anche in VBA.

Il tuo codice HTML di esempio sembra un po 'complesso poiché hai più file <div> tag con la stessa classe. Inoltre non è XML valido a causa di //Extracted// nel <img> etichetta. Inoltre, non c'erano tag di chiusura nell'esempio. Comunque, l'ho riordinato nel codice di esempio qui sotto.

Ho guardato la tua domanda e l'ho interpretata in questo modo:

Estrai qualsiasi testo da un file <span> tag dove è di classe _MHb o Fs; e dove è un discendente di a <div> tag di classe _Xnb _QJ

In tal caso, la tua query XPath può essere costruita in tre parti:

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

Significato: ottieni qualsiasi tag div con classe _Xnb _QJ.

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

Significato: prendi semplicemente l'elemento più interno dal primo set (ricordando che hai più file <div> tag con la stessa classe).

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

Significato: filtra il più interno <div> per <span> tag che hanno la classe _Mhb o _Fs.

Quindi, puoi usare XPath in VBA se includi la libreria MSXML (che penso tu abbia già fatto). Il codice ha questo aspetto:

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

L'output di debug è simile a questo:

<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

Sembra tutto un po 'complesso, ma andrà tutto bene una volta che avrai provato a farlo.