*IMPORTANT: please ask coding questions in the Ask For Help forum
Basic Webpage Controls with Javascript / COM
This tutorial requires AutoHotkey v1.1+ with built-in COM Support.
Purpose
The purpose of this tutorial is to teach the intermediate AHK user how to start using COM to control webpages. My goal is to provide methods for controlling webpages, similar to how the AHK Control Commands can control Windows Applications. This tutorial is going to be high level, but will provide links to those who want to dig deeper into these concepts. You don't need to have much programming experience, but I will assume you feel comfortable writing and executing AHK scripts. We will be covering the following three topics:
- The HTML DOM - (Document Object Model) A basic understanding of the HTML DOM is essential for controlling webpages. This is because it's a "map" or "heirarchy" for accessing parts of the webpage. The HTML DOM is not language dependent, but rather the model for how the webpage document is constructed.
- Javascript - We will cover some basic Javascript because it is the scripting language of the web, and is supported by most web browsers. Controlling webpages using Javascript is not the primary aim of this tutorial, but it will prove valuable because you should be able to find plenty of useful Javascript examples online. This will be helpful because in my opinion, the simplest way to start using COM is to learn some basic Javascript, and then "translate" that code to use with COM in AHK.
- COM - (Component Object Model) All you really need to know about COM for this tutorial is that Internet Explorer is a COM object - which means we can use COM to manipulate it. Using COM is the most effective way to control an Internet Explorer Webpage with AHK.
"Let me say it a different way: COM is the steering wheel - the HTML DOM is a road map - AHK is the car" ~tank
Disclaimers
For this tutorial, I will show you how to control webpages using Javascript, along with the AHK COM "translations" - also, note Sean's post below. Using COM requires Internet Explorer, but Javascript can be used with most Web Browsers. That being said, the DOM examples in this tutorial were written using Internet Explorer 9. The DOM examples may not be exactly the same in other browsers. In each code example, Javascript will be on the first line with the corresponding AHK code on the second line.
Some other tutorials that helped me out, and inspired this tutorial can be found here:
- COM Tutorial by tank - Study the basics from this; I will not be covering them.
- W3Schools - Many links listed below will take you to this website, which is an excellent resource for learning Javascript in depth.
Thank You:
- Chris Malet for creating AutoHotkey
- Lexikos for AutoHotkey v1.1+ (_L)
- Sean and fincs for helping with Native COM Support
- Sean for creating the COM Standard Library
- tank for the tutorial listed above, and daonlyfreez
- tank, sinkfaze, and jaco0646 for reviewing this tutorial
Terms - The following terms will be used throughout this tutorial. You may use these links for a more in-depth description of each item.
HTML DOM, Javascript, COM, Methods, document, value, element, form, name, ID, Input, Tag, selectedIndex, checked, innerText, innerHTML
Methods - The following Methods will be used throughout this tutorial. (comparable to built-in functions for AHK)
alert(), getElementById(), getElementsByName(), getElementsByTagName(), focus(), click()
Before we begin, this tutorial will be using examples that start with javascript: - which you will feed through the URL Address bar. These examples will be based on (and can be used with) the Search Forum webpage. Our first example will use the alert() method to pop-up a message box that says Hello World! Simply put this javascript in your URL Address bar and hit enter:
javascript: alert('Hello World!') wb.Navigate("javascript: alert('Hello World!')")
Note - some browsers may remove the "javascript: " if you paste the javascript line in the url address bar. You may have to manually type it in.
Accessing WebPage Contents - HTML DOM
To understand how to use Javascript to control a webpage, you need a general understanding of the HTML DOM. It is similar to a "map" or "heirarchy" of the Webpage, as shown here:
*Image is from this website, which is another great resource for learning Javascript.
In the image above, note the document object - you will be using this object quite often. To access the Webpage, you will need to navigate through the HTML DOM. Here are some simple ways to do this:
- Object Name and Index
Say you want to get the value of the 3rd element in the 2nd form, which will be the Find words Input Box. The path would look like this (a collection of objects starts at 0):
document.forms[1].elements[2].value
Now if you want to show the value of the element in a pop-up, simply put this javascript in your URL Address bar and hit enter:
javascript: alert(document.forms[1].elements[2].value) MsgBox % wb.document.forms[1].elements[2].value
- Object Name / ID Attribute
You can also use the objects name or ID. For example, in the 2nd form, Find words Input Box id is query. The following JavaScript fed through the address bar would produce the same results:
javascript: alert(document.forms[1].query.value) MsgBox % wb.document.forms[1].query.value
... or if you only know the elements id is query, you could display the value of that element using all, which references all the elements on the webpage:
javascript: alert(document.all.query.value) MsgBox % wb.document.all.query.value
- getElement Methods
If you want to get an element(s) based on limited criteria, you can use the following 3 methods:
- getElementById(id) - returns a reference to the first object with the specified ID
- getElementsByName(name) - Returns a collection of objects with the specified name
- getElementsByTagName(tagname) - Returns a collection of objects with the specified tagname
The following example will display the tip under the Find words Input Box, which is the 6th element on the webpage with a SPAN Tag:
(Note - the item number may be dynamic)
javascript: alert(document.getElementsByTagName('span')[5].innerText) MsgBox % wb.document.getElementsByTagName("span")[5].innerText
Controlling the WebPage
So far we have just retrieved information from the webpage. Now lets start controlling the webpage. Note - if the Javascript doesn't end with a Method, use void 0.
- Focus on a Webpage Element - Focus()
Sets the focus to the Find words Input Box:
javascript: document.all.query.focus() wb.document.all.query.focus()
- Click on a Webpage Element - Click()
Clicks the Search Now button:
javascript: document.all.submit.click() wb.document.submit.click()
- Set Value of an Input Field - Value
Sets the value of the Find words Input Box:
javascript: document.all.query.value = 'Input Value'; void 0 wb.document.all.query.value := "Input Value"
- Dropdown Box Selection - selectedIndex
<select name="search_content" id="search_content"> <option value="both">Search title and content</option> <option value="titles">Only search in titles</option> <option value="content">Only search in content</option> </select>
This is the HTML for the Match Dropdown. The following will set the Dropdown to Only search in titles:
javascript: document.all.search_content.selectedIndex = 1; void 0 // .value = 'titles' wb.document.all.search_content.selectedIndex = 1 ;// .value := "titles"
- Radio / Checkbox Selection - Checked
Sets the Search in section radio to Members:
javascript: document.all.radio_members.checked = true; void 0 wb.document.all.radio_members.checked := true
- Get Text from a WebPage Element - innerText
Say you want to get the text from the Navigation options at the top of the page (innerHTML will give you all the HTML):
text := wb.document.all.primary_nav.innerText
... or if you want all the text (or html) from the page:
text := wb.document.documentElement.innerText
There you have it! These techniques should help get you started. Next, I would recommend the following:
- Try these Controls out on some of your favorite webpages.
- Find some more Javascript examples, and then try "translating" them to COM. (Javascript is well documented online)
- Learn additional ways to access the HTML DOM.
You may be wondering, "How do I find information about the element so I can access it?" Good question! The following tools can help you with that.
Helpful Tools
- iWebBrowser2 Learner - This program will give you information about IE webpage elements as you hover over them.
- IE HTML Element Spy - This program will show you the information and source code of each element by dragging the curser over the webpage.
Frequently Asked Questions
- What is a wb?
An AHK object that contains the web browser object (Internet Explorer). Here is a simple script for creating one:
wb := ComObjCreate("InternetExplorer.Application") ;// Create an IE object wb.Visible := true ;// Make the IE object visible wb.Navigate("www.AutoHotkey.com") ;// Navigate to a webpage
- How to access an existing IE object?
Access an IE object by WinTitle and Internet Explorer_Server Number:
WBGet(WinTitle="ahk_class IEFrame", Svr#=1) { ;// based on ComObjQuery docs static msg := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT") , IID := "{0002DF05-0000-0000-C000-000000000046}" ;// IID_IWebBrowserApp ;// , IID := "{332C4427-26CB-11D0-B483-00C04FD90119}" ;// IID_IHTMLWindow2 SendMessage msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle% if (ErrorLevel != "FAIL") { lResult:=ErrorLevel, VarSetCapacity(GUID,16,0) if DllCall("ole32\CLSIDFromString", "wstr","{332C4425-26CB-11D0-B483-00C04FD90119}", "ptr",&GUID) >= 0 { DllCall("oleacc\ObjectFromLresult", "ptr",lResult, "ptr",&GUID, "ptr",0, "ptr*",pdoc) return ComObj(9,ComObjQuery(pdoc,IID,IID),1), ObjRelease(pdoc) } } }
Access an IE object by Window/Tab Name:
IEGet(name="") { IfEqual, Name,, WinGetTitle, Name, ahk_class IEFrame ;// Get active window if no parameter Name := (Name="New Tab - Windows Internet Explorer")? "about:Tabs":RegExReplace(Name, " - (Windows|Microsoft)? ?Internet Explorer$") for wb in ComObjCreate("Shell.Application").Windows() if wb.LocationName=Name and InStr(wb.FullName, "iexplore.exe") return wb }
*For information how these functions differ, see this post.
- How to know when the webpage in done loading?
You can use the Busy and/or ReadyState property, which should work in most scenarios:
wb.Navigate("www.AutoHotkey.com") while wb.busy or wb.ReadyState != 4 Sleep 10
... or here is an example using the DocumentComplete event:
ComObjConnect(wb, "IE_") ;// Connect the webbrowser object loading := true ;// Set the variable "loading" as TRUE wb.Navigate("www.AutoHotkey.com") while loading Sleep 10 MsgBox DONE! ComObjConnect(wb) ;// Disconnect the webbrowser object (or just wb := "") IE_DocumentComplete() { ;// "IE_" prefix corresponds to the 2nd param in ComObjConnect() global loading := false ;// Break the While-Loop }
- What if all this stuff is too confusing for me?
Try this Tutorial written by Mickers which is designed to help non-coders (n00bz) grasp the basic concepts of AutoHotkey_L COM: Basic Ahk_L COM Tutorial for Webpages