Trying to click on the first youtube video link using VBA - vba

My end goal is to dynamically get music playing. I figured that navigating to youtube, searching for the string, and playing the first video suggested is a good way of getting this done. Pandora and Spotify both have hoops that you need to jump through before playing.
Sub YouTube()
So we open up IE, and navigate to the website
Set objIE = CreateObject("InternetExplorer.Application")
WebSite = "www.youtube.com"
With objIE
.Visible = True
.navigate WebSite
Do While .Busy Or .readyState <> 4
DoEvents
Loop
So far, so good. Next we find the search box, and make a search. Dummy text entered for the sake of easy coding, it'll eventually be an argument passed to the function.
Set Element = .document.getelementsbyname("search_query")
Element.Item(0).Value = "portal 2 walkthrough video"
.document.forms(1).submit
Do While .Busy Or .readyState <> 4
DoEvents
Loop
Great, we made it! Now for the part I'm struggling on - clicking on the first video.
I've tried a few different things - I can't seem to find a name, and I keep getting a "Permission denied" when I try to do something like this, as suggested by other users. See: How do I click a link on a web page using Excel VBA?
I've decided not to programatically control the mouse and click, since the location I need to click on keeps dynamically changing.
I'm not very good at interfacing with IE while using VBA, so at this point I'm stumped.
Set Element2 = .document.getelementsbytagname("a")
For Each i In Element2
If i.classname = "yt-lockup-content" Then
i.Click
Exit For
Else
'do nothing
End If
Next i
End With
End Sub
I've also tried:
.document.getelementsbyclassname("yt-lockup-content").Click
But that's not a supported method
.document.querySelector("a[href=javascript:browserPrint();]").Click
Gets a permission denied

The following using a loop to wait until results are present. I try to keep much of the selectors used to target elements fairly loose to allow for changes in html
Option Explicit
Public Sub test()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
With ie
.Visible = True
.Navigate2 "https://www.youtube.com/"
While .Busy Or .readyState <> 4: DoEvents: Wend
.document.querySelector("[title=Search]").Value = "portal 2 walkthrough video"
.document.querySelectorAll("form").item(1).submit
While .Busy Or .readyState <> 4: DoEvents: Wend
Do
Loop While .document.querySelectorAll("#results").Length = 0
.document.querySelector("#results h3 a").Click
While .Busy Or .readyState <> 4: DoEvents: Wend
Stop '<Delete me later
End With
End Sub

Another method is to use the querySelector() method. You know you want the element with the tag a, because the a tag means that it contains a link.
Then combine the above with the class name that you're looking for, yt-lockup-title, and you get this single line:
.querySelector("h3.yt-lockup-title").Click
Take note that this is a method of the document object. So objIE.Document.querySelector()
Don't want to use the .Click method? You can also grab the url from the href attribute and just perform a navigation:
Dim vidURL As String
vidURL = objIE.document.querySelector("h3.yt-lockup-title > a").getAttribute("href")
objIE.navigate "https://www.youtube.com" & vidURL
However, in the method you attempted with using
.document.getelementsbyclassname("yt-lockup-content").Click
the getElementsByClassName() function returns a collection of elements. Because of this, you would need to append the index number of the element you are wanting, which would very likely be the first element (since you want the first video).
One of the two lines would be what you're looking for:
.document.getelementsbyclassname("yt-lockup-content")(0).Click
' - OR -
.document.getelementsbyclassname("yt-lockup-content").Item(0).Click
They both do and mean the same thing.

I have changed a element to span element and it worked. Code below:
Sub YouTube()
Set objIE = CreateObject("InternetExplorer.Application")
WebSite = "www.youtube.com"
With objIE
.Visible = True
.navigate WebSite
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
Set Element = .document.getelementsbyname("search_query")
Element.Item(0).Value = "portal 2 walkthrough video"
.document.forms(1).submit
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
Set Element2 = .document.getelementsbytagname("span")
For Each i In Element2
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
If i.classname = "yt-thumb-simple" Then
i.Click
Exit For
Else
'do nothing
End If
Next i
End With
End Sub

Related

VBA- wanted to click element which has multiple frames

With the previous question's answer I stepped ahead however still stuck on one point where I wanted to click the element but it seems it has 2 frames and thats the reason when I am running code its giving error that element not found, please check attachment and below code and advise.
Sub activeBexIE_Final()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'On Error Resume Next
Dim Perm_bot As New Selenium.IEDriver
Perm_bot.Get "official link"
Perm_bot.Wait 2000
Perm_bot.FindElementById("logonuidfield").SendKeys "XYZ"
Perm_bot.SendKeys Perm_bot.Keys.Tab
Perm_bot.SendKeys "PQR"
Perm_bot.SendKeys Perm_bot.Keys.Enter
Perm_bot.Wait 40000
Perm_bot.switchToFrame
Perm_bot.FindElementById("iframe_Roundtrip_9223372036563636042")
Perm_bot.FindElementById("BUTTON_OPEN_SAVE_btn1_acButton").SendKeys
Perm_bot.Keys.Enter
Perm_bot.Wait 30000' *till here I am sucessful- Opening Url-login-click on
"Open" option*
*'from here I am unable to move further, pls check attachment"select
layout" like how I wanted to select and also check the attachment "frame"
and "element" which is having the HTML details, not sure if this particular
element has 2 element, if yes then how I should write the script and after
this I wanted to do tab 7 times and then enter, kindly help for further
script, thanks in advance
'Perm_bot.switchToFrame Perm_bot.FindElementById("urPopupOuter0")
Perm_bot.switchToFrame Perm_bot.FindElementById("urPopupInner0")
Perm_bot.FindElementById("LOAD_state_tigen4_tlv1_list_unid6_tv").Click
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{ENTER}"
Perm_bot.Wait 10000
Application.DisplayAlerts = True
Application.ScreenUpdating = True
'perm_dot.Quit
'Set perm_dot = Nothing
End Sub
Select Layout
FrameElement
I believe your concern is your iframes are having similar attributes and you have to switch to each one of it before tabing 7 times.
Approach would be
Just like getting all windows handles and then loop you can use common xpath for iframe for e.g
findelements(By.Xpath("//iframes))
this will return iframe elements and then you can use loop and traverse and use
SwitchToFrame().
If your webpage is containing multiple frames and you need to perform an action on each frame too then I suggest trying to create an object for those frames and assign it to the 'document' object and then try to perform the action on each frame.
Sub demo()
Dim URL As String
Dim IE, doc1, doc2 As Object
Dim frame1 As HTMLFrameElement
Dim frame2 As HTMLFrameElement
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "D:\Tests\parent.html"
IE.Navigate URL
Do While IE.ReadyState = 4: DoEvents: Loop 'Do While
Do Until IE.ReadyState = 4: DoEvents: Loop 'Do Until
Set frame1 = IE.document.getElementByID("urpopupouter0")
Set frame2 = IE.document.getElementByID("urpopupinner0")
Set doc1 = frame1.contentWindow.document
Set doc2 = frame2.contentWindow.document
IE.document.getElementByID("btn1").Click
doc1.getElementByID("btn1").Click
doc2.getElementByID("btn1").Click
Set IE = Nothing
End Sub
I tested the above code on my side and it works fine with the multiple frames on a webpage.
Test result:
VBA code is clicking the button on each frame and on the parent web page which changes the forecolor of the button to red.
Further, you can try to modify the code as per your own requirements.

Return Address from Google term search to excel using VBA

I am familiar with StackOverflow but have just recently signed up. I am trying to search a Hotel on google and return the address in Excel using VBA. Below is a photo of what Information I am trying to return from Google. From my research, I was able to find a VBA that allowed me to return the Results stats.
Would it be possible to modify my code and return the box at the top of my google search?
I would really appreciate your help! Below is the VBA I am using to return search results.
Sample Image - Red Roof Inn & Address
Sub SearchGoogle()
Dim ie As Object
Dim form As Variant
Dim button As Variant
Dim LR As Integer
Dim var As String
Dim var1 As Object
LR = Cells(Rows.Count, 1).End(xlUp).Row
For x = 2 To LR
var = Cells(x, 1).Value
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
With ie
.Visible = True
.navigate "http://www.google.co.in"
While Not .readyState = READYSTATE_COMPLETE
Wend
End With
'Wait some to time for loading the page
While ie.Busy
DoEvents
Wend
Application.Wait (Now + TimeValue("0:00:02"))
ie.document.getElementById("lst-ib").Value = var
'Here we are clicking on search Button
Set form = ie.document.getElementsByTagName("form")
Application.Wait (Now + TimeValue("0:00:02"))
Set button = form(0).onsubmit
form(0).submit
'wait for page to load
While ie.Busy
DoEvents
Wend
Application.Wait (Now + TimeValue("0:00:02"))
Set var1 = ie.document.getElementById("resultStats")
Cells(x, 2).Value = var1.innerText
ie.Quit
Set ie = Nothing
Next x
End Sub
Right now your code loads the page and then loads the value of the resultStats element.
So the section of your code that you will need to alter is:
Set var1 = ie.document.getElementById("resultStats")
Cells(x, 2).Value = var1.innerText
The first step to your problem is to understand the DOM of the HTML page you are attempting to use, in this case Google. I would suggest using a browser to navigate the DOM as it would give you a good idea of what the whole page is doing.
If you are aiming to do this on a macro basis you will need a path through the DOM that will always take you where you want to go. I would suggest having two pages with different searches open so that you can check you hypothesis as you go.
For example the boxes that you refer to seem to be located in a class called kp-header from knowing this you can build out your path through the DOM to return the text value displayed on screen. Again you will need to do your own investigations to find the best stating point for your search as kp-header was just the first potently helpful result I could find.
Although please note that depending on the speed you are loading these webpages you may hit a limit from google as they discourage scraping. What would be a better option to avoid these limits and to avoid yourself having to investigate all of google's DOM would be to try and incorporate one of google's API's

Click on picture or link behind it

Hi I have macro which supposed to click on button on web page..problem is there is no ID behind just this code. Its intranet web page.
Begining of my code
Set IE = New InternetExplorerMedium
IE.Navigate = "some website"
While IE.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend
IE.Visible = True
IE.document.getElementById("CategoryCombo").Value = "78"
IE.document.getElementById("CategoryCombo").FireEvent ("onchange")
'~~> wait until element is present on web page
Do
Set ieobj = Nothing
On Error Resume Next
Set ieobj = IE.document.getElementById("text1265")
DoEvents
Loop Until Not ieobj Is Nothing
'~~> search box
IE.document.getElementById("text1265").Value = "some value"
'~~> button click example
IE.document.getElementById("subBtn").Click
Part of website code
<a title="View document" href="javascript:FSResults_fsopenWindow('index.fsp?pn=DOLViewDocument&d=78&q=78-17158635-1&o=78-17158635-1&p=DOCUMENT_NAME#ensureVisible')" onclick="fsCancelEvent(event)"><img border="0" alt="View document" align="absmiddle" src="Images/DocTypes/PDF.gif"></a>
I tried
IE.document.getElementByTitle("View document").FireEvent ("onclick")
I also tried
IE.document.getElementByTagName("a").FireEvent ("onclick")
Thank you
I also tried
IE.document.getElementByTagName("a").FireEvent ("onclick")
This should work for you, but you are missing something. You need to specify which <a> tag you are looking for, so .getElementsByTagName("a") turns into .getElementsByTagName("a")(i), where i is the index of the tag you are looking for (you get the index by counting in order every <a> tag in the HTML, starting from 0).
The index is needed because .getElementsByTagName("tagName") returns an array, not a single value.
You could have used CSS selectors.
For example, an attribute selector
ie.document.querySelector("[title='View document']").Click
Or same thing to target href by its value
ie.document.querySelector("[href*=fsopenWindow]").Click
The last one looks for href containing 'fsopenWindow'
Both of these avoid looping over collections of elements and use CSS so are faster.
In the end I came up with this. Thank you for help Nicholas Kemp, your answer send me to right direction
Set elements = IE.document.getElementsByTagName("a")
For Each element In elements
If Left(element, 33) = "javascript:FSResults_fsopenWindow" Then
Debug.Print element
IE.Navigate element
End If
Next

Excel VBA loop to input data in webpage

I have gone through many articles and able to input data in to webpage from excel. Now I am trying to use a loop because I have to entry data for 10 to 50 times in the same page.
Here is the code
Sub vfcp()
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Top = 100
objIE.Left = 100
objIE.Width = 800
objIE.Height = 800
objIE.AddressBar = 1
objIE.StatusBar = 1
objIE.Toolbar = 1
objIE.Visible = True
Dim Input
Range("A2").Select
objIE.Navigate ("https://www.askebsa.dol.gov/VFCPCalculator/WebCalculator.aspx")
Do Until Selection.Offset(0, 0).Value = ""
If objIE.ReadyState = 4 Then
Input = Selection.Offset(0, 2).Value
objIE.document.GetElementByID("_ctl0_MainContent_txtPrincipal").Value = Input
objIE.document.GetElementByID("_ctl0_MainContent_cmdCalculate").Click
Selection.Offset(1, 0).Select
End If
Loop
End Sub
The problems in this code is, I have a list of 10 date. the loop inputs the last date of the list. I am trying to input the first date and click submit, then wait for the page to load and input the second date, and stop the loop if there is an empty cell.
Where is the code to enter the dates? You cannot click without them.
"then wait for the page to load and input the second date"
you can achieve this by inserting the following between your End If and Loop lines.
'Allows IE to load
While objIE.ReadyState <> 4
DoEvents
Wend
This shouldn't be too hard. I went to that URL, hit F12 to see the code behind the site, and started searching for the appropriate ID names ('Principal:', 'Loss Date:', etc). That's about it. Run the script to see a working version. Oh, yeah, set a reference to 'Microsoft Internet Controls' before you run the code.
Sub TryThis()
Dim ie As SHDocVw.InternetExplorer
Set ie = New SHDocVw.InternetExplorer
ie.Visible = True
ie.Navigate "https://www.askebsa.dol.gov/VFCPCalculator/WebCalculator.aspx"
Do
DoEvents
Loop Until ie.readystate = 4
'ie READYSTATE has 5 different status codes, here we are using status 4:
Call ie.Document.GetElementByID("_ctl0_MainContent_txtPrincipal").SetAttribute("value", "100000")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtLossDateMonth").SetAttribute("value", "01")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtLossDateDay").SetAttribute("value", "01")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtLossDateYear").SetAttribute("value", "2016")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtRecoveryDateMonth").SetAttribute("value", "01")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtRecoveryDateDay").SetAttribute("value", "01")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtRecoveryDateYear").SetAttribute("value", "2017")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtFinalPaymentMonth").SetAttribute("value", "12")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtFinalPaymentDay").SetAttribute("value", "30")
Call ie.Document.GetElementByID("_ctl0_MainContent_txtFinalPaymentYear").SetAttribute("value", "2017")
'to find the "<input……/>" tag hyper link and to click the button
Set AllInputs = ie.Document.getelementsbytagname("input") 'you can use any tagname as you wish
For Each hyper_link In AllInputs
If hyper_link.Name = "_ctl0:MainContent:cmdCalculate" Then 'you can use .name, .id etc
hyper_link.Click
Exit For
End If
Next
Do
DoEvents
Loop Until ie.readystate = 3
Do
DoEvents
Loop Until ie.readystate = 4
End Sub
If you want to scrape the results, refresh the URL and do the same as I described above: F12, search for the relevant IDs and/or names, and pull those into a Worksheet in Excel. I'll leave it to you to figure out that part. It will be a good learning experience!!!

VBA getelementsbyclassname use with getelementsbyid

I'm trying to write a short VBA code to click on a button on a website by searching first by its classname, and then by id:
Sub Autoclick[enter image description here][1]()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate "http://stackoverflow.com/"
IE.Visible = True
While IE.Busy
DoEvents
Wend
IE.Document.getElementsByClassname("nav mainnavs").getElementById("nav-jobs").Click
End Sub
However the code would not click on the Jobs button. I understand that I can just use getelementbyid directly, but I'd still like to know why using getelementsbyclassname and getelementbyid together would not work.
Attached image contains the html code of the website.
Thanks a lot for any help!
I'd still like to know why using getelementsbyclassname and
getelementbyid together would not work.
Because code IE.Document.getElementsByClassname("nav mainnavs").getElementById("nav-jobs") causes error 438: object doesn't support this property or method.
It doesn't work because getElementsByClassName("nav mainnavs") returns a div and divs doesn't have any getElementById method.
To search the div by element id it would probably be necessary to loop through all the elements of it and check their id:
Dim mainnavs
Set mainnavs = IE.document.getElementsByClassName("nav mainnavs")
If mainnavs.Length > 0 Then
Dim mainnavItem ' this is a div element and it doesn't have .getElementById() method
Set mainnavItem = mainnavs.Item(0)
Dim itm
For Each itm In mainnavItem.all
If itm.ID = "nav-jobs" Then
itm.Click
Exit For
End If
Next itm
Else
MsgBox "getElementsByClassName('nav mainnavs') didn't return any elements"
End If
when I apply the same method to my company's website it keeps on
showing the message box "didn't return any elements"
This means that element with such class name does not exist on the page.
Do you wait until the page is fully loaded?
While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE: DoEvents: Wend
why would we do mainnavItem.all in the For loop
This is because there is no other possibility to search for element by its id. Therefore we go through all the children of the mainnavItem and check the id.