简体   繁体   中英

Accessing elements of querySelectorAll in vba

One of the users have helped me to know the topic of Locating HTML elements with CSS selectors: querySelector() method is much more easier than getElementsBy() https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll#obtaining_a_list_of_matches...In code below, I want to access elements of all with innerText View Listing. For that purpose I wrote code below where querySelectorAll takes the parent div with class module(as an array, or collection, list call how you want) successfully. But after I was not able to go on element by element neither with querySelect() nor within for loop;

Public Sub newEditionQry()
    
    Const URL As String = "https://cooperatordirectory.com/search_results?location_value=Florida&adm_lvl_1_sn=FL&stateSearchLN=Florida&country_sn=US&location_type=administrative_area_level_1&stateSearch=FL&swlat=24.396308&nelat=31.000968&swlng=-87.634896&nelng=-79.974306&lat=27.6648274&lng=-81.5157535&faddress=Florida%2C+USA&place_id=ChIJvypWkWV2wYgR0E7HW9MTLvc"
    Dim ie As SHDocVw.InternetExplorer
    
    Set ie = New SHDocVw.InternetExplorer

    With ie
        .Visible = True
        .navigate URL
        Do While .readyState <> READYSTATE_COMPLETE Or .Busy: DoEvents: Loop
        
        Set a = .document.querySelectorAll(".module")
        
        For Each element In a
            Debug.Print a.querySelector("a.btn").innerText ' err line
        Next element
        
    End With

End Sub

What will I do if I will be able to catch elements with viewListing Texts. I will manipulate each of them ( if you give a look the website, you see they are dozens of them) by method click.

<div class="module nomargin text-center">
                
                <a class="btn btn-success btn-block" href="/pro/20220324090906">View Listing</a>
                                    <div class="clearfix bpad"></div>
                    <a class="btn btn-primary btn-block" href="/pro/20220324090906/connect">Send Message</a>
                            </div>

You have a typo (?) where you are calling .querySelector on the parent nodeList a . This is not a valid method call.

Instead, you wanted:

element.querySelector("a.btn").innerText

However, element.querySelector is an oddity as the shift to Edge was enacted. And here, by element , I mean html element ie a node within the DOM (not the document node), or element interface, rather than the iteration variable named element.

Your code with the above change will then error if the selector list in the loop call to querySelector returns nothing as you don't test the return to ensure there are matches.

Given what it seems you are after, the solution requires merging the two selector lists to produce a single parent nodeList satisfying both original conditions. Iterate that and simply access the .innerText property directly.

Also, the typical method for looping a nodeList is to loop from 0 to nodeList.Length - 1 and index into nodeList during the loop. There was a bug, maybe still present, with the enumeration method called by using a For Each on a static DispNodeList, in VBA, that can crash the calling application.


Public Sub newEditionQry()
    
    Const URL As String = "https://cooperatordirectory.com/search_results?location_value=Florida&adm_lvl_1_sn=FL&stateSearchLN=Florida&country_sn=US&location_type=administrative_area_level_1&stateSearch=FL&swlat=24.396308&nelat=31.000968&swlng=-87.634896&nelng=-79.974306&lat=27.6648274&lng=-81.5157535&faddress=Florida%2C+USA&place_id=ChIJvypWkWV2wYgR0E7HW9MTLvc"
    Dim ie As SHDocVw.InternetExplorer
    
    Set ie = New SHDocVw.InternetExplorer

    With ie
        .Visible = True
        .navigate URL
        Do While .readyState <> READYSTATE_COMPLETE Or .Busy: DoEvents: Loop

        Set a = .document.querySelectorAll(".module a.btn")
        
        For Each element In a
            Debug.Print element.innerText
        Next element
  
    End With

End Sub

Document.querySelectorAll()

The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.

Element.querySelector()

The querySelector() method of the Element interface returns the first element that is a descendant of the element on which it is invoked that matches the specified group of selectors.


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM