1

I am trying to fill in a search box on a web page that as it is filled in it auto searches for the results. The website is https://pcpartpicker.com/products/motherboard/. If you go there and type in a motherboard manufacturer of motherboard name you can see how it begins to narrow down the possible selections. I have code that will fill in the search box but nothing happens.

Sub GetMotherboards()
    Dim ie                      As InternetExplorer
    Set ie = New InternetExplorer

    Dim doc                     As HTMLDocument
    Dim objText                 As DataObject
    Dim objArticleContents      As Object
    Dim objLinksCollection      As Object
    Dim objToClipBoard          As DataObject
    Dim r As Object
    Dim prodRating              As String
    Dim prodName                As String
    Dim lngNumberOfVideos As Long
    Dim strURL                  As String
    Dim strNewString As String, strStr As String, strTestChar As String
    Dim bFlag As Boolean

    strURL = "https://pcpartpicker.com/products/motherboard/" ' Range("J5").Value
    With ie
        .navigate strURL
        .Visible = True
        Do While .readyState <> 4: DoEvents: Loop
        Application.Wait Now + #12:00:02 AM#

        Set doc = ie.document
    End With
    bFlag = False
    With doc
        Set objArticleContents = .getElementsByClassName("subTitle__form")

        Stop
        Set ele = .getElementsByClassName("subTitle__form")(0)

        Set form = .getElementsByClassName("subTitle__form")(0).getElementsByClassName("form-label xs-inline")(1)

        Set inzputz = ele.getElementsByClassName("text-input")(0)
        Call .getElementsByClassName("text-input")(0).setAttribute("placeholder", "MSI B450 TOMAHAWK") '.setAttribute("part_category_search", "MSI B450 TOMAHAWK")
    End With

End Sub

After reading some posts here (which I now can't find) my thinking is that there is/ are event listeners and functions that need to be included in this code but that is over my head. Could someone please help me figure this out.

Tim Williams has a post here (an answer to a post) which discussed this but now I can't find it.

K.Dᴀᴠɪs
  • 9,945
  • 11
  • 33
  • 43
awsmitty
  • 121
  • 1
  • 2
  • 10
  • How did you pass the filter string to be searched on that site? It seems your URL is fixed without any search string! – S.Serpooshan Oct 01 '19 at 05:50

2 Answers2

2

You need to execute the keyup event after you place your value into your textbox.

You can accomplish this by using the execScript method.

So, after you load the webpage, create a variable for your input/textbox. In the below example, it's tb. Set the .Value property to your search text (which I used "MSI") then fire the keyup event via script.

Dim tb As HTMLInputElement
Set tb = IE.document.getElementById("part_category_search")
tb.Value = "MSI"
IE.document.parentWindow.execScript "$('#part_category_search').keyup()"

I am not overly familiar with jQuery, so this script targets all inputs on the webpage. But I've tested it and it works for your search.

Here was the full code I used in testing if you want to shorten yours:

Dim IE As InternetExplorer
Set IE = New InternetExplorer
IE.Visible = True
IE.navigate "https://pcpartpicker.com/products/motherboard/"
Do While IE.Busy Or IE.readyState < 4
    DoEvents
Loop

Dim tb As HTMLInputElement
Set tb = IE.document.getElementById("part_category_search")
tb.Value = "MSI"
IE.document.parentWindow.execScript "$('#part_category_search').keyup()"
K.Dᴀᴠɪs
  • 9,945
  • 11
  • 33
  • 43
2

You can avoid the expense of a browser and perform the same xhr GET request the page does that returns json. You will need a json parser to handle the response.

Json library:

I use jsonconverter.bas. Download raw code from here and add to standard module called JsonConverter . You then need to go VBE > Tools > References > Add reference to Microsoft Scripting Runtime. Remove the top Attribute line from the copied code.

I show a partial implementation which makes requests for different categories and products and uses both full and partial string searches. It is a partial implementation in that I read responses into json objects and also print the json strings but do not attempt to access all items within json object. That can be refined upon more detail from you. For demo puposes I access ("result")("data") which gives you the price and name info. Part of the original response json has html as value for accessor ("result")("html"). This has description info e.g.Socket/CPU with motherboard items.

Option Explicit

Public Sub ProductSearches()
    Dim xhr As Object, category As String, items()

    Set xhr = CreateObject("MSXML2.XMLHTTP")
    category = "motherboard"
    items = Array("Gigabyte B450M DS3H", "MSI B450 TOMAHAWK", "random string")

    PrintListings items, xhr, category

    category = "memory"
    items = Array("Corsair Vengeance") 'partial search

     PrintListings items, xhr, category

End Sub

Public Function GetListings(ByVal xhr As Object, ByVal category As String, ByVal item As String) As Object
    Dim json As Object
    With xhr
        .Open "GET", "https://pcpartpicker.com/products/" & category & "/fetch/?xslug=&location=&search=" & item, False
        .setRequestHeader "User-Agent", "Mozilla/5.0"
        .send
        Set json = JsonConverter.ParseJson(.responseText)("result")("data")
        Set GetListings = json
    End With
End Function

Public Sub PrintListings(ByRef items(), ByVal xhr As Object, ByVal category As String)
    'Partially implemented. You need to decide what to do with contents of json object
    Dim json As Object, i As Long
    For i = LBound(items) To UBound(items)
        Set json = GetListings(xhr, category, items(i))
        'Debug.Print Len(JsonConverter.ConvertToJson(json)) ' Len(JsonConverter.ConvertToJson(json)) =2 i.e {} then no results
        Debug.Print JsonConverter.ConvertToJson(json)  'demo purposes only
        'do something with json
    Next
End Sub

Json parsing:

Read about using JsonConverter and parsing json in vba here, here and here.

QHarr
  • 83,427
  • 12
  • 54
  • 101
  • Your answer works as well, and with lightning speed. I'm not sure where in your code it specifies the price (which is needed information). Could you point that out for me please? Also, could you help me take your first category (motherboards) and find other features like number of SATA ports, or USB Headers? These are not listed in the initial table that is generated, but after clicking on a specific motherboard the features of the motherboard are listed on the left. My final intent is to build such a table in Excel so that 20+ MB's can be compared easily. – awsmitty Oct 01 '19 at 15:00
  • Price is within the info retrieved by Set json = JsonConverter.ParseJson(.responseText)("result")("data") ......the number has to be /100 to get as on page.The other info I believe is in ("result")("html"), You have to parse it out of that. I will update the answer for you today or tomorrow most likely. – QHarr Oct 01 '19 at 15:03
  • What does the 20+ MB relate to? – QHarr Oct 01 '19 at 15:04
  • 20+ motherboards - I was running out of characters that can be used in a comment, lol. Thank you very much for your help. I'm new t this stuff. I will be studying your code and references for some time. – awsmitty Oct 01 '19 at 15:32