Issue getting information using XPath method in Selenium VBA Excel - html

I am struggling getting the information of the name of a person in a website. Here is what I see when I inspect the page :
As you can see, I highlighted the line that I think is causing me some trouble. I don't know why when I select the line " User : Piquemal Bruno" (second line starting from the bottom) and I create an XPath I only have this :
/html/body/table/tbody/tr/td[2]/table/tbody/tr1/td[2]/b
I don't know why I don't have the previous information, as if it doesn't exists. Normally I should have this : /html/frameset/frame/document/html/body/table/tbody/tr/td[2]/table/tbody/tr1/td[2]/b
But something is blocking me from having the whole path.
Sub GetUserInfo()
Dim k As WebElements
Dim h As WebElement
Dim FindBy As New Selenium.By
EdgeWeb.get """"INTERNET PAGE THAT I WANT""""
Set h = EdgeWeb.FindElementByName("banner")
Set k = EdgeWeb.FindElements(FindBy.XPath("/html/frameset/frame/document/html/body/table/tbody/tr/td[2]/table/tbody/tr[1]/td[2]/b"))
Debug.Print k.Count
End Sub
Here k is empty but h sees an element. Which is normal because the banner is just before the #document tag. It really looks like the #document tag is cutting the path.
I tried many other methods like FindElementByTag or FindElementByCSS but nothing works.
Hope you can help me and thank you beforehand.

Related

Obtain Innertext from Web Element with Variable Path - Selenium

I have a VBA macro that I'm running in Excel 2016. The macro brings back information from the internet using Chrome and Selenium WebDriver. The macro iterates through several similar webpages, but some pages have a few more or less lines than others. Hence, the XPath to the innertext I'm interested in varies slightly from page to page. Here is a snippet of the source code for the element, it is the "242" that I'm trying to locate and extract.
<div ng-repeat="squarefootage in improvement.SquareFootage" class="ng-scope">
<div>
<span class="labelSquareFootage ng-binding">ATTACHED GARAGE AREA </span><span class="result ng-binding">242</span>
</div>
</div>
As a workaround I'm just grabbing the entire source code for the page and then parsing it with INSTR to find what I'm looking for. I was wondering if there was a more elegant method to find an element with a variable path? Is there something in WebDriver that would work like
WDriver.FindElementbyInnerHTML
?
Here is a link to the website, you can look at a few different addresses and see how the path changes from page (address) to page (next address).
You could gather all nodes with matching class and loop until desired garage text found then take the nextSibling
Public Sub Demo()
'Your code to get to page and enter address and search, open heading, then....
Dim html As MSHTML.HTMLDocument
Set html = New MSHTML.HTMLDocument
html.body.innerHTML = WDriver.PageSource
Dim nodes As Object, node As Object, i As Long
Set nodes = html.querySelectorAll(".labelSquareFootage")
For i = 0 To nodes.Length - 1
Set node = nodes.Item(i)
If InStr(node.innerText, "ATTACHED GARAGE AREA") > 0 Then
Debug.Print node.NextSibling.innerText
Exit For
End If
Next i
End Sub
For xpath, you could try
//*[text()[contains(.,'ATTACHED GARAGE AREA')]]/following-sibling::span
if the desired value is the next span node. This searches for the desired text in the .innerText then takes the nextSibling span.
CSS selectors

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

Retrieving the text between the <div> with VBA

I am trying to get a text string from inside a div on a webpage, but I can't seem to figure out how it is stored in the element.
Set eleval = objIE.Document.getElementsByClassName("outputValue")(0)
Debug.Print (eleval.innerText)
I have tried this and variations thereof, but my string just reads as "".
I mainly need help on how is this type of data is referenced in VBA.
<div class="outputValue">"text data that I want"</div>
Here is a screenshot of the page in question, I cannot give a link since it requires a company login to reach.
With .querySelector method, make sure page if fully loaded before attempting.
Example delays can be added with Application.Wait Now + TimeSerial(h,m,s)
Set eleval = objIE.Document.querySelector("div[class="outputValue"]")
Debug.Print eleval.innerText
If it is the first of its className on the page you could also use:
Set eleval = objIE.Document.querySelector(".outputValue")
If there is more than one and it is at a later index you can use
Set eleval = objIE.Document.querySelectorAll(".outputValue")
And then access items from the nodeList returned with
Debug.Print eleval.Item(0).innerText 'or replace 0 with the appropriate index.
Dim elaval as Variant
elaval = Trim(Doc.getElementsByTagName("div")(X).innerText)
msgbox elaval
Where X is the instance of your class div

Get value from HTML element for display in Textbox

I have tried adapting a handful of solutions Ive found on here and cannot get any to work. Most recently,
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim Web As New HtmlAgilityPack.HtmlWeb
Dim Doc As New HtmlAgilityPack.HtmlDocument
Doc = Web.Load("http://MyWebSearch.com/s/" + TextBox1.Text)
For Each table As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(<div class="inline-block"></div>)
Textbox5.text(table.InnerText)
Next
End Sub
I am trying to conduct a search with a fixed address where + textbox1 contains the search item. I need to return the value from one element on the page into Textbox5 after search is conducted. I cant for the life of me get this to work. Ive tried obtaining the xpath but that failed also. What am I doing wrong?
The web page is rbx.trade/s/"username"
I am trying to return the users "Rap" and display in textbox5
You're searching for the class of an element. You probably want to search for the ID instead.
For Each table As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(<div id="elementID"></div>)
Textbox5.text(table.InnerText)
Next
Or if you indeed mean to be using the class, store each value in an array or append to the text box instead of storing it directly. Say there are 8 element with that class. Doing it the way you are will always store the value of the 8th skimmed element with that class name.

how to extract this code using vba - i need to click on next button

Just an FYI... I am using UserForm1.WebBrowser1.document.CurrentWindow.execScript("return doSubmit( this.form )").Click code to extract
I need to click on next button but element ID is not available; below is the HTML code
<input class="saveButton" onclick="return doSubmit( this.form )" type="BUTTON" value="Next">
i tried using below vba code but this does'nt work for me
Dim CurrentWindow As HTMLWindowProxy: Set CurrentWindow = UserForm1.WebBrowser1.document.parentWindow
Call CurrentWindow.execScript("return doSubmit( this.form )")
Please let me know if any further thing required
So. Clicking something without an ID can be done, you just have to know how to FIND what you're looking for. Normally, I'd recommend clicking on the element by innertext as a good backup.
I know you can't probably share the webpage, so I won't ask. But, what is the tag assigned to this element? "td","a","div","input" etc etc.
You can finding the element using this loop.
Dim Cnt As Variant
Dim oCell As Object
Cnt = 0 '
With oie.document.all
For Each oCell In .tags("a") 'This will change according to html tagging of element
If oCell.value = "Next" Then 'If this "Next" value is unique.
oie.document.all.Item(cnt).click 'If doesn't trigger try nextline
oie.document.all.item(cnt).fireevent ("onclick")
Exit For
End If
Cnt = Cnt + 1
Next oCell
End With
Set oCell = Nothing
Now, in order to get this to work. Enable the "Microsoft Internet Controls" reference library.
A couple things that might have to change depending on the HTML structure.
oie.document.all.item 'This might change to something like oie.document.body. or oie.document.forms(0).document.all.
Like I said, the "a" needs to be changed to look at every tag assigned to the element in the html.
I hope this points you in the right direction, if you don't want to run the loop everytime the macro runs, you can put this into a function that runs and assigns all of the elements on load. But one thing at a time :)
Hello and thanks for your quick turn around!
Code is not running...
I tried your code as per my requirement and make the necessary changes:
Dim Cnt As Variant
Dim oCell As Object
Cnt = 0
With UserForm1.WebBrowser1.document.all
For Each oCell In .tags("input")
If oCell.Class= "saveButton" Then
UserForm1.WebBrowser1.document.all.Item(Cnt).Click
UserForm1.WebBrowser1.document.all.Item(Cnt).FireEvent ("onclick")
Exit For
End If
Cnt = Cnt + 1
Next oCell
End With
Set oCell = Nothing
End Function
Just an FYI... i am using userform to perform this task.
As you said, we need some unique value so i have 'savebutton' as class and change in code as 'oCell.class'...
Is there any chance to find the 'savebutton' as this is unique?
Thanks a ton!