0

I am trying to pull a child element from some html but I can not for the life of me work it out. I have tried several way, all have failed. Currently the code pulls all the elements and not the child that I need.

Sub Title
    If doc.getElementsByClassName("lvsubtitle")(i) Is Nothing Then
        wsSheet.Cells(Sheet1.Cells(Sheet1.Rows.Count, "E").End(xlUp).Row + 1, "E").Value = "-"
    Else
        dd = doc.getElementsByClassName("lvsubtitle")(i).innerText
        Sheet1.Cells(Sheet1.Cells(Sheet1.Rows.Count, "E").End(xlUp).Row + 1, "E").Value = dd
    End If

Tried and failed are, they all give errors

dd = doc.getElementsByClassName("lvsubtitle")(i).child (0).innerText   
dd = doc.getElementsByClassName("lvsubtitle")(i).children (0).innerText
dd = doc.getElementsByClassName("lvsubtitle")(i, 0).innerText      
dd = doc.getElementsByClassName("lvsubtitle")(0, i).innerText 
dd = doc.getElementsByClassName("lvsubtitle")(0).innerText

Child Element

I need the bit in yellow, but currently it also pulls in the bit in red.

Thanks in advance

This is the url Ebay Link

FOR INFO - The classes on IE tend to show different than they do on Chrome or Firefox:

QHarr I can never get my head around how you do the CC selector. I am new to vba and I only understand the basic. You code is always top work but way out of my depth to understand. Please could you keep it simple and to work on IE

3
  • Sorry, I am at a bit of a loss on how to use this forum, I see message in by tray, when I click on them they disapear. So I don't know who to reply back to what is been written. I can see no comments from other members on this that I have just written. The comment from QHarr is no longer visible. Commented Apr 2, 2020 at 15:59
  • Where is 'i' assigned ? Commented Apr 2, 2020 at 16:00
  • I deleted my comment because I saw you can left me a comment in the question. You should reply to people in the comments except where the requirements should be a part of the question for all to see. Commented Apr 2, 2020 at 16:02

1 Answer 1

1

My preference would be for css selectors but in line with your request I would chain nextSibling method to base nodes and make those base nodes be the titles. The current problem you have is because the same class name exists for both node you want and node you don't want. The following will select only the first but bear in mind there are not always two to select from. Where there is only one you will get the text that is there which can be "Brand New"

Option Explicit

Public Sub OMX_data()
    Dim ie As SHDocVw.InternetExplorer

    Set ie = New SHDocVw.InternetExplorer
    With ie

        .Visible = True

        .Navigate2 "https://www.ebay.co.uk/sch/i.html?_from=R40&_trksid=m570.l1313&_nkw=phones&_sacat=0"

        Do
            DoEvents
        Loop While ie.readyState <> 4 Or ie.Busy

        Dim elems  As Object, elem As Object

        With .Document

            Set elems = .getElementsbyclassname("lvtitle")

            For Each elem In elems
                Debug.Print elem.innertext, vbTab, elem.NextSibling.NextSibling.innertext
            Next
            Stop

        End With

    End With

    .Quit
End Sub

Version 2:

Where you only want the first line of text if there are two separate nodes with the same class

Option Explicit

Public Sub OMX_data()
    Dim ie As SHDocVw.InternetExplorer

    Set ie = New SHDocVw.InternetExplorer
    With ie

        .Visible = True

        .Navigate2 "https://www.ebay.co.uk/sch/i.html?_from=R40&_trksid=m570.l1313&_nkw=phones&_sacat=0"

        Do
            DoEvents
        Loop While ie.readyState <> 4 Or ie.Busy

        Dim elems  As Object, elem As Object
        Dim currentNode As Object

        With .Document

            Set elems = .getelementsbyclassname("lvresult")

            For Each elem In elems

                Set currentNode = elem.getelementsbyclassname("lvsubtitle")

                If currentNode.Length > 1 Then
                    Debug.Print elem.getelementsbyclassname("lvtitle")(0).innertext, vbTab, currentNode(0).innertext,
                 Else
                     Debug.Print elem.getelementsbyclassname("lvtitle")(0).innertext
                 End If
                Debug.Print vbNewLine
            Next
            Stop

        End With
       .Quit
    End With
End Sub

In a picture:

enter image description here

Many of the result nodes (green bounded in image) can have multiple children with the same class (as shown bounded in red). If you simply select by the class lvsubtitle then you will get all these children which means you will get text such as "Brand New" when you don't want it.

Now, in my first code example I show how you can select a previous sibling node (bounded in purple), walk the DOM to the adjacent a tag with nextSibling, and on again with nextSibling to get to the first div with the target class. This method will return each time therefore that first of two divs / only 1 if only 1.

It seems that text such as "Brand New" can appear in the first node when there is only 1. In that case, I show the second code where you select for a parent node (bounded in green); test how many children with the target class there are and if there are more than 1 take only the first and print the title and the first line text, otherwise only print the title.

Sign up to request clarification or add additional context in comments.

8 Comments

QHarr thanks for your code it is alway top work, well out of my depth.
As for CDP1802. The code itself is large and I will admit not the best written. I cut and copied and pasted so much to work out a fix that the code is all over the place. I did not want to post the full code. First to save me the embarrassment, and secondly incase somebody thought i wanted some free custom work. The code for "i" is - FOR I - 0 to 500. and it is stuck in a loop, i have to use the Esc key to get out of it, the code is in a mess and i did not wish to post it for the reasons above. If someone wants to look at it then I will post it, but it's a mess & I can't explain most of it.
Not sure what the problem is with this version. You simply choose the a different class (lvtitle) which is the class for the title of the item. This item is at the same level as the text you want. You can walk to the next node at same level (sibling) with a method called nextSibling; call that method again and you are at the target node. If however, you only want the first node of two and ignore when there is only one node (this node being with the class you originally used) you can taken a parent node and test for the number of nodes with that class
Break your code into self-contained sections which address a single problem (so if lots of problems simplify code to only that which can demonstrate the current problem you are asking about- which should be able to run it and reproduce ideally). When you post ask about only one problem at a time.
That way we can all avoid cognitive overload and focus just one specific problem at a time.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.