我正在寻找可以帮助我创建AHK脚本的人,该脚本将单击网站上的一系列按钮。
它必须在页面上单击的第一个按钮是:
<button class="btn btn-primary pull-right" onclick="document.getElementById('btnCommentAdd').click()">Add comment</button>
然后将弹出一个窗口,其中有一个下拉菜单,其中需要选择以下<option>Har selv sign up, men har spg</option>
完整代码:
<select id="inpCommentCategories" class="form-control">
<option value="0">Category</option>
<option>Sign up</option>
<option>Har selv sign up, men har spg</option>
<option>Ikke sign up endnu, men har spg</option>
<option>Ombooking af tekniker dato</option>
<option>Udenfor området</option>
<option>Produkt/Internet spg</option>
<option>Gravearbejde</option>
<option>Telefonnummer ændring</option>
<option>Har ikke en mail adresse</option>
<option>Tekniker klage</option>
<option>Klage</option>
<option>Tekniker (udeblev, forsinket)</option>
<option>Tekniker (ønsker kontakt)</option>
<option>Nåede ikke sign up</option>
<option>Reetablering</option>
<option>Sign off</option>
<option>Oprettelse af KAP Installation</option>
<option>Oprettelse af Site Survey</option>
<option>Booket til KAP, fiber ikke skudt ind</option>
<option>Fejl</option>
<option>Øvrige</option>
</select>
然后作为最后一步,必须单击“提交”按钮。
<button id="btnCommentSubmit" class="btn btn-primary">Submit</button>
我不知道从哪里开始。尽管我希望有人创建脚本,但我只能复制粘贴,但如果我将来某个时候需要进行一些更改,它仍然需要一些解释。
答案 0 :(得分:0)
为了使AutoHotkey直接与网页的HTML交互,必须使用COM文档对象。这使用基本的JavaScript语言与各种对象进行接口。但是,为了入门,这里是我的一个项目中的基本工具,欢迎您使用。我重新打包方法的唯一原因是在某些失败时进行自定义事件处理。
这将帮助您入门。我有一个使用下面详细介绍的对象导航到网页的直接示例
; Create a new window and navigate
obj_servnow := ComObjCreate("InternetExplorer.Application") ; Create the object
srv_now_hwnd := IE_Handler.GetHwnd(obj_servnow) ; Store the Window ID so you can do stuff if it closes
IE_Handler.NavToUrl(obj_servnow, navURL) ; Navigate to URL
IE_Handler.WaitNotBusy(obj_servnow) ; Wait for the window to load.
COM是挑剔的,如果您不小心,它将在所有地方抛出异常。
我在AutoHotkey 2.0 Alpha
中编写了此代码,如果您要使用其他版本,则必须进行转换,因为大多数函数的语法完全不同。
class IE_Handler
{
; PURPOSE
; * To give a universal Handler method for all the IE windows used in this script.
; * To enable better/smoother exception handling
; * Get methods should always return a value.
GetHwnd(ByRef pwb)
{
; pwb - OBJECT - Internet Explorer COM object
Try
{
return pwb.hwnd
}
Catch
{
return false
}
}
GetFieldById(ByRef pwb, s)
{
; pwb - OBJECT - Internet Explorer COM object
; s - STRING - ID of field that has an appropriate value tag
; No exception is thrown, instead return empty value.
Try
{
return pwb.Document.GetElementById(s).value
}
Catch
{
return ""
}
}
GetByWindow(winId)
{
; winId - INT - AHK 2.0 returns int for win IDs.
; Use WinExist or similar function to get the window handle of an IE window.
; This allows the program to connect to a specific window.
; Method is used during startup and ShellMessags
if (!winId || !RegExMatch(winId, this.hwnd_regex))
{
Throw Exception("Unexpected Window ID Passed " . winId)
}
for pwb in ComObjCreate("Shell.Application").Windows
{
Try
{
if InStr(pwb.FullName, "iexplore.exe") && winId == pwb.HWND
{
; Return literal object for use
return pwb
}
}
Catch
{
; Catch is total failure to obtain the window.
; Maybe it was closed while the loop was running.
Throw Exception("COM Error in locating object by window ID " . winId)
}
}
Throw Exception("Unable to locate provided window ID " . winId)
}
GetInnerHTMLByClassIndex(ByRef pwb, s, i)
{
; pwb - OBJECT - Internet Explorer COM object
; s - STRING - Class name of tags to search
; i - INT - Integer for the array given by GetElementsByClassName
if (i < 0)
{
Throw Exception("Unexpected index less than zero: " . i)
}
Try
{
return pwb.Document.GetElementsByClassName(s)[i].innerHTML
}
Catch
{
return ""
}
}
GetDOMById(ByRef pwb, s)
{
; pwb - OBJECT - Internet Explorer COM object
; s - STRING - Class name of tags to search
; Returns object hook for a web page element
Try
{
return pwb.Document.GetElementById(s)
}
Catch
{
; This method is meant to be tested during variable assignment, so return false if unable to interface with the specified element.
return false
}
}
GetDOMByClassIndex(ByRef pwb, s, i)
{
; pwb - OBJECT - Internet Explorer COM object
; s - STRING - Class name of tags to search
; i - INT - Integer for the array given by GetElementsByClassName
if (i < 0)
{
Throw Exception("Unexpected index less than zero: " . i)
}
Try
{
return pwb.Document.GetElementsByClassName(s)[i]
}
Catch
{
; This method is meant to be tested during variable assignment, so return false if unable to interface with the specified element.
return false
}
}
SetProperty(ByRef pwb, property, val)
{
; pwb - OBJECT - Internet Explorer COM object
; property - STRING - Name of the property to change of the IE object. (toolbar, menubar, visible, statusbar, etc.)
; val - INT - Range from -1 to 1 (0 is false) (Trinary operator)
; Exclusive to 2.0, strlower and strupper
; https://lexikos.github.io/v2/docs/commands/StrLower.htm
property := StrLower(property)
; Each of these would be a check for != so the ! can go like !(expression)
; To invert the whole conditional phrase
if !(property = "toolbar" || property = "visible" || property = "menubar")
{
Throw Exception("Unexpected property passed " . property)
}
if (val < -1 || val > 1)
{
Throw Exception("Unexpected value passed " . val)
}
Try
{
pwb.%property% := val
return true
}
Catch
{
; Update over 2.2 - Used to throw exception here.
; Just gonna return false
return false
}
}
SetInnerHTMLById(ByRef pwb, s, v)
{
; pwb - OBJECT - Internet Explorer COM object
; s - STRING - Field ID of the desired tag
; v - STRING - Value to set innerHTML
; No exception is thrown, instead return true or false
Try
{
pwb.document.getElementById(s).innerHTML := v
return true
}
Catch
{
return false
}
}
SetFieldById(ByRef pwb, s, v)
{
; pwb - OBJECT - Internet Explorer COM object
; s - STRING - Field ID of the desired tag
; v - STRING - Value to set value (usually html <input>)
; This function can fail if the proper HTML field is not found
; That is why it does not throw an exception
Try
{
pwb.Document.GetElementById(s).value := v
return true
}
Catch
{
return false
}
}
CloseHiddenWindows(ignoreWin := false)
{
; Close invisible windows. Allow option to ignore a specific hwnd if so choosing to.
Try
{
for pwb in ComObjCreate("Shell.Application").Windows
{
if (InStr(pwb.FullName, "iexplore.exe") && pwb.Visible = 0 && pwb.hwnd != ignoreWin)
{
pwb.Quit()
}
}
}
; No catch desired here.
}
WaitNotBusy(ByRef pwb)
{
; pwb - OBJECT - Internet Explorer COM object
; ReadyState is a more reliable determination as opposed to IE_Com.Busy property.
; 1 = Request sent
; 2 = Request received
; 3 = Request processing
; 4 = Page is done sending/receiving.
; IE_Com.Busy property is either true or false.
Try
{
Loop 100
{
Sleep(100)
if (pwb.ReadyState = 4 || !pwb.Busy)
{
; This is a normal exit
return true
}
}
; Failed to wait all the way
return false
}
Catch
{
; 11/15/2019 - Returning false instead of throwing exception
; Throw Exception("COM ERROR - Unable to check ReadyState for passed object")
return false
}
}
NavToUrl(ByRef pwb, url)
{
; pwb - OBJECT - Internet Explorer COM object
; url - STRING - Actual URL, NOT regular expressions
if !RegExMatch(url, "^https?://*")
{
Throw Exception("Invalid URL passed: " . url)
}
Try
{
pwb.Navigate(url)
}
Catch
{
Throw Exception("COM ERROR - Unable to call Navigate function")
}
}
Kill(ByRef pwb)
{
; pwb - OBJECT - Internet Explorer COM object
Try
{
; Make the window invisible, then kill it quietly.
pwb.Visible := 0
pwb.Quit()
return true
}
Catch
{
return false
}
}
Refresh(ByRef pwb)
{
; pwb - OBJECT - Internet Explorer COM object
Try
{
pwb.Refresh()
return true
}
Catch
{
return false
}
}
; End of class IE Handler :D
}