I'm using IE11 with the HMTL Object Library and Internet Controls references activated.
There's no element ID on the button but am able to use ie.Document.getElementsByClassName by adding some html and xml declarations thanks to this post.
I'm taking a name and city, state from Excel and plugging it into the website then clicking the search button.
This is where my error occurs.
Run-time error '438': Object doesn't support this property or method.
HTML:
VBA:
Option Explicit
Sub HGScrape()
'Application.ScreenUpdating = False
'we define the essential variables
Dim ie As Object
Dim my_url As String
Dim SearchButton, NameBox, AddressBox
Dim ele As Object
Dim x As Integer
Dim y As Integer
Dim IsOdd As Integer
Dim html_doc As Object 'HTMLDocument
Dim xml_obj As Object 'MSXML2.DOMDocument
my_url = "https://www.healthgrades.com/"
'add the "Microsoft Internet Controls" reference in your VBA Project indirectly
Set ie = New InternetExplorer
ie.Visible = True 'False ''''''''''''''''''''''
ie.Navigate my_url '"13.33.74.92" '("https://www.healthgrades.com/")
While ie.ReadyState <> 4
DoEvents
Wend
Set NameBox = ie.Document.getElementById("search-term-selector-child")
NameBox.Value = ActiveSheet.Range("A2")
Set AddressBox = ie.Document.getElementById("search-location-selector-child")
AddressBox.Value = ActiveSheet.Range("B2")
Set html_doc = CreateObject("htmlfile")
Set xml_obj = CreateObject("MSXML2.XMLHTTP")
xml_obj.Open "GET", my_url, False
xml_obj.send
html_doc.body.innerHTML = xml_obj.responseText
Set SearchButton = ie.Document.getElementsByClassName("autosuggest_submiter") 'id of the button control (HTML Control)
SearchButton.Click
While ie.ReadyState <> 4
DoEvents
Wend
I condensed your code a bit. You really do not need to set every element to a variable. This just wastes resources in the long run.
Use the ClassName submiter__text to grab your submit button, and it's index of 0.
Sub HGScrape()
Const sURL As String = "https://www.healthgrades.com/"
Dim ie As New InternetExplorer
With ie
.Visible = True
.Navigate sURL
While .Busy Or .ReadyState < 4: DoEvents: Wend
.Document.getElementById("search-term-selector-child"). _
Value = ActiveSheet.Range("A2")
.Document.getElementById("search-location-selector-child"). _
Value = ActiveSheet.Range("B2")
.Document.getElementsByClassName("submiter__text")(0).Click
While .Busy Or .ReadyState < 4: DoEvents: Wend
End With
End Sub
"..Why was the "submitter_text" class the correct one?"
The best way to explain it is to show you. If you are unsure what selection to make, then right-click the element and choose "Inspect Element" and look around the highlighted line.
Related
I have this simple macro that opens up IE and type a word in search box. It was working before, but now is returning
Error 424 - Object required.
Any ideas on what is happening? Is there any lib reference that I'm missing?
Sub AcessaPaginaDados()
Dim xobj As HTMLDivElement
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.Navigate ("https://www.google.com/")
Do While ie.Busy Or ie.readyState <> 4
DoEvents
Loop
Set xobj = ie.document.getElementById("lst-ib")
Call xobj.setAttribute("value", "teste")
End Sub
That id doesn't appear against the input box when I open google. You can use an attribute = value selector to target the title attribute of the search box. Right-click inspect the search box and see what your local language attribute value is for title=. In U.K. the value is Search. Use whatever your local value is.
Element html:
Other:
Also, .navigate2 is the preferred method.
If the page is slow loading you may need a loop until element present.
Option Explicit
Public Sub AcessaPaginaDados()
Dim xobj As HTMLDivElement
With CreateObject("InternetExplorer.Application")
.Visible = True
.Navigate2 "https://www.google.com/"
While .Busy Or .readyState < 4: DoEvents: Wend
Set xobj = .document.querySelector("[title=Search]")
xobj.Value = "teste"
Stop
.Quit
End With
End Sub
I am trying to scrap barcode owners from this site : http://gepir.gs1.org/index.php/search-by-gtin
I am receiving "Object doesnt support this property or method" error msg because of the final line. I tried to extract it with class and tag but failed.
I am trying to extract the company name from the dynamic table.
Sub aa()
Dim ie As New SHDocVw.InternetExplorer
Dim doc As HTMLDocument
Dim aaa As Object
Dim objIE As InternetExplorer
Set objIE = New InternetExplorer
ie.Visible = True
ie.navigate "gepir.gs1.org/index.php/search-by-gtin"
Do While ie.readyState <> READYSTATE_COMPLETE
Loop
Debug.Print ie.LocationName, ie.LocationURL
Set doc = ie.document
ie.document.forms("searchbygtin").elements("keyValue").Value = "685387379712"
ie.document.forms("searchbygtin").elements("method").Click
Debug.Print ie.document.getElementsBytag("tr")(7).innerText
End Sub
Any help would be great,
Thanks
You need TagName
Debug.Print ie.document.getElementsByTagName("tr")(7).innerText
I get a captcha though so I doubt you can complete this task in this way. Selenium and IE both seem to trigger the captcha, at least for me.
If not for the captcha I would re-write your script as follows (perhaps with a loop to make sure tr element is present):
Option Explicit
Public Sub GetLastChangeDate()
Dim ie As New SHDocVw.InternetExplorer, doc As HTMLDocument
Const URL = "gepir.gs1.org/index.php/search-by-gtin"
With ie
.Visible = True
.navigate URL
While .Busy Or .readyState < 4: DoEvents: Wend
Set doc = .document
Debug.Print .LocationName, .LocationURL
doc.getElementById("keyValue").Value = "685387379712"
doc.getElementById("submit-button").Click
While .Busy Or .readyState < 4: DoEvents: Wend
Debug.Print .document.getElementsByTagName("tr")(7).innerText
End With
End Sub
I am trying to login Web page and fetch data however my login details are not getting update, i have tried all possibilities code from your forum, nothing is working for me
Below is my code, am getting attached error
Sub test()
Dim ie As Object
Dim objCollection As Object
Dim i As Integer
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate "https://portal.expeditors.com/expo/login"
Do While ie.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Get all the elements with input tag name
Set objCollection = ie.document.getElementsByTagName("input")
i = 0
'Loop through all elements and find login form and fill it
While i < objCollection.Length
'Login name
If objCollection(i).Name = "username" Then
objCollection(i).Value = "bom-sumand"
End If
'Store login button in object
If objCollection(i).Type = "submit" Then
Set objElement = objCollection(i)
End If
i = i + 1
Wend
'Click login
objElement.Click
'Clean up
Set ie = Nothing
End Sub
I would use the available ids rather than looping to find the input boxes and sign in. These are much faster selector methods. You can add a .Focus. Also, swop InternetExplorer for InternetExplorerMeduim in some cases.
If problem continues check your internet settings in case site is blocked.
Open the URL via creating an IE instance direct.
Option Explicit
Public Sub Login()
Dim ie As New InternetExplorer 'InternetExplorerMedium
Const MAX_WAIT_SEC As Long = 5
Dim t As Date, ele As Object
With ie
.Visible = True
.navigate "https://portal.expeditors.com/expo/login"
While .Busy Or .readyState < 4: DoEvents: Wend
With .document
Do
DoEvents
On Error Resume Next
Set ele = .getElementById("j_username")
On Error GoTo 0
If Timer - t > MAX_WAIT_SEC Then Exit Do
Loop While ele Is Nothing
If ele Is Nothing Then Exit Sub
With ele
.Focus
.Value = "bob"
End With
With .getElementById("j_password")
.Focus
.Value = "penny"
End With
.getElementById("signInBtn").Click
End With
While .Busy Or .readyState < 4: DoEvents: Wend
Stop '<== Delete me later
.Quit
End With
End Sub
Macro trying and failing to open a second instance of IE try this.
Sub test()
Dim ie As Object
Dim redURL As String
Dim objCollection As Object
Dim i As Integer
redURL = "https://portal.expeditors.com/expo/login"
On Error Resume Next
Set ie = GetObject(, "InternetExplorer.Application")
If Err Then
Set ie = CreateObject("InternetExplorer.Application")
End If
On Error GoTo 0
ie.Visible = True
ie.Navigate redURL
Do While ie.Busy
Loop
End Sub
Need help how to create excel vba code for this
I'll be needing the codes so I can complete my macro.
Thanks in advance
First, you will need to create a reference to:
Microsoft Internet Controls
Microsoft HTML Object Library
In VBE, click Tools > References
Sub clickLink()
Dim ie As New InternetExplorer, Url$, doc As HTMLDocument
Url = "http://UrlToYourLink.com"
With ie
.navigate Url
Do While .Busy Or .readyState < READYSTATE_COMPLETE
DoEvents
Loop
doc = .document
.Visible = True
End With
Dim myBtn As Object
Set myBtn = doc.getElementsByClassName("button rounded")(0)
myBtn.Click
End Sub
The Internet control is used to browse the webpage and the HTML Objects are used to identify the username and password textboxes and submit the text using the control button.
Dim HTMLDoc As HTMLDocument
Dim oBrowser As InternetExplorer
Sub Login_2_Website()
Dim oHTML_Element As IHTMLElement
Dim sURL As String
On Error GoTo Err_Clear
sURL = "https://www.google.com/accounts/Login"
Set oBrowser = New InternetExplorer
oBrowser.Silent = True
oBrowser.timeout = 60
oBrowser.navigate sURL
oBrowser.Visible = True
Do
' Wait till the Browser is loaded
Loop Until oBrowser.readyState = READYSTATE_COMPLETE
Set HTMLDoc = oBrowser.Document
HTMLDoc.all.Email.Value = "sample#vbadud.com"
HTMLDoc.all.passwd.Value = "*****"
For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
If oHTML_Element.Type = "submit" Then oHTML_Element.Click: Exit For
Next
' oBrowser.Refresh ' Refresh If Needed
Err_Clear:
If Err <> 0 Then
Debug.Assert Err = 0
Err.Clear
Resume Next
End If
End Sub
The program requires references to the following:
1 Microsoft Internet Controls
2. Microsoft HTML Object Library
Microsoft internet controls are a great way to do this, but if you aren't allowed to add new references, here is another way to go about web scraping.
This methode ain't as 'clean' as Microsoft internet controls and HTML object but it gets the job done.
Sub GoogleSearch()
Dim ie As Object
Dim objSearchBnt As Object
Dim objCollection As Object
Dim i As Integer
'initialize counter
i = 0
'Create InternetExplorer Object
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
'navigate to the url
ie.navigate "Www.google.com"
'Statusbar shows in the buttom corner of excel
Application.StatusBar = "Loading, please wait..."
'Wait until page is ready
Do While ie.busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Store all the elements with input tag
Set objCollection = ie.Document.getElementsByTagName("input")
'Go through all input elements
While i < objCollection.Length
'input search field
If objCollection(i).Name = "q" Then
objCollection(i).Value = "Hello World"
End If
'search button
If objCollection(i).Type = "submit" Then
Set objSearchBnt = objCollection(i)
End If
i = i + 1
Wend
objSearchBnt.Click
'Clean up
Set objSearchBnt = Nothing
Set objCollection = Nothing
Set ie = Nothing
'Give excel control over the status bar agian
Application.StatusBar = ""
End Sub
My goal is to scrape the source code of a web page.
The site seems to have different Frames which is why my code won't work properly.
I tried to modify a code which I found online which should solve the Frame issue.
The following code creates an error (object required) at:
Set profileFrame .document.getElementById("profileFrame")
Public Sub IE_Automation()
'Needs references to Microsoft Internet Controls and Microsoft HTML Object Library
Dim baseURL As String
Dim IE As InternetExplorer
Dim HTMLdoc As HTMLDocument
Dim profileFrame As HTMLIFrame
Dim slotsDiv As HTMLDivElement
'example URL with multiple frames
baseURL = "https://www.xing.com/search/members?section=members&keywords=IT&filters%5Bcontact_level%5D=non_contact"
Set IE = New InternetExplorer
With IE
.Visible = True
'Navigate to the main page
.navigate baseURL & "/publictrophy/index.htm?onlinename=ace_anubis"
While .Busy Or .readyState <> READYSTATE_COMPLETE: DoEvents: Wend
'Get the profileFrame iframe and navigate to it
Set profileFrame = .document.getElementById("profileFrame")
.navigate baseURL & profileFrame.src
While .Busy Or .readyState <> READYSTATE_COMPLETE: DoEvents: Wend
Set HTMLdoc = .document
End With
'Display all the text in the profileFrame iframe
MsgBox HTMLdoc.body.innerText
'Display just the text in the slots_container div
Set slotsDiv = HTMLdoc.getElementById("slots_container")
MsgBox slotsDiv.innerText
End Sub
Hummmm, I'm not exactly sure what you are doing here, but can you try the code below?
Option Explicit
Sub Sample()
Dim ie As Object
Dim links As Variant, lnk As Variant
Dim rowcount As Long
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate "https://www.xing.com/search/members?section=members&keywords=IT&filters%5Bcontact_level%5D=non_contact"
'Wait for site to fully load
'ie.Navigate2 URL
Do While ie.Busy = True
DoEvents
Loop
Set links = ie.document.getElementsByTagName("a")
rowcount = 1
With Sheets("Sheet1")
For Each lnk In links
'Debug.Print lnk.innerText
'If lnk.classname Like "*Real Statistics Examples Part 1*" Then
.Range("A" & rowcount) = lnk.innerText
rowcount = rowcount + 1
'Exit For
'End If
Next
End With
End Sub
General:
I think in your research you may have come across this question and misunderstood how it relates/doesn't relate to your circumstance.
I don't think iFrames are relevant to your query. If you are after the list of names, their details and the URLs to their pages you can use the code below.
CSS Selectors
To target the elements of interest I use the following two CSS selectors. These use style infomation on the page to target the elements:
.SearchResults-link
.SearchResults-item
"." means class, which is like saying .getElementsByClassName. The first gets the links, and the second gets the description information on the first page.
With respect to the first CSS selector: The actual link required is dynamically constructed, but we can use the fact that the actual profile URLs have a common base string of "https://www.xing.com/profile/", which is then followed by the profileName. So, in function GetURL, we parse the outerHTML returned by the CSS selector to get the profileName and concatenate it with the BASESTRING constant to get our actual profile link.
Code:
Option Explicit
Public Sub GetInfo()
Dim IE As New InternetExplorer
With IE
.Visible = True
.navigate "https://www.xing.com/publicsearch/query?search%5Bq%5D=IT"
While .Busy Or .readyState < 4: DoEvents: Wend
Dim a As Object, exitTime As Date, linksNodeList As Object, profileNodeList As Object
' exitTime = Now + TimeSerial(0, 0, 5) '<== uncomment this section if timing problems
'
' Do
' DoEvents
' On Error Resume Next
' Set linksNodeList = .document.querySelectorAll(".SearchResults-link")
' On Error GoTo 0
' If Now > exitTime Then Exit Do
' Loop While linksNodeList Is Nothing
Set linksNodeList = .document.querySelectorAll(".SearchResults-link") '<== comment this out if uncommented section above
Set profileNodeList = .document.querySelectorAll(".SearchResults-item")
Dim i As Long
For i = 0 To profileNodeList.Length - 1
Debug.Print "Profile link: " & GetURL(linksNodeList.item(i).outerHTML)
Debug.Print "Basic info: " & profileNodeList.item(i).innerText
Next i
End With
End Sub
Public Function GetURL(ByVal htmlSection As String) As String
Const BASESTRING As String = "https://www.xing.com/profile/"
Dim arr() As String
arr = Split(htmlSection, "/")
GetURL = BASESTRING & Replace$(Split((arr(UBound(arr) - 1)), ">")(0), Chr$(34), vbNullString)
End Function
Example return information: