Source: Jethrow @ Autohotkey Forums
Basic Webpage Controls with JavaScript / COM
This tutorial requires one of the following:
- AutoHotkey_L - has built-in COM Support (recommended)
- the COM Standard Library - for use with AHK Basic
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.
Disclaimers
For this tutorial, I will show you how to control webpages using JavaScript, along with the AHK COM "translations" (AutoHotkey_L in Black, AHK Basic in Green) - also, note Sean's post below. (Using COM requires Internet Explorer, but JavaScript can be used with most Web Browsers) The guidelines for "translating" JavaScript can be found in the first post of the COM Standard Library thread (for AHK Basic).
Color Legend wrote: |
Javascript: dark blue
AutoHotkey_L: black AHK Basic: green |
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_L
- Sean & fincs for helping with Native COM Support
- Sean for creating the COM Standard Library
- tank for the tutorial listed above, & daonlyfreez
- tank, sinkfaze, & jaco0646 for reviewing this tutorial
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:
Code: |
javascript: alert('Hello World!')
pwb.Navigate("javascript: alert('Hello World!')") COM_Invoke(pwb, "Navigate", "javascript: alert('Hello World!')") |
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 & Index
Say you want to get the value of the 1st element in the 1st form, which will be the Search for Keywords Input Box. The path would look like this (a collection of objects starts at 0):
Code: |
document.forms[0].elements[0].value |
Code: |
javascript: alert(document.forms[0].elements[0].value)
MsgBox % pwb.document.forms[0].elements[0].value MsgBox % COM_Invoke(pwb, "document.forms[0].elements[0].value") |
You can also use the objects name or ID. For example, the 1st forms name is SearchForm, with its 1st elements name being search_keywords. The following javascript fed throught the address bar would produce the same results:
Code: |
javascript: alert(document.SearchForm.search_keywords.value)
MsgBox % pwb.document.SearchForm.search_keywords.value MsgBox % COM_Invoke(pwb, "document.SearchForm.search_keywords.value") |
Code: |
javascript: alert(document.all.search_keywords.value)
MsgBox % pwb.document.all.search_keywords.value MsgBox % COM_Invoke(pwb, "document.all.search_keywords.value") |
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
(Note - the item number may be dynamic)
Code: |
javascript: alert(document.getElementsByTagName('input')[3].value)
MsgBox % pwb.document.getElementsByTagName("input")[3].value MsgBox % COM_Invoke(pwb, "document.getElementsByTagName[input].item[3].value") |
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 Search for Keywords Input Box:
Code: |
javascript: document.all.search_keywords.focus()
pwb.document.all.search_keywords.focus() COM_Invoke(pwb, "document.all.search_keywords.focus") |
Clicks the Search button:
Code: |
javascript: document.getElementsByTagName('input')[11].click()
pwb.document.getElementsByTagName("input")[11].click() COM_Invoke(pwb, "document.getElementsByTagName[input].item[11].click") |
Sets the value of the Search for Keywords Input Box:
Code: |
javascript: document.all.search_keywords.value = 'Input Value'; void 0
pwb.document.all.search_keywords.value := "Input Value" COM_Invoke(pwb, "document.all.search_keywords.value", "Input Value") |
Quote: |
<SELECT class=post name=sort_by><OPTION selected value=0>Post Time</OPTION><OPTION value=1>Post Subject</OPTION><OPTION value=2>Topic Title</OPTION><OPTION value=3>Author</OPTION><OPTION value=4>Forum</OPTION></SELECT> |
Code: |
javascript: document.all.sort_by.selectedIndex = 3; void 0 ; Note - you could use value = 3
pwb.document.all.sort_by.selectedIndex := 3 COM_Invoke(pwb, "document.all.sort_by.selectedIndex", 3) |
Quote: |
<INPUT value=ASC type=radio name=sort_dir> Ascending<BR><INPUT value=DESC CHECKED type=radio name=sort_dir> Descending |
Code: |
javascript: document.all.sort_dir[0].checked = true; void 0
pwb.document.all.sort_dir[0].checked := True COM_Invoke(pwb, "document.all.sort_dir[0].checked", True) |
Say you want to get the text at the top of the page (innerHTML will give you all the HTML):
Code: |
text := pwb.document.getElementsByTagName("TD")[2].innerText
text := COM_Invoke(pwb, "document.getElementsByTagName[TD].item[2].innerText") |
Code: |
text := pwb.document.documentElement.innerText
text := COM_Invoke(pwb, "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.
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 pwb?
- A variable that contains a pointer to the web browser object (Internet Explorer). Here is a simple script for creating one:
Code: |
; AutoHotkey_L:
pwb := ComObjCreate( "InternetExplorer.Application" ) ; Create an IE object pwb.Visible := True ; Make the IE object visible pwb.Navigate( "www.AutoHotkey.com" ) ; Navigate to a webpage |
Code: |
; AHK Basic:
COM_Init() ; Initialize COM pwb := COM_CreateObject( "InternetExplorer.Application" ) ; Create an IE object COM_Invoke( pwb, "Visible", True ) ; Make the IE object visible COM_Invoke( pwb, "Navigate", "www.AutoHotkey.com" ) ; Navigate to a webpage ; when finished COM_Release( pwb ) ; Always release COM objects COM_Term() ; Always Uninitialize COM |
How to access an existing IE object?
- Sean's GetWebBrowser() function is great for this, and can be found here. Here is a function that accesses an IE object by window name:
Code: |
; AutoHotkey_L:
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 pwb in ComObjCreate( "Shell.Application" ).Windows If ( pwb.LocationName = Name ) && InStr( pwb.FullName, "iexplore.exe" ) Return pwb } |
Code: |
; AHK Basic:
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" ) oShell := COM_CreateObject( "Shell.Application" ) ; Contains reference to all explorer windows Loop, % COM_Invoke( oShell, "Windows.Count" ) { If pwb := COM_Invoke( oShell, "Windows.item[" A_Index-1 "]" ) If ( COM_Invoke( pwb, "LocationName" ) = name && InStr( COM_Invoke( pwb, "FullName" ), "iexplore.exe" ) ) Break COM_Release( pwb ), pwb := "" } COM_Release( oShell ) Return, pwb } |
How to know when the webpage in done loading?
- Sean's IEReady() function is great for this, and can be found here. Here is an example using the ReadyState property, which should work in may scenarios:
Code: |
; AutoHotkey_L:
pwb.Navigate( "www.AutoHotkey.com" ) While, pwb.ReadyState <> 4 ; While, pwb.Busy Sleep, 10 |
Code: |
; AHK Basic:
COM_Invoke( pwb, "Navigate", "www.AutoHotkey.com" ) While, COM_Invoke( pwb, "ReadyState" ) <> 4 ; While, COM_Invoke( pwb, "Busy" ) Sleep, 10 |
- OR - here is an example using the DocumentComplete event:
Code: |
; AutoHotkey_L:
pwb := ComObjCreate( "InternetExplorer.Application" ) pwb.Visible := True ComObjConnect( pwb, "IE_" ), loading = 1 ; Connect IE object & set var "loading" as TRUE pwb.Navigate( "www.AutoHotkey.com" ) While, loading Sleep, 10 MsgBox, DONE! ComObjConnect( pwb ) ; Disconnect IE object Return IE_DocumentComplete() { ; the "IE_" prefix corresponds to the ComObjConnect() function above Global loading = 0 ; Break the While-Loop } |
Code: |
; AHK Basic:
COM_Init() pwb := COM_CreateObject( "InternetExplorer.Application" ) COM_Invoke( pwb, "Visible", "True" ) sink := COM_ConnectObject( pwb, "IE_" ), loading = 1 ; Connect IE object & set var "loading" as TRUE COM_Invoke( pwb, "Navigate", "www.AutoHotkey.com" ) While, loading Sleep, 10 MsgBox, DONE! COM_DisconnectObject( sink ) ; Disconnect IE object COM_Release( pwb ), COM_Term() Return IE_DocumentComplete() { ; the "IE_" prefix corresponds to the COM_ConnectObject() function above Global loading = 0 ; 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
- I would recommend tank's iWeb Functions, which are designed to make web automation more simple. (original is AHK Basic only, but here is an AutoHotkey_L Version by sinkfaze)
Basic Webpage Controls
COM Object Reference
Last edited by jethrow on Wed Jun 22, 2011 10:18 pm; edited 22 times in total
Source: Jethrow @ Autohotkey Forums