Script sometimes logs in a website but fails most of the times - vba

I've created a vba script using Internet Explorer to log in a website using my credentials. The thing is the script sometimes works flawlessly but most of the times it fails while hitting the sign in button, meaning gets stuck there.
Sub SignIn()
Const Url$ = "https://member.angieslist.com/app/search?categoryName=Plumbing&isMisspelling=false&query=Plumbing&categorySearchType=legacy&category=107"
Dim IE As New InternetExplorer, HTML As HTMLDocument
Dim oPass As Object, oMail As Object, oButton As Object
With IE
.Visible = True
.navigate Url
While .Busy Or .readyState < 4: DoEvents: Wend
Set HTML = .document
With HTML
Do: DoEvents: Loop Until .querySelectorAll("#login--login-email").Length > 0
Set oMail = .querySelector("#login--login-email")
oMail.Focus
oMail.innerText = "useremail"
Do: DoEvents: Loop Until .querySelectorAll("#login--login-password").Length > 0
Set oPass = .querySelector("#login--login-password")
oPass.Focus
oPass.innerText = "password"
Do: DoEvents: Loop Until .querySelectorAll("#login--login-button").Length > 0
Set oButton = .querySelector("#login--login-button")
oButton.Focus
oButton.Click 'It gets here stuck most of the times
End With
End With
End Sub
How can I log in that site without fail?

This MIGHT work...50/50 shot.
Sub SignIn()
Const Url$ = "https://member.angieslist.com/app/search?categoryName=Plumbing&isMisspelling=false&query=Plumbing&categorySearchType=legacy&category=107"
Dim IE As New InternetExplorer, HTML As HTMLDocument
Dim oPass As Object, oMail As Object, objElement As Object, objCollection As Object
With IE
.Visible = True
.navigate Url
While .Busy Or .readyState < 4: DoEvents: Wend
Set HTML = .document
With HTML
Do: DoEvents: Loop Until .querySelectorAll("#login--login-email").Length > 0
Set oMail = .querySelector("#login--login-email")
oMail.Focus
oMail.innerText = "useremail"
Do: DoEvents: Loop Until .querySelectorAll("#login--login-password").Length > 0
Set oPass = .querySelector("#login--login-password")
oPass.Focus
oPass.innerText = "password"
Set ElementCol = IE.document.getElementsByClassName("btn btn-sm btn-primary btn-block btn-flat")
ElementCol.Item(0).Click
End With
End With
End Sub

Related

Catching anchor element using SHDocVw.InternetExplorer

I want to catch the anchor element in website via vba.
I tried both as an MSHTML.IHTMLAnchorElement and MSHMTL.IHTMLBUttonELement but either way gives an error on Set line. Can anyone describe what's wrong with code below?
Sub goToWhtSpp()
Dim ie As New SHDocVw.InternetExplorer
ie.Visible = True
ie.navigate "https://cooperatordirectory.com/"
Do While ie.readyState <> READYSTATE_COMPLETE Or ie.Busy
Loop
Dim doc As MSHTML.HTMLDocument
Set doc = ie.document
Application.Wait 3000
URL = "https://cooperatordirectory.com/search_results?location_value=Florida&adm_lvl_1_sn=FL&stateSearchLN=Florida&country_sn=US&location_type=administrative_area_level_1&stateSearch=FL&swlat=24.396308&nelat=31.000968&swlng=-87.634896&nelng=-79.974306&lat=27.6648274&lng=-81.5157535&faddress=Florida%2C+USA&place_id=ChIJvypWkWV2wYgR0E7HW9MTLvc"
ie.navigate URL
Dim aelement As MSHTML.IHTMLAnchorElement
Set aelement = doc.getElementsByClassName("btn btn-primary btn-block") ' err line
Dim btn As MSHTML.IHTMLButtonElement
Set btn = doc.getElementsByClassName("btn btn-primary btn-block") ' err line
Debug.Print btn.Value
End Sub
<a class="btn btn-primary btn-block" href="/pro/20220324090906/connect">Send Message</a>
You want a page load wait after each .navigate. In this case you only need the one .navigate and wait.
getElementsByClassName() returns a collection not a single node. So both your type declaration, subsequent SET attempt to this type, and later attempt to view the .value attribute will fail. .value is a property of a single node.
If you want the first "button" href then index into a correctly typed variable and call .item(0), or, more efficiently, use the querySelector() method of ie.document and pass in a single class of the multi-valued class (the one which still correctly identifies the target element).
Dim anchors As IHTMLElementCollection
Set anchors = .document.getElementsByClassName("btn-primary")
Dim anchor As IHTMLAnchorElement
Set anchor = .document.getElementsByClassName("btn-primary").Item(0)
Option Explicit
Public Sub PrintMessageUrl()
Const URL As String = "https://cooperatordirectory.com/search_results?location_value=Florida&adm_lvl_1_sn=FL&stateSearchLN=Florida&country_sn=US&location_type=administrative_area_level_1&stateSearch=FL&swlat=24.396308&nelat=31.000968&swlng=-87.634896&nelng=-79.974306&lat=27.6648274&lng=-81.5157535&faddress=Florida%2C+USA&place_id=ChIJvypWkWV2wYgR0E7HW9MTLvc"
Dim ie As SHDocVw.InternetExplorer
Set ie = New SHDocVw.InternetExplorer
With ie
.Visible = True
.navigate URL
Do While .readyState <> READYSTATE_COMPLETE Or .Busy: DoEvents: Loop
Debug.Print .document.querySelector(".btn-primary").href
.Quit
End With
End Sub

VBA Macro for Internet Explorer - code run well on debugging 1 by 1 command but didn't work if i run the whole program

I'm new with VBA Macro using for automate the internet explorer.
I've used it for creating bot to follow other online shopping follower (e-commerce).
Actually the code run well if I use debug 1 by 1 command, and it worked (can do the follow thing).
But if I run the whole program, the code just operate maybe several command & stopped (but it didn't error).
I used it for e-commerce (sho.ee).
The step is:
open IE for other shop's followers
grab all the link
open the new link in new IE
follow them, close the new IE
and looping.
If I run step by step it worked.
Hope you guys could help me which wrong with the code.
Here's the code => i changed the name of the shop by xxx
Sub Followers()
Dim objIE As InternetExplorer
Dim ieAnchors As Object
Dim Anchor As Object
Set objIE = New InternetExplorer
objIE.Visible = True
objIE.Navigate "https://shopee.co.id/shop/xxx/followers/"
Do While objIE.Busy = True Or objIE.ReadyState <> 4: DoEvents: Loop
Set ieAnchors = objIE.Document.getElementsByClassName("shop-href")
For Each Anchor In ieAnchors
result = Anchor
If result <> result_prev Then
Dim objIE_1 As InternetExplorer
Dim ieBtn As Object
Dim Btn As Object
Set objIE_1 = New InternetExplorer
objIE_1.Visible = True
objIE_1.Navigate Anchor
Do While objIE_1.Busy = True Or objIE_1.ReadyState <> 4: DoEvents: Loop
Set ieBtn = objIE_1.Document.getElementsByClassName("shopee-button-outline shopee-button-outline--complement shopee-button-outline--fill ")
For Each Btn In ieBtn
Btn.Click
Next Btn
objIE_1.Quit
result_prev = Anchor
End If
Next Anchor
End Sub
Sometimes pages load in parts, registering as complete before all elements have loaded. In these cases I use application.Wait to force the program to wait a set amount of time for page loads:
'wait five seconds
Application.Wait (Now + TimeValue("0:00:05"))
If it is a simple page, I will have a Do loop a check for ReadyState to avoid slowing the program down unnecessarily:
'wait for page to load
Do Until ie.ReadyState = READYSTATE_COMPLETE or ie.ReadyState = 4
DoEvents
Loop
yes it worked. by adding Application.Wait (Now + TimeValue("0:00:05"))
Sub Followers()
Dim objIE As InternetExplorer
Dim ieAnchors As Object
Dim Anchor As Object
Set objIE = New InternetExplorer
objIE.Visible = True
objIE.Navigate "https://shopee.co.id/shop/xxx/followers/"
Do While objIE.Busy = True Or objIE.ReadyState <> 4: DoEvents: Loop
Application.Wait (Now + TimeValue("0:00:02"))
Set ieAnchors = objIE.Document.getElementsByClassName("shop-href")
For Each Anchor In ieAnchors
result = Anchor
If result <> result_prev Then
Dim objIE_1 As InternetExplorer
Dim ieBtn As Object
Dim Btn As Object
Application.Wait (Now + TimeValue("0:00:02"))
Set objIE_1 = New InternetExplorer
objIE_1.Visible = True
objIE_1.Navigate Anchor
Do While objIE_1.Busy = True Or objIE_1.ReadyState <> 4: DoEvents: Loop
Set ieBtn = objIE_1.Document.getElementsByClassName("shopee-button-outline shopee-button-outline--complement shopee-button-outline--fill ")
For Each Btn In ieBtn
Btn.Click
Next Btn
objIE_1.Quit
result_prev = Anchor
End If
Next Anchor
End Sub

Unable to fill in some date inputs to perform a customized search

I'm trying to create a script in vba to select dates according to my preferable input date, as in 03/11/2019 and output date, as in 05/11/2019 for the two fields check-in and chek-out. the macro that I've written so far can click on those fields but can't fill in the inputs with the aforesaid dates.
Website address
I've tried:
Sub FillInTheForm()
Dim IE As New InternetExplorer, HTML As HTMLDocument
Dim post As Object, elem As Object, guest As Object
Dim findbtn As Object, URL$
URL = "https://www.discoverqatar.qa/"
With IE
.Visible = True
.navigate URL
While .Busy = True Or .readyState < 4: DoEvents: Wend
Application.Wait Now + TimeValue("00:00:05")
Set post = .document.querySelector("[class='rsp_s_checkindate_input'] > #lpPannel_txtFromDate")
post.Focus
post.Click
Application.Wait Now + TimeValue("00:00:05")
Set elem = .document.querySelector("[class='rsp_s_checkoutdate_input'] > #lpPannel_txtToDate")
elem.Focus
elem.Click
Application.Wait Now + TimeValue("00:00:05")
Set guest = .document.querySelector("#lblPaxInfo")
guest.Focus
guest.Click
Application.Wait Now + TimeValue("00:00:05")
Set findbtn = .document.querySelector("input#btnSearch")
findbtn.Focus
findbtn.Click
End With
' IE.Quit
End Sub
Some intentional delays are there within the script which I can kick out later defining any timed loop.
How can I fill in the dates in those boxes to perform a customized search?
Just set the value attributes
Option Explicit
Public Sub SetDates()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
With ie
.Visible = True
.Navigate2 "https://www.discoverqatar.qa/"
While .Busy Or .readyState <> 4: DoEvents: Wend
With .document
.querySelector("#lpPannel_txtFromDate").Value = "03/11/2019"
.querySelector("#lpPannel_txtToDate").Value = "05/11/2019"
.querySelector("#btnSearch").Click
Stop
End With
End With
End Sub

VBA IE change dropdown value

Tried the below code for following URL Scripture look up. Please how to change drop down value from WEB to RV1909?
Dim Doc As HTMLDocument
Set Doc = IEApp.document
TestV2 = ""
TestV3 = ""
TestV2 = Doc.getElementsByClassName("app-list text-list")(0).innerText
Debug.Print "4b of 5: " & TestV2
IEApp.Doc.getElementsByClassName("app-list text-list").selectedIndex = 1
IEApp.Doc.getElementsByClassName("app-list text-list").FireEvent ("onchange")
TestV3 = Doc.getElementsByClassName("app-list text-list")(0).innerText
Debug.Print "4c of 5: " & TestV3
Tried many approaches from other posts, the following does not work:
IEApp.Doc.getElementsByClassName("app-list text-list")(0).innerHTML = "RV1909"
Here is the screenshot of Chrome Inspector:
In this case it's not enough just change div.app-list.text-list element innerText, as you can see that element is simple div, but not even ul. It should be changed by scripts which are called on click events. So, first of all you need to click on div to display the entire list, and then click on the RV1909 item. The below example shows how that could be done:
Sub Test()
Dim oIE As Object
Dim oDiv As Object
Set oIE = CreateObject("InternetExplorer.Application")
With oIE
.Visible = True
.Navigate "http://ebible.org/study/"
Do While .readyState <> 4 Or .Busy
DoEvents
Loop
With .Document
Do While .readyState <> "complete"
DoEvents
Loop
Set oDiv = .getElementsByClassName("app-list text-list")(0)
oDiv.Click
Do While .readyState <> "complete"
DoEvents
Loop
For Each oNode In .getElementsByClassName("text-chooser-main")(0).getElementsByClassName("text-chooser-abbr")
If oNode.innerText = "RV1909" Then
oNode.Click
Do While oDiv.innerText <> "RV1909"
DoEvents
Loop
Exit For
End If
Next
End With
End With
End Sub
Change the html div element <div class=app-list text-list>WEB</div> to <div class=app-list text-list>RV1909</div>

How to load all the results on a web page using VBA?

I want to load all the games from the below web site.
http://www.flashscore.com/soccer/england/premier-league-2015-2016/results/
First load of the page shows me only a part of the total results, but I want to load all the data from the page.
Even if I use the below code to press the link "Show more matches", there are still hidden games not showed.
Could anyone help me with some hints?
Image link
My code is below:
Sub Test_Flashscore()
Dim URL As String
Dim ie As New InternetExplorer
Dim HTMLdoc As HTMLDocument
Dim dictObj As Object: Set dictObj = CreateObject("Scripting.Dictionary")
Dim tRowID As String
URL = "http://www.flashscore.com/soccer/england/premier-league-2015-2016/results/"
With CreateObject("InternetExplorer.Application")
.Visible = True
.navigate URL
Do: DoEvents: Loop While .Busy Or .readyState <> 4
Do: DoEvents: Loop While .document.readyState <> "complete"
.document.parentWindow.execScript "loadMoreGames();"
Do: DoEvents: Loop While .document.getElementById("preload").Style.display = "none"
End With
Set ie = Nothing
MsgBox "Process Completed"
End Sub
Just quickly, does it have to be that site or are other feeds worth considering?
Maybe: http://www.football-data.co.uk/englandm.php
so:
http://www.football-data.co.uk/mmz4281/1617/E0.csv