I used the VBA below and monitored the variable IE.document. When the url is IE.navigate="http://www.mixi.jp", I could get all the web text using IE.document.all.
But in other sites like "http://www.yahoo.co.jp" , I could not get Web text. Why is that?
Sub Main()
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "http://www.yahoo.co.jp"
Do While IE.Busy Or IE.readyState < 4
DoEvents
Loop
End Sub
Because this particular website's IE.document is nothing:
This seems to be the case with dynamically served sites, there are some suggestions here which I use below.
Although I am not sure you will be able to easily "get all of the text", you can certainly still iterate over the elements you're interested in extracting:
Sub Main()
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate "http://www.yahoo.co.jp"
Do While ie.Busy Or ie.readyState < 4
DoEvents
Loop
'Create a collection of DIV elements for example
Dim myElements
DIm ele
Set myElements = ie.Document.Body.GetElementsByTagName("DIV")
'Then you can iterate over the DIV elements/etc., modify as needed.
For each ele in myElements
Debug.Print ele.InnerText
Next
End Sub
Related
The program is trying to identify the login area.
The problem is that in the script of the web page there is no ID to refer to so I tried to get elements by Name but it doesn't work.
Sub test()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.application")
IE.Visible = True
IE.navigate "https://freebitcoin.io"
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
IE.document.getElementByName("email").Value = "tarnone#outlook.com"
End Sub
I have message "error 438 "object doesn't support this property or method"
There are a few elements with that class name - form-control email, thus the 0-th one is the one needed. And then with .Value the email could be set:
Sub TestMe()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "https://freebitcoin.io"
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Dim someElement As Object
Set someElement = IE.document.getElementsByClassName("form-control email")
someElement(0).Value = "mail#some.mail"
End Sub
Sub Two()
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate "http://example.com/market/listings/578080/Sneakers%20(WHITE)"
Do: DoEvents: Loop Until IE.ReadyState = 4
Srd27 = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")(0).innerText
ActiveSheet.Range("D27").Value = Srd27
IE.Navigate "http://example.com/market/listings/578080/Floral%20Shirt%20(Black)"
Do: DoEvents: Loop Until IE.ReadyState = 4
Srd28 = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")(0).innerText
ActiveSheet.Range("D28").Value = Srd28
IE.Navigate "http://example.com/market/listings/578080/Tracksuit%20Top%20(Yellow)"
Do: DoEvents: Loop Until IE.ReadyState = 4
Srd29 = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")(0).innerText
ActiveSheet.Range("D29").Value = Srd29
IE.Navigate "http://example.com/market/listings/578080/School%20Jacket"
Do: DoEvents: Loop Until IE.ReadyState = 4
Srd30 = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")(0).innerText
ActiveSheet.Range("D30").Value = Srd30
IE.Navigate "http://example.com/market/listings/578080/Leather%20Bootcut%20Pants"
Do: DoEvents: Loop Until IE.ReadyState = 4
Srd31 = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")(0).innerText
ActiveSheet.Range("D31").Value = Srd31
IE.Quit
End Sub
If i use F8 key in Visual Basic app it works sometimes. But when I use macros in Excel its saying
'object variable or with block variable not set - error '91''
I have tested it and from what I can see it's that the address "http://steamcommunity.com/market/listings/578080/Sneakers%20(WHITE)" gives you a page saying that the product could not be found.
The method getElementsByClassName generates error because the element you are looking for is not available on the loaded page.
Try something like this:
Sub Two()
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate "http://steamcommunity.com/market/listings/578080/Sneakers%20(WHITE)"
Do: DoEvents: Loop Until IE.ReadyState = 4
on error resume next
Srd27 = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")(0).innerText
on error goto 0
If Srd27 <> "" then
ActiveSheet.Range("D27").Value = Srd27
Else
ActiveSheet.Range("D27").Value = "Product not found"
end if
'repeat for the rest of the code
IE.Quit
End Sub
And of course I am always encouraging to use Option Explicit and declare all variables.
You need to set the object and validate its state before trying to access its properties.
getElementsByClassName()
Returns a collection of objects with the same class attribute value.
Sub Two()
Dim IE As Object, Srd27 As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate "http://steamcommunity.com/market/listings/578080/Sneakers%20(WHITE)"
Do: DoEvents: Loop Until IE.ReadyState = 4
Set Srd27 = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")(0)
If Not Srd27 Is Nothing Then
ActiveSheet.Range("D27").Value = Srd27.innerText
End If
End Sub
Edit:
To get multiple results, you have to loop through the elements collection and get the innerText of each element.
Dim elements As Object, element as Object
Set elements = IE.Document.getElementsByClassName("market_commodity_orders_header_promote")
If Not elements Is Nothing Then
For Each element in elements
Debug.Print element.innerText
Next
End if
Below is the code i am using
Sub IE_try()
Application.ScreenUpdating = False
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "my site"
Application.StatusBar = "Submitting"
While IE.Busy
DoEvents
Wend
delay 5
IE.Document.getElementByClass("ms-textSmall ms-srch-sb-prompt ms-helperText").Value = "abc"
IE.Documnet.getElementByName("ms-srch-sb-searchImg").Click
End Sub
Error message:
Thanks in advance :)
You are getting a strange error. In general your code is a bit wrong - you should use getElementsByClassname and not getElementsByClass. Here is something to start with, working for the StackOverflow site, writing abv in the search engine.
Option Explicit
Sub IE_try()
Dim Element As Object
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "http://stackoverflow.com"
While IE.Busy
DoEvents
Wend
Set Element = IE.Document.getElementsByClassname("f-input js-search-field")
Element.Item.Value = "abv"
End Sub
I'm trying to automate a task in excel that requires opening a webpage, navigating to a link on that page, and then clicking on a button on the second page to download an .xlsx file.
I've written a script that should do this. However, the response I get from the webpage is not always the same. In particular, sometimes this will return a download from the first page and sometimes it will navigate to the second page and not download anything, once or twice it has done both.
My sense is that this has to do with how long it takes for InternetExplorer.application to complete a request. I can't figure out how to troubleshoot this though, given that I tell the script to wait for IE.application to complete its request.
Sub DoBrowse2()
'For Each lnk In Sheets("Sheet4").Hyperlinks
'Range(lnk).Hy.Follow
'Next
Dim i As Long
Dim URL As String
Dim BaseURL As String
Dim ToURL As String
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
Dim HWNDSrc As Long
Dim html As IHTMLDocument
Set IE = CreateObject("InternetExplorer.Application")
URL = Range("B2").Hyperlinks(1).Address
IE.Navigate URL
IE.Visible = True
Application.StatusBar = URL & " is loading. Please wait..."
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
Application.StatusBar = URL & " Loaded"
'Set html = IE.Document
'Dim elements As IHTMLElementCollection
'Set elements = html.all
For Each itm In IE.Document.all
If itm.className = "datagrid" Then
For Each el In itm.Document.all
Debug.Print "hello"
If el.className = "ujump" And Right(el.innerText, 12) = "Constituents" Then
'Debug.Print el.innerText
ToURL = el.getAttribute("data-subset")
BaseURL = "http://datastream.thomsonreuters.com/navigator/search.aspx?dsid=ZUCH002&AppGroup=DSAddin&host=Metadata&prev=scmTELCMBR&s=D&subset="
ToURL = BaseURL & ToURL
'Debug.Print ToURL
IE.Navigate ToURL
IE.Visible = True
Do While IE.Busy
Debug.Print "in busy loop"
Application.Wait DateAdd("s", 1, Now)
Loop
GoTo end_of_for
End If
Next
End If
Next
end_of_for:
Debug.Print ("STOP STOP STOP STOP STOP")
Dim Script As String
For Each itm In IE.Document.all
If itm.className = "lgc excel" Then
Debug.Print "hello world"
Debug.Print itm.getAttribute("onclick")
itm.Click
Do While IE.Busy
Debug.Print "app busy"
Application.Wait DateAdd("s", 1, Now)
Loop
Exit For
End If
Next
End Sub
Thanks in advance for your help.
Use this to determine whether IE page has been fully loaded, it always must be both of these conditions:
Do Until ie.ReadyState = 4 And ie.Busy = False
DoEvents
Loop
Even with code above if there are scripts on the page, some content may be loaded after ie.ReadyState = 4 And ie.Busy = False condition is met and either easy way, but inefficient and unreliable Application.Wait can be used or you can try finding elements on the website which inform about loading state and determine the state by their visible attributes etc.
Part of your code is wrong and causes an endless loop:
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
It makes DoEvents fire while readystate is complete and also until it reaches complete status.
Narrow down a collection of all elements:
For Each itm In IE.Document.all
to a specific collection for better performance when possible, for example:
For Each itm In IE.Document.GetElementsByTagName("div")
I use VBA excel to parse a long list of local .htm files. The problem is that I get an error even before the programm starts to parse the HTM-files.
Error is:
VBA code:
<!-- language: lang-html -->
Enum READYSTATE
READYSTATE_UNINITIALIZED = 0
READYSTATE_LOADING = 1
READYSTATE_LOADED = 2
READYSTATE_INTERACTIVE = 3
READYSTATE_COMPLETE = 4
End Enum
Sub ImportHTM()
'Dim ie As InternetExplorer
Dim ie As InternetExplorerMedium
Dim html As HTMLDocument
Set ie = New InternetExplorerMedium
'Set ie = New InternetExplorer
ie.Visible = False
ie.navigate "d:\Cloud\Dropbox\3.htm"
Do While ie.READYSTATE <> READYSTATE_COMPLETE
Application.StatusBar = "Loading Profile..." 'PROBLEM SEEMS TO BE HERE SOMEWHERE!
DoEvents
Loop
Set html = ie.document
Set ie = Nothing
Application.StatusBar = ""
'code code code --> which at this point isn't executed because the error occures before
Do you have any ideas what could cause the problem? Do you have any solution suggestions?
Also the command:
ie.Visible = False
doesn't seem to have any effect whatsoever since it opens the HTM-file in a new IE window.
Move the status bar update out of the loop.
Application.StatusBar = "Loading Profile..."
Do While ie.Busy Or ie.READYSTATE <> READYSTATE_COMPLETE
DoEvents
Loop
Application.StatusBar = vbNullString
There is no need to rewrite the same message into the Application.StatusBar property hundreds if not thousands of times while you are waiting on a page load.
Regarding a new Internet.Explorer 'window' not inheriting the .Visible = False attribute, I recommend you switch to .Navigate2 and ShellWindows.
Addendum: Don't destroy your ie object until you are finished with the html associated with ie.document.