AHK-如何创建将与网站按钮交互的脚本

时间:2019-11-08 13:53:25

标签: autohotkey

我正在寻找可以帮助我创建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>

我不知道从哪里开始。尽管我希望有人创建脚本,但我只能复制粘贴,但如果我将来某个时候需要进行一些更改,它仍然需要一些解释。

1 个答案:

答案 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
}