AHK - Как создать скрипт, который будет взаимодействовать с кнопками сайта - PullRequest
0 голосов
/ 08 ноября 2019

Я ищу кого-нибудь, кто поможет мне создать скрипт 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 голосов
/ 16 ноября 2019

Чтобы интерфейс 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
}
...