0

I have the following html part

<div class="description">
<span>Brand:</span> 
<a href="http://www.bestfamily.gr">Nikon</a><br/>
<span>Product Code:</span> 130342 <br/>
<span>Barcode</span> 18208948581 <br/>
<span>Availability:</span>Available</div>

I am trying to get the last span and the word Available using the following

Set availability = ie.Document.getElementsByClassName(".description").getElementsByTagName("span")(2)
wks.Cells(i, "D").Value = availability.innerText

But it shows all span texts What I am doing wrong here?

braX
  • 11,506
  • 5
  • 20
  • 33
  • I'm not really familiar with HTML and VBA. Maybe consider this question for reference: https://stackoverflow.com/questions/42741997/get-all-innertext-vba – prextor Dec 11 '18 at 10:51
  • 2
    Try changing `ie.Document.getElementsByClassName(".description")..` to `ie.Document.getElementsByClassName("description")..`. Remove **`.`** from infront of **`description`** – Zac Dec 11 '18 at 11:08
  • It is not working it shows nothing in cell –  Dec 11 '18 at 11:16
  • Try using an elements collection and then use it's properties for the count – Nathan_Sav Dec 11 '18 at 11:27

2 Answers2

1

Use last-child css pseudo class in descendant combination with parent element class selector.

.description span:last-child

The :last-child CSS pseudo-class represents the last element among a group of sibling elements.

Applying:

single match

Set availability = ie.document.querySelector(".description span:last-child")
Cells(1,1) = availability.innerText

all matches

Set availability = ie.document.querySelectorAll(".description span:last-child")
Cells(1,1) = availability.item(0).innerText

Otherwise, you can return the span collection from that parent class and index into it

Set availability = ie.document.querySelectorAll(".description span")
Cells(1,1) = availability.item(2).innerText '<==choose your index here

Or even chain:

Set availability = ie.document.querySelector(".description span + span + span")  '<==expand as required. This uses [adjacent sibling combinator][4].

Sadly, pseudo classes nth-of-type / nth-child are not supported in VBA implementation though you can in many other languages e.g. python.

—-

If after just the Available you should be able to use .description as your selector to return all the text in the div. Then use Split on the .innerText using Chr$(32) to split by and extract the UBound (I.e. the last element of the generated array)

Set availability = ie.document.querySelector(".description")
Dim arr() As String
arr = split( availability.innerText, ":")
Cells(1,1) = arr(UBound(arr))
QHarr
  • 83,427
  • 12
  • 54
  • 101
  • Yes but I get only the word Availability: inside span, not the text Available which belongs to div? I am not sure –  Dec 11 '18 at 13:49
  • @Nikos select the div by class name. Split the .innertext and take the ubound – QHarr Dec 11 '18 at 13:51
  • you mean Set availability = ie.document.querySelectorAll(".description div") Cells(1,1) = availability.innertext.unbound ? –  Dec 11 '18 at 13:54
  • 1
    instead of chr$(32) I just put ":" and I got the last word thank you very much –  Dec 11 '18 at 14:21
0

As Zac pointed out in the comments, you shouldn't use a period . with the getElementsByClassName method.

ie.Document.getElementsByClassName is returning a DispHTMLElementCollection of elements. You need to specify which element you want to reference

Set availability = ie.Document.getElementsByClassName(".description")(0).getElementsByTagName("span")(2)

A better way to write the write the code would be to reference the Microsoft HTML Object Library and create a variable to test each element returned. Unfortunately, there is a bug in the DispHTMLElementCollection implementation, so you will need to use Object instead of DispHTMLElementCollection.

Dim doc As HTMLDocument
Dim availability As Object
Set doc = ie.Document
Set availability = doc.getElementsByClassName("description")

Dim div As HTMLDivElement
Dim span As HTMLSpanElement
Dim spans As Object

For Each div In availability
    Set spans = div.getElementsByTagName("span")
    For Each span In spans
        Debug.Print span.innerText
    Next
Next    

Output

enter image description here

TinMan
  • 6,624
  • 2
  • 10
  • 20