VBA: Click option on dropdown list from website - html

Am sorry if it may be very simple, I am a newbie, but I have researched a lot without finding how to click this option (XBT/USD) inside the dropdown list:
https://ibb.co/jqf7zk
I only have managed to display the list with the code below, but I don't know how to select XBT/USD because this doesn't have an ID on html source.
Option Explicit
Sub BrowseToSite()
Dim IE As New SHDocVw.InternetExplorer
Dim oSelect As HTMLInputButtonElement
IE.Visible = True
IE.Navigate "https://www.kraken.com/charts"
Do While IE.ReadyState <> READYSTATE_COMPLETE
Loop
IE.Document.getElementById("pairselect-button").Click
End Sub
HTML code according to inspect element:
< a tabindex="-1" class="currpairs" data-pair-text="XBT/USD" data-pair="XBTUSD">XBT/USD</a >
Thanks in advance for your valuable response.

You are almost there. You have found the dropdown menu. All you need to do is clicking XBT/USD. The easiest method that comes to my mind is using getElementsByClassName but you dont have to necessarily use it. You can find them by using xpath or tagname as well.
Well, if you inspect the source you will see there are lots of class="currpairs". If you hover on them, you will see that they belong to each item in dropdown list. XBT/USD is the second item in the list. So the missing part in your code is:
IE.Document.getElementsByClassName("currpairs")(1).Click
Notice we used (1) after getting the class currpairs. This is because counting starts from 0 in list. So (0) represents the first item XBT/EUR, and (1) represents the second item XBT/USD in the list.
Hope this helps.

Related

Internet Explorer click an icon and a button of a specific line of a table

I've asked a similar question two days ago but I know stumble again on a similar problem but somehow different. previous question asked on a related problem
I have a report of many lines with the same structure. I need to click an icon that is on the nth line. That report is structured in cells so I know that my icon is in the first position (column) of that report. After I have click that icon I'll also have to click on a button in the 10th column.
I already know how to access the page in question with that code
Sub click_button_no_hlink()
Dim i As Long
Dim IE As Object
Dim Doc As Object
Dim objElement As Object
Dim objCollection As Object
Set IE = CreateObject("InternetExplorer.Application") 'create IE instance
IE.Visible = True
IE.Navigate "https://apex.xyz.qc.ca/apex/prd1/f?p=135:LOGIN_DESKTOP::::::" ' Adress of web page
While IE.Busy: DoEvents: Wend 'loading page
This first part is easy isn't? And I know how to handle it. Afterward I tried different variation around this but it either do nothing, or I get an error message. Obviously I don't fully understand what I'm doing with the "querySelector" thing…
dim step_target as string
step_target = 2
'identify all the lines of my table containing lines, containing icons
'and button to click on
Set objCollection = IE.document.getElementsByClassName("highlight-row")
i = 0
Do While i < objCollection.Length
'cell 2 is the one containing the step I'm targetting
If objCollection.Item(i).Cells(2).innerText = step_target Then
'that's not doing anything
objCollection.Item(i).Cells(9).Click
'tried many syntax around this with no luck
IE.document.querySelector([objCollection.Item(i).Cells(9)]).FireEvent ("onclick")
End If
i = i + 1
Loop
Here's images of the code of the page
Showing all the lines of the report
Showing all code lines of a particular line
and now the code of that first icon I need to click on (this is where I need help ;-) how can I call that action)
and finally the code of that button I also need to click on
Again, I thank you all in advance, for the time you'll take to help me along this.
you could try attribute selector for first in combination with descendant combinator and a type selector
ie.document.querySelector("[headers='ID_DET_DEM_TRAV_STD'] a").click
you could try attribute selector for second in combination with descendant combinator and input type selector
ie.document.querySelector("[headers='BOUTON1'] input").click
alternative for second is
ie.document.querySelector("[value=Fait]").click
Typically, if you want to select by position e.g. 1 and 10th columns you would use
td:nth-of-type(1)
td:nth-of-type(10)
Though you would also use a tr:nth-of-type(n) to get the right row as well e.g. first row, first col. Then add in any child type selector, for example, that you might need.
ie.document.querySelector("tr:nth-of-type(1) td:nth-of-type(1)")
Child a tag:
ie.document.querySelector("tr:nth-of-type(1) td:nth-of-type(1) a")
Child input tag: would then be:
IE.document.querySelector("tr:nth-of-type(4) td:nth-of-type(10) input").Click

How to click on a <a> element of an <li> of a <ul> using vba?

Here is a piece of code of the HTML page I am working on.
I am trying to programmatically click on the element highlighted in blue in the picture above.
Here is the code I wrote:
Set objIE = New SHDocVw.InternetExplorer
Do While objIE.Busy: DoEvents: Loop
Do Until objIE.readyState = READYSTATE_COMPLETE: DoEvents: Loop
Set IeDoc2 = objIE.Document
Set the_input_elements2 = IeDoc2.getElementsByClassName("parent-item")
For Each input_element2 In the_input_elements2
If input_element2.href = "javascript:directToSearch()" Then
input_element2.Click
Exit For
End If
Next input_element2
How do I click on an element of a ul in HTML using VBA?
When I run this code, nothing happens. No errors but no result.
Here's a couple of ways to refer to the element you're interested in:
'Targeted (if you know exactly at which order the elements appear in the list)
Dim li As HTMLListElement
Set li = IeDoc2.getElementById("accordion-leftmenu") 'get the list item you're interested in...
Debug.Print li.Children(1).innerText '...and access its sub-element in a targeted way
Debug.Print li.getElementsByTagName("a")(1).innerText '...or find all <a></a> elements contained in it and access the one you're interested in, in a targeted way
'Non targeted (you have to search for it)
Dim element As HTMLObjectElement
For Each element In IeDoc2.getElementsByTagName("a") 'loop through all <a></a> elements...
If element.innerText = "Advanced Search" Then '...and find the one you're interested in
Debug.Print element.innerText
End If
Next element
For demonstration purposes the above code just prints the inner text of the element. You can modify it accordingly.
References used: Microsoft HTML Object Library
Also on a side note, please post the actual HTML next time rather than a screenshot of it. It would make it easier for people to help you.
Loop all "a" tags inside the ID of the left menu
IeDoc2.getElementById("accordion-leftmenu").getElementsByTagName("a")
in the loop check if the .innerText is "Advanced Search". click if it is.
Dim IeDoc2 As MSHTML.HTMLDocument
Dim the_input_elements2 As MSHTML.IHTMLElementCollection
Dim input_element2 As MSHTML.IHTMLElement
...
Set the_input_elements2 = IeDoc2.getElementById("accordion-leftmenu").getElementsByTagName("a")
For Each input_element2 In the_input_elements2
If input_element2.innerText = "Advanced Search" Then
input_element2.Click
Exit For
End If
Next input_element2
Edit: Alright, I've tested the code and it works. I did however have to make sure that Two references were checked: "Microsoft HTML Object Library" and "Microsoft Internet Controls".

Extract item price from HTML

I'm struggling to get the price from the following HTML
<span class="pricing__now" itemprop="price">7.99</span>
I'm trying to extract the "7.99" from the above example.
I've tried HTML.getElementsByClassName("pricing__now")(0).innertext
but drawing blank.
Any help, kindly received.
Many thanks in advance.
Ian
It will be easier to give better advice if we can see more HTML and also the URL if possible. Here are some tips:
1) You need to ensure you have the right index
To check you have the right index, right click inspect element the press Ctrl + F to bring up the HTML search box and enter .pricing__now. Check how many matches there are and at which index your desired match is.
2) Ensure the page has loaded with this value when you try to access. So before trying to access, if using IE, ensure you have:
While IE.Busy Or IE.readyState < 4: DoEvents: Wend
after your navigate2 line
3) You can also use combined CSS selectors to be more specific
ie.document.querySelector(".pricing__now[itemprop=price]").innerText

VBA Excel Run time error 438 / getElementbyClassName

I'm a newbie, attempting to web scrape aspect ratio details from the imdb.com website.
I've plundered some code on You Tube and adapted it using inspect element.
The code opens imdb and runs a search by title but returns a Run Time error 438.
Ideally I'd like it to return the html of the top result so I could perform a further click the top result to follow through to the page with tech details from where I could get the aspect ratio information and paste it into a cell.
Unfortunately I get a fail from my Click instruction - haven't even got to the point of extracting the aspect ratio info.
Can anyone see where I've gone wrong?
Many thanks,
Nick
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row = Range("Title").Row And Target.Column = Range("Title").Column Then
Dim ie As New InternetExplorer
ie.Visible = True
ie.navigate "https://www.imdb.com/find?ref_=nv_sr_fn&q=" & Range("Title").Value
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE
Dim doc As HTMLDocument
Set doc = ie.document
Dim sDD As String
doc.getElementsByTagName("a").Click
End If
End Sub
So, addressing your code
You can use a shorter version of Target.Address = Range("Title").Address
You don't want the first a tag element. You want the first search result a tag element.
You can use a CSS selector combination to get the first search result a tag element as shown below.
I use a CSS selector combination of .result_text a to target elements within parent class result_text with tag a. The . is a class selector.
This combination is known as a descendant selector.
Using search term in sheet of Red October this is what the CSS query first result is:
It is a relative link with base string https://www.imdb.com.
Applying via querySelector method means only first matched result is returned i.e. the top result.
VBA:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Address = Range("Title").Address Then
Dim ie As New InternetExplorer
ie.Visible = True
ie.navigate "https://www.imdb.com/find?ref_=nv_sr_fn&q=" & Range("Title").value
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE
Dim doc As HTMLDocument
Set doc = ie.document
doc.querySelector(".result_text a").Click
'other code
End If
Application.EnableEvents = True
End Sub
This line of code:
doc.getElementsByTagName("a")
gives you the Collection of Hyperlinks in your HTML Document. That is, it gives you ALL the elements that match your given criteria, if any are available.
However, some issues may arrive:
There may not be any hyperlinks available - So there are no elements to click on.
You are not referencing any element to click. If you want the first one in the collection of found items, you could go with the index, as suggested. Else, you might look for another clicking criteria (such as what is its text or another given attribute).
Even still, a found element might not be clickable by your browser, if, for example, it is shadowed by another element.

VBA to click a dynamic href

I'm trying to click a link on a website with the tag:
<a href="/dbget-bin/www_bget?dr:D01441:>D01441</a>
However, I'm doing this after searching for a unique item (I have an array of >9000 unique items), and the "D01441" part is different for each item, and I don't know in advance what it will be for each. The following code is in a loop that goes through each item and searches for it one at a time. After searching, I would like to click on a link that appears (the code above) and do more things on that next web page.
Dim IE As Object
Dim ele As Object
Set IE = CreateObject("InternetExplorer.Application")
...
For Each ele In IE.document.getElementsByTagName("a")
If ele.Href = "/dbget-bin/www_bget?dr:D01441" Then
ele.Click
Exit For
End If
Next
The above code doesn't work and I'm not sure why. But once I get it to work, I don't know how to modify the "D01441" part so that I can click on any searched item's link. Here's more html around the link I want:
<tbody>
<tr> ... </tr>
<tr>
<td class = "data1">
<a href = "/dbget-bin/www_bget?dr:D01441:>D01441</a>
</td>
<td class = "data1">..</td>
<td class = "data1">..</td>
...
EDIT: To try to deal with the changing "D01441", I tried using InStr but it doesn't work either:
For Each ele In IE.document.getElementsByTagName("a")
If InStr(ele.Href, "/dbget-bin/www_bget?dr:") = 1 Then
MsgBox "There"
ele.Click
Exit For
End If
Next
CSS selectors:
Try using a CSS selector combination applied via querySelector method of document to target the common start part of the href.
Applying the selector combination:
IE.document.querySelector("a[href^='/dbget-bin/www_bget?dr:']").Click
Understanding the selector combination:
This uses a CSS selector combination to target the element with:
a[href^='/dbget-bin/www_bget?dr:']
This says element with a tag having attribute href whose value starts with
'/dbget-bin/www_bget?dr:' . The ^ means starts with.
Query in action:
Here is the selector in action on your HTML sample:
Side note:
If you have multiple elements with a tags and an href that starts with /dbget-bin/www_bget?dr:, it will match the first one, in most instances. If that is the case seeing more HTML would help. I think there are a few problems with that HTML sample because in theory a more selective CSS query might be .data1 a[href^='/dbget-bin/www_bget?dr:'], so as to include the parent element class of data1, "." being a class selector.
#QHarr answer is the elegant and best solution, but...
To address your issue of getting the part number from the href, you can use the InStr like this
For Each ele In IE.document.getElementsByTagName("a")
Dim partNumber As String
Dim colonPosition As Long
colonPosition = InStr(1, ele.Href, ":", vbTextCompare)
If colonPosition > 0 Then
partNumber = Right$(ele.Href, Len(ele.Href) - colonPosition)
Debug.Print partNumber
End If
Next ele