Perform click on href link in VB.NET - html

How can I perform a click on this link using VB.NET webbrowser?
<li class="r">Denunciar este perfil</li>
I've tried something like this, but didn't work:
Dim elements As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("a")
For Each pElem As HtmlElement In elements
If (pElem.OuterHtml.Contains("profile.php")) Then
pElem.InvokeMember("click")
End If
Next

I solved it by putting the webbrowser.navigate on a different timer and adding an interval.

Related

vb.net selenium select element from dropdown

I don't know much about selenium. I'm trying to select an element from a dropdown to click on it, but vb.net doesn't find this element. or it finds another element that has the same class name.
It is the following dropdown menu on aliexpress.
And this is the code I have written so far....
Dim chromeDService = ChromeDriverService.CreateDefaultService() 'hides command prompt
chromeDService.HideCommandPromptWindow = True
Dim opt As New ChromeOptions()
opt.AddArguments("headless") 'prevents driver from opening a new window
Dim driver As IWebDriver = New ChromeDriver(chromeDService, opt)
driver.Navigate.GoToUrl(URL_AS_STRING) 'the URL as String
driver.Manage.Timeouts().ImplicitWait = TimeSpan.FromSeconds(2)
If driver.FindElement(By.ClassName("switcher-info")).FindElement(By.ClassName("currency")).Text = "USD" Then
Console.WriteLine("changing currency...")
'driver.FindElement(By.LinkText("EUR")).Click()
driver.FindElement(By.ClassName("switcher-info")).Click()
driver.Manage.Timeouts().ImplicitWait = TimeSpan.FromSeconds(1)
Dim element As IWebElement = driver.FindElement(By.ClassName("switcher-common")).FindElement(By.ClassName("switcher-currency-c")).FindElement(By.ClassName("select-item"))
Console.WriteLine(element.GetAttribute("innerText"))
End If
My question now is, how can I select and click on the element with the currency?
I intend to click on it so that it selects another currency.
Of course I could also make everything less complicated and include an exchange API. But the real rates do not match with the prices
You can do it simply by clicking the corresponding elements one by one exactly what the real user does via the GUI.
I see Selenium in VBA doesn't have explicit waits, so only the implicitly wait can be used as you already defined it driver.Manage.Timeouts().ImplicitWait = TimeSpan.FromSeconds(2) and since it was defined we do not need to define it anymore until we want to define it for some other value.
This is what I wrote.
I hope this should work:
If driver.findElementByXPath("//a[#id='switcher-info']//span[#class='currency']").Text = "USD" Then
Console.WriteLine("changing currency...")
driver.findElementByXPath("//span[#class='currency']").Click()
driver.findElementByCssSelector(".switcher-currency .select-item").Click()
driver.findElementByXPath("//a[#data-currency='EUR']").Click()
driver.findElementByXPath("//button[#data-role="save"]").Click()
In case there are pop-ups appearing on the aliexpress home screen disturbing the above code run try do the following:
If driver.FindElementsByXPath("//div[contains(text(),'Don')]").Count Then
driver.FindElementsByXPath("//div[contains(text(),'Don')]").Click()
If driver.FindElementsByXPath("//img[#class='btn-close']").Count Then
driver.FindElementsByXPath("//img[#class='btn-close']").Click()
If driver.FindElementsByXPath("//img[#class='close-btn']").Count Then
driver.FindElementsByXPath("//img[#class='close-btn']").Click()
And only after that run the code above so that the whole code will be something like this:
If driver.FindElementsByXPath("//div[contains(text(),'Don')]").Count Then
driver.FindElementsByXPath("//div[contains(text(),'Don')]").Click()
If driver.FindElementsByXPath("//img[#class='btn-close']").Count Then
driver.FindElementsByXPath("//img[#class='btn-close']").Click()
If driver.FindElementsByXPath("//img[#class='close-btn']").Count Then
driver.FindElementsByXPath("//img[#class='close-btn']").Click()
If driver.findElementByXPath("//a[#id='switcher-info']//span[#class='currency']").Text = "USD" Then
Console.WriteLine("changing currency...")
driver.findElementByXPath("//span[#class='currency']").Click()
driver.findElementByCssSelector(".switcher-currency .select-item").Click()
driver.findElementByXPath("//a[#data-currency='EUR']").Click()
driver.findElementByXPath("//button[#data-role="save"]").Click()
You need to close all the popups before interacting with any element on the page. Try this:-
driver.findElementByXPath(".//div[contains(text(),'notifications')]//following::img").Click()
driver.findElementByXPath(".//img[#class='btn-close']").Click()
driver.findElementByXPath(".//a[#id='switcher-info']").Click()
driver.findElementByXPath(".//div[#data-role='switch-currency']").Click()
driver.findElementByXPath(".//li/a[#data-currency='EUR']").Click()
I think, that the ClassName-Selector ist not the right one.
It is not a real dropdown like <select> but a dropdown-menue of links.
the Link for US-Dollar looks like this:
<span class="select-item chang-border" data-spm-anchor-id="a2g0o.home.1000001.i0.650c2145pgspp2">
<a rel="nofollow" href="javascript:;" data-spm-anchor-id="a2g0o.home.1000001.40">USD ( US Dollar )</a>
</span>
You can use the FindElementByCssSelector to access this link:
driver.FindElementByCssSelector("[data-spm-anchor-id=a2g0o.home.1000001.40]").Click()
For EURO it is:
driver.FindElementByCssSelector("[data-spm-anchor-id=a2g0o.home.1000001.43]").Click()

"Clicking" anchor element to navigate to next page VBA

I'm creating an automation that will go through almost 110 pages with VBA. These pages have identical layout. I would need to go from one page to another automatically by "clicking" next button. At the very end of every page, there is a "button" (list anchor) that says "Next page". Problem is that the source code does not contain ID which would make it easy to refer with:
getElementById("id").Click
I open browser. That works fine. and I've tried something like this but it doesn't work:
Dim ieDoc As Object
Dim links As Object
Dim link As Object
Set ieDoc = ieApp.Document
Set links = ieDoc.Anchors
For Each link In links
If link.innerHTML = "innerHTML" Then
link.Click
Exit For
End If
Next link
I have tried almost everything I could find from stackoverflow but nothing worked for my needs.
THis is the source code of the "Next button" that I'm trying to click:
<li class="pager-next"><a title="Next page" href="/fi/tyosuhde- edut/kayttokohdehakupage=1&service_type=lunch&keywords=&city=&service=&service_areas=&payment_method=&municipality=&service_coupon_code=&items_per_page=50">seuraava ›</a></li>
I quess the problem is that the ClassName is in "li" and not in "a"?
Could some help me??
EDIT
Found a workaround!!:
Set pages = doc.getElementsByTagName("a")
For Each page In pages
If (page.getAttribute("title") = "Siirry seuraavalle sivulle") Then
page.Click
End If
Next page
You will need to keep reseting the html document with each refresh.
After a refresh try
ieApp.document.querySelector("a[title=""Next page""]").Click
CSS Selector
More info about CSS Selectors: CSS selectors
EDIT:
In your case the actual HTML selector is
appIE.doc.querySelector("a[title = ""Siirry seuraavalle sivulle""]").Click
Note there is no space after the "a" and you will need to leave enough time between clicks to allow the new page to load.

VB WebBrowser click button

On this web page: https://www.youtube.com/upload_defaults
I would like to call a function and then click the "Save" button in the upper right corner.
There is no ID or Name. How can I do this?
You can use the distinct CSS class of the button: account-save-button
In VB.NET, use HtmlDocument.GetElementsByTagName like this:
Private Sub ClickSaveButton()
If (WebBrowser1.Document IsNot Nothing) Then
Dim Elems As HtmlElementCollection
Dim WebOC as WebBrowser = WebBrowser1
Elems = WebOC.Document.GetElementsByTagName("BUTTON")
For Each elem As HtmlElement In Elems
Dim CssClass As String = elem.GetAttribute("classname")
If ((CssClass IsNot Nothing) And (CssClass.Length <> 0)) Then
If CssClass.ToLower().Contains("account-save-button") Then
elem.InvokeMember("click");
Exit For
End If
End If
Next
End If
End Sub
To verify it with just a web browser, try this from your browser's developer console; it works because youtube uses jQuery:
$(".account-save-button").click();
Or pure javascript: document.getElementsByClassName('account-save-button')[0].click();
For reference, here is the button's markup:
<button class="yt-uix-button yt-uix-button-size-default yt-uix-button-primary account-save-button account-action-button" type="submit" onclick=";return true;"><span class="yt-uix-button-content">Save</span></button>
Other thoughts:
This is basically screen scraping, which can lead to brittle applications when the page changes, etc.
Google may already have a web service API for what you are trying to accomplish.. but that's a good question:
What exactly are you trying to accomplish? What is the context? We may be able to suggest a better alternate solution.
Update:
I checked the Youtube API Reference, but I don't see anything for setting preferences for upload defaults.

How to parse a html page, vb.net form

how can I parse this html code:
163 Punti<
I want to parse "163 Punti". I've tried to search on google but I didn't found nothing..
Someone could help me? Thanx
The element doesn't have an ID. So you can't get the element by using GetElementById method (which is the surest way to identify an element). However you can use other methods.
Dim allLinks As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("A")
For Each link As HtmlElement In allLinks
If link.GetAttribute("href") = "http://member.20dollars2surf.com/points.php" Then
Dim linkText As String = link.InnerHtml
MessageBox.Show(linkText)
End If
Next
The above code will work properly only if there is only one link on the page with that URL. Otherwise you will need to further customize this code.

GetElementById/GetElementsByTagName not finding element

Bear in mind that I know only a bit about HTML:
There is a site I'm trying to interact with using a WebBrowser. The site has a textarea element as follows:
<textarea name="ctl00$ContentPlaceHolderMain$txtCallDesc" rows="2" cols="20" id="ctl00_ContentPlaceHolderMain_txtCallDesc" tabindex="205" style="width: 100%; height: 80px; font-size: 8pt"></textarea>
From what I've read, the generated ID of the textarea signifies that it's placed inside another form of some sort, and I'm not sure if this is where I'm running into my problem.
Once the page has loaded, I have something like the following in a button:
Dim theCol As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("textarea")
For Each curElement As HtmlElement In theCol
ListBox1.Items.Add(curElement.TagName)
Next
Nothing populates in the list. I've also tried using the ID of the text box gathered by the 'inspect element' feature of Chrome:
Dim value As HtmlElement = WebBrowser1.Document.GetElementById("ctl00_ContentPlaceHolderMain_txtCallDesc")
MsgBox(value.GetAttribute("value"))
No matter what I do, I can't seem to get the program to recognize that there ARE textarea elements in the document. The source for the page is far to long to spam everyone with here, but is there anything I'm missing that I should be looking out for? Perhaps needing to get another element first, then search that for elements within it?
Edit:
The element I'm trying to get seems to be within an iFrame, but it looks like it's from the same domain so the same origin policy shouldn't come into play, should it?
<iframe id="mainFrame" width="100%" height="100%" frameborder="0" class="mainFrame" name="Main" src="/Calls/OpenCalls.aspx">
Using the code shown in Get Iframe HTML:
For i = 0 To WebBrowser1.Document.Window.Frames.Count - 1
Dim frameDoc = WebBrowser1.Document.Window.Frames(i)
Dim theCol = frameDoc.Document.GetElementsByTagName("textarea")
For Each curElement As HtmlElement In theCol
ListBox1.Items.Add(String.Format("TagName: {0} Id:{1}", curElement.TagName, curElement.Id))
Next
Next
The essential part being the use of WebBrowser1.Document.Window.Frames.
You can't reference elements inside an iframe directly since they are inside another document. So first get a reference to the document element inside the iframe and then you can query it the same way.
Dim frameDoc = WebBrowser1.Document.GetElementById("mainFrame").DomElement.contentWindow.Docume‌​nt
And the rest you already know...
Dim theCol = frameDoc.GetElementsByTagName("textarea")
For Each curElement In theCol
ListBox1.Items.Add(curElement.TagName)
Next