Automating Chrome with AutoHotkey: Getting InnerText, OuterHTML & Values

AutoHotkey Merchandise-White Stress ballBeing able to Automate Chrome has been a long-time goal of mine.  With GeekDude’s Chrome.ahk Class you now can do this.  Read more about his class on the AHK forum here.

If you didn’t see it, also check out my other tutorial on Setting values with Chrome and AutoHotkey.

 

Here is the function I demonstrate in the below video on Automating Chrome with AutoHotkey: Getting InnerText, OuterHTML & Values
Tab := Chrome.GetTab() ;Connect to Active tab

;********************Methd: Class, Tag, Name, ID **** ***********************************
data:=Chm_Get(Tab,Method:=”Name”,Attribute:=”s”,Index:=2)
;~ MsgBox % data.InnerText
DebugWindow(ExploreObj(data),1,1,200,0)

;********************Method: Class, Tag, Name, ID **** ***********************************
;********************Get Property***********************************
Chm_Get(Tab,Method=”Class”,Attribute=”hfeed”,Index=1){
Obj:={}
;***********Class*******************
if (Format(“{:L}”,Method)=”class”){ ;Case-insensitive check to see if method = Class
Obj.OuterHTML:= Tab.Evaluate(“document.getElementsByClassName(‘” Attribute “‘)[” Index-1 “].outerHTML”).Value
Obj.Value:= Tab.Evaluate(“document.getElementsByClassName(‘” Attribute “‘)[” Index-1 “].value”).Value
Obj.InnerText:= Tab.Evaluate(“document.getElementsByClassName(‘” Attribute “‘)[” Index-1 “].innerText”).Value
Obj.TextContent:= Tab.Evaluate(“document.getElementsByClassName(‘” Attribute “‘)[” Index-1 “].textContent”).Value
} ;***********Tag*******************
Else if (Format(“{:L}”,Method)=”tag”){ ;Case-insensitive check to see if method = Tag
Obj.OuterHTML:= Tab.Evaluate(“document.getElementsByTagName(‘” Attribute “‘)[” Index-1 “].outerHTML”).Value
Obj.Value:= Tab.Evaluate(“document.getElementsByTagName(‘” Attribute “‘)[” Index-1 “].value”).Value
Obj.InnerText:= Tab.Evaluate(“document.getElementsByTagName(‘” Attribute “‘)[” Index-1 “].innerText”).Value
Obj.TextContent:= Tab.Evaluate(“document.getElementsByTagName(‘” Attribute “‘)[” Index-1 “].textContent”).Value
} ;************Name******************
Else if (Format(“{:L}”,Method)=”name”){ ;Case-insensitive check to see if method = Name
Obj.OuterHTML:= Tab.Evaluate(“document.getElementsByName(‘” Attribute “‘)[” Index-1 “].outerHTML”).Value
Obj.Value:= Tab.Evaluate(“document.getElementsByName(‘” Attribute “‘)[” Index-1 “].value”).Value
Obj.InnerText:= Tab.Evaluate(“document.getElementsByName(‘” Attribute “‘)[” Index-1 “].innerText”).Value
Obj.TextContent:= Tab.Evaluate(“document.getElementsByName(‘” Attribute “‘)[” Index-1 “].textContent”).Value
} ;***********ID*******************
Else if (Format(“{:L}”,Method)=”id”){ ;Case-insensitive check to see if method = ID
Obj.OuterHTML:= Tab.Evaluate(“document.getElementById(‘” Attribute “‘).outerHTML”).Value
Obj.Value:= Tab.Evaluate(“document.getElementById(‘” Attribute “‘).value”).Value
Obj.InnerText:= Tab.Evaluate(“document.getElementById(‘” Attribute “‘).innerText”).Value
Obj.TextContent:= Tab.Evaluate(“document.getElementById(‘” Attribute “‘).textContent”).Value
} Else{ MsgBox fix Attribute- Valid values are: Name, Class, Tag, ID
}
return obj
}

 

 

 

Video Tutorial Automating Chrome with AutoHotkey: Getting InnerText, OuterHTML & Values

Automating Chrome with AutoHotkey: Setting InnerText, OuterHTML & Values

Person reading a newspaper at a desk beside a black water bottle with a green logo and a laptopWeb Scraping is Amazing!  Being able to automate Chrome with AutoHotkey has been a long-term goal of mine!  In this video I (quickly) walk through a function I wrote to leverage GeekDude’s Chrome.ahk class.  You can get the class here or read more about it on the AutoHotkey forum.

There’s lots more to do but I wanted to share this to help others get started using the above Class.  :)

Here is the code I demonstrate in the below video where I demonstrate  setting text in Chrome with AutoHotkey.

#Include B:\Progs\AutoHotkey_L\AHK Work\WebPage\Chrome\Examples\Chrome.ahk  ;GeekDude Class ; https://github.com/G33kDude/Chrome.ahk  https://autohotkey.com/boards/viewtopic.php?t=42890
Tab:=Chm_Create_Instance("C:\Users\joe\AppData\Local\Google\Chrome\User Data\Default") ;Create instance using default Profile
Chm_Navigate(Tab,"https://the-automator.com") ;Navigate to a URL
Chm_Set(Tab,Method:="Class",Attribute:="s",Index:=2,Property:="v",Value:="Just a test")
;~ Chm_Set(Tab,Method:="Name",Attribute:="s",Index:=2,Property:="v",Value:="Just another test")
;~ Chm_Set(Tab,Method:="tag",Attribute:="Input",Index:=1,Property:="v",Value:="Just a test")
;~ Chm_Set(Tab,Method:="ID",Attribute:="cat",Index:=2,Property:="v",Value:="11")

;********************Chrome Set Property******* Propterty=  i=innerText v=Value  o=outerHTML****************************
Chm_Set(Tab,Method="Class",Attribute="hfeed",Index=1,Property="i",Value=""){
  ;***********Class*******************
  if (Format("{:L}",Method)="class"){  ;Case-insensitive check to see if method = Class
    if (Format("{:L}",Property)="o") ;If Property="o" then set OuterHTML
      Tab.Evaluate("document.getElementsByClassName('" Attribute "')[" Index-1 "].outerHTML='" Value "'").Value
    Else if (Format("{:L}",Property)="v") ;If Property="v" then set Value
      Tab.Evaluate("document.getElementsByClassName('" Attribute "')[" Index-1 "].value='" Value "'").Value
    Else if (Format("{:L}",Property)="i") ;If Property="i" then set innerText
      Tab.Evaluate("document.getElementsByClassName('" Attribute "')[" Index-1 "].innerText='" Value "'").Value
  } ;***********Tag*******************
  Else if (Format("{:L}",Method)="tag"){ ;Case-insensitive check to see if method = Tag
    if (Format("{:L}",Property)="o") ;If Property="o" then set OuterHTML
      Tab.Evaluate("document.getElementsByTagName('" Attribute "')[" Index-1 "].outerHTML='" Value "'").Value
    Else if (Format("{:L}",Property)="v") ;If Property="v" then set Value
      Tab.Evaluate("document.getElementsByTagName('" Attribute "')[" Index-1 "].value='" Value "'").Value
    Else if (Format("{:L}",Property)="i") ;If Property="i" then set innerText
      Tab.Evaluate("document.getElementsByTagName('" Attribute "')[" Index-1 "].innerText='" Value "'").Value
  } ;***********Name*******************
  Else if (Format("{:L}",Method)="Name"){ ;Case-insensitive check to see if method = Name
    if (Format("{:L}",Property)="o") ;If Property="o" then set OuterHTML
      Tab.Evaluate("document.getElementsByName('" Attribute "')[" Index-1 "].outerHTML='" Value "'").Value
    Else if (Format("{:L}",Property)="v") ;If Property="v" then set Value
      Tab.Evaluate("document.getElementsByName('" Attribute "')[" Index-1 "].value='" Value "'").Value
    Else if (Format("{:L}",Property)="i") ;If Property="i" then set innerText
      Tab.Evaluate("document.getElementsByName('" Attribute "')[" Index-1 "].innerText='" Value "'").Value
  } ;***********ID*******************
  Else if (Format("{:L}",Method)="id"){ ;Case-insensitive check to see if method = ID
    if (Format("{:L}",Property)="o") ;If Property="o" then set OuterHTML
      Tab.Evaluate("document.getElementById('" Attribute "').outerHTML='" Value "'").Value
    Else if (Format("{:L}",Property)="v") ;If Property="v" then set Value
      Tab.Evaluate("document.getElementById('" Attribute "').value='" Value "'").Value
    Else if (Format("{:L}",Property)="i") ;If Property="i" then set innerText
      Tab.Evaluate("document.getElementById('" Attribute "').innerText='" Value "'").Value
  } Else{ 	MsgBox fix Method- Valid values are: Name, Class, Tag, ID (case of text does not matter)
}
}
;********************Create instance and use a path to profile***********************************
Chm_Create_Instance(Profile_Path=""){
 if !(Profile_Path){
 FileCreateDir, ChromeProfile ;Make sure folder exists
 ChromeInst := new Chrome("ChromeProfile") ;Create a new Chrome Instance
 }Else{
 try ChromeInst := new Chrome(Profile_Path) ;Create for profile lookup prfile by putting this in your url in Chrome chrome://version/
 }
 return Tab := ChromeInst.GetTab() ;Connect to Active tab
}
;********************Navigate to page***********************************
;~ Chm_Navigate(Tab,"https://the-automator.com")
Chm_Navigate(Tab,URL){
 Tab.Call("Page.navigate", {"url": URL}) ;Navigate to URL
 Tab.WaitForLoad() ;Wait for page to finish loading
}

 

Here’s the video walking through how to use the function with the above

Chrome.ahk Class to setting text in Chrome with AutoHotkey

 

 

Web Scraping with AutoHotkey 110- Saving Files / Images from a URL / Hyperlink

Saving Files / Images from a URL / HyperlinkWhile URLDownloadToFile is a built-in function for downloading binary files (Images, Word files, Spreadsheets, etc.) I’ve, and others, have had issues using it (I think it was that I was behind a proxy at work).   In the below video I demonstrate how to use the URLDownloadToFile command as well as demonstrate a function I borrowed from Maestrith (Author of AutoHotkey Studio).

Saving Files / Images from a URL / Hyperlink

 

Here is the code I walk through in the first part of the above video (demonstrating the built-in functionality and an example calling the function.

#SingleInstance,Force
;*************URL download to File*************************
url:="https://i2.wp.com/www.toptenia.com/wp-content/uploads/2017/08/gal-gadot.jpg"
;*********************url Download to file**********************************
UrlDownloadToFile, % url, % "Gal_Gadot_URLDownload.jpg" ;simple built-in way to download a file given a url

Download_File_XMLHTTP(URL) ;Call the function
;********************created by Maestrith but tweaked by Joe Glines***********************************
Download_File_XMLHTTP(URL){
	SplitPath,URL,File_Name ;get file name from URL
	req:=ComObjCreate("MSXML2.XMLHTTP.6.0"),ado:=ComObjCreate("ADODB.Stream")
	req.Open("HEAD",URL),req.Send() 
	ado.Type:=1
	req.Open("GET",URL,1),req.Send()
	while(req.ReadyState!=4){
		Sleep,50
	}
	ado.Open(),ado.Write(req.ResponseBody),ado.SaveToFile(File_Name,2),ado.Close()
	Sleep, 100
}

Bearded man in denim shirt and woman in white top reviewing papers and a laptop together at a desk with coffee

And here is the code where I demonstrate how you can get a list of images and iterate over them in an object (calling the download function)

#SingleInstance,Force
global Obj:=[] ;Creates obj holder for variables
;**************************************
pwb := WBGet()
MsgBox % pwb.document.images.length ;Show how many images there are
ComObjError(false)  ;Need to turn off so doesn't trigger error
;******example with While loop***Note a_index-1 is in first row, not each individual one*	 
While(ele:=pwb.document.links[a_index-1]){ ;store reference to element in ele While looping over elements
	if InStr(ele.href,"https://www.google.com/imgres?imgurl="){ ;if one of the images from Google.com
		obj.InsertAt(A_index-1,StrSplit(uri_decode(StrSplit(ele.href,"https://www.google.com/imgres?imgurl=").2),["?","&"]).1) ;Strip out a lot of the un-wanted text
	}
}
for k, v in obj{
	Download_File_XMLHTTP(v)
	Sleep, 100
}
ComObjError(True)  ;Turn back on
;********************created by Maestrith but tweaked by Joe Glines***********************************
Download_File_XMLHTTP(URL){
	SplitPath,URL,File_Name ;get file name from URL
	req:=ComObjCreate("MSXML2.XMLHTTP.6.0"),ado:=ComObjCreate("ADODB.Stream")
	req.Open("HEAD",URL),req.Send() 
	ado.Type:=1
	req.Open("GET",URL,1),req.Send()
	while(req.ReadyState!=4){
		Sleep,50
	}
	ado.Open(),ado.Write(req.ResponseBody),ado.SaveToFile(File_Name,2),ado.Close()
	Sleep, 100
}

;~ http://www.autohotkey.com/board/topic/47052-basic-webpage-controls-with-javascript-com-tutorial/
;~ wb := WBGet()
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)
      }
   }
}
Uri_Decode(str) {
		Loop
			If RegExMatch(str, "i)(?<=%)[\da-f]{1,2}", hex)
				StringReplace, str, str, `%%hex%, % Chr("0x" . hex), All
		Else Break
			Return, str
	}
	
Uri_Encode(Uri, full = 0)
	{
		oSC := ComObjCreate("ScriptControl")
		oSC.Language := "JScript"
		Script := "var Encoded = encodeURIComponent(""" . Uri . """)"
		oSC.ExecuteStatement(Script)
		encoded := oSC.Eval("Encoded")
		Return encoded
	}