1 (изменено: sergeiplugatyr, 2014-03-17 20:32:36)

Тема: AHK: Авторизация на сайтах с использованием WinHttpRequest

Всем доброго дня, походу никто не в силах помочь мне с "InternetExplorer" и я решил написать авторизацию на сайте через WinHTTP.
Не получается заполнить поля логин/пароль на сайте vk.com:

URL := "http://vk.com/"
Data2 := "pass= tyt password"
Data1 := "email=tyt mail"
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WebRequest.Open("POST", URL, false)
WebRequest.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
WebRequest.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.0.10)")
Data = %Data1%&%Data2%
WebRequest.Send(Data)
MsgBox, % WebRequest.StatusText
MsgBox, % WebRequest.getAllResponseHeaders()
FileAppend, % WebRequest.responseText, File.txt

А если поставить вместо POST запроса GET, то выдает такую ошибку "Request Entity Too Large"
Жду вашей помощи.

Как сказал мой дед - Я твой дед

2

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Позвольте поинтересоваться - какая конечная цель после авторизации ? Объясню почему спрашиваю - я на VBS ( с помощью коллеги JSMan-а ) собрал авторизацию для API контакта. Дабы сделать сайт скачки музыки из VK. Но авторизация в API и на сайт контакта немного отличается. Поэтому интересуюсь конечной задачей. Да и на IE авторизацию вообще элементарно делать. Только ослик ещё и все картинки и скрипты за собой потянет. Так что не уверен, что это Вам нужно.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

3

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Да и на IE авторизацию вообще элементарно делать

Это я знаю, но мне никто почему то не может помочь перевести скрипт под библиотеку com.ahk дабы он компилировался классической версией компилятора.
Сайт вконтакте я выбрал для примера, а вообще мне для другого сайта нужна авторизация, но я бы на примере контакта переделал под другой сайт уже.

Как сказал мой дед - Я твой дед

4

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

А зачем нужно компилировать старой версией?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

5

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov пишет:

А зачем нужно компилировать старой версией?

Просто это принципиально для меня, а вообще для защиты кода.

Как сказал мой дед - Я твой дед

6

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

mpress ведь тоже защищает код.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

7

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov пишет:

mpress ведь тоже защищает код.

Mpress распаковать очень легко, а старый компилятор чем мне нравится что после упаковки скрипта файл показывает что упакован Microsoft Visual C++.

Как сказал мой дед - Я твой дед

8

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr, так всё таки Вам нужно решение через WinHttpRequest или Internet Explorer ? Или без разницы ? И хотелось бы узнать адрес конечного сайта. Авторизация на разные сайты требует разных технологических решений.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

9

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Я так понимаю, что IE требует comobjcreate, а её нет в старом анк.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

10

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon
Кстати, не могли бы Вы привести ссылку на решение с помощью VBS.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

11

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov пишет:

Я так понимаю, что IE требует comobjcreate, а её нет в старом анк.

В этом то и дело, посмотрите мою тему "Получение страницы через InternetExplorer" и всё поймёте .

Как сказал мой дед - Я твой дед

12

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov пишет:

Xameleon
Кстати, не могли бы Вы привести ссылку на решение с помощью VBS.

Ещё не выкладывал. Собственно надобности пока не было. Код собран в ASP.

sergeiplugatyr, посмотрел тему. Решил на основании той страницы и наваять код.
Не понял зачем там querySelector, ведь все объекты страницы и так доступны.


Option Explicit

Dim oIE
Dim oForm
Set oIE = CreateObject("InternetExplorer.Application")

oIE.Visible = True

oIE.Navigate "http://notepad.cc/login/neeluzbo28"

'Ждём окончания загрузки
SyncNavigate()

'Получаем первую по счёту форму в документе (можно и по ID дёргать если он есть)
Set oForm = oIE.document.forms(0)

'Заполняем поле пароля
oForm("pad[password]").value = "123"

'Сабмитим форму
oForm.submit

'Ждём окончания загрузки
SyncNavigate()

MsgBox "Авторизация завершена"

Sub SyncNavigate()
    Do While oIE.Busy
        WScript.Sleep 100
    Loop
End Sub
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

13 (изменено: sergeiplugatyr, 2014-03-18 17:32:17)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon пишет:

sergeiplugatyr, так всё таки Вам нужно решение через WinHttpRequest или Internet Explorer ? Или без разницы ? И хотелось бы узнать адрес конечного сайта. Авторизация на разные сайты требует разных технологических решений.

Желательно через Internet Explorer, но писать код надо под библиотеку com.ahk чтобы его можно было компилировать старой версией компилятора. Конечный сайт - Ucoz.ru, есть некоторые наработки:

#Include COM.ahk
com := COM_CreateObject("InternetExplorer.Application")
Com_Invoke(com, "Visible", "True")
Com_Invoke(com, "Navigate", "http://tyt site.ucoz.ru/admin/") 
While, COM_Invoke(com, "ReadyState" ) <> 4
    continue
COM_Invoke(com, "document.all[password].value", "tyt pass")
Com_Invoke(com, "document.all[53].click") ; тут не кликает, порядковый номер элемента определен правильно.
While, COM_Invoke(com, "ReadyState" ) <> 4
    continue
COM_Release(com)
COM_Term()

А про WinHttpRequest я подумал потому что уже потерял надежду что мне кто нибудь сможет помочь.

Как сказал мой дед - Я твой дед

14

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Старая версия компилятора позволяет извлекать код скрипта даже если при компиляции задан пароль. Задача не так тривиальна как "скачать unpacker", но решается легко.
Ерундой маешься, нужна защита - используй exepackerы, основная масса юзеров не осилит распаковать mpress.

15 (изменено: alexii, 2014-03-19 01:09:55)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Защита, основанная на незнании, порочна по определению.

16

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr

1) Авторизация на Юкоз получилась с минимумом изменений. Код представил ниже.

2) Полностью согласен с bWRmeA. Ковыряться со старым AHK только из-за особенностей компиляции скрипта, когда уже вышли новые версии, простите - бредово.

Полным полно утилит ASPack / ASProtect и т.п.

Я бы вообще на VBS-е собрал и не парился. VBS / JS тоже компилится в EXE. Но я бы так поступил только из-за того что мне VBS привычен. Если Вам AHK привычнее, то можно и на нём скомпилить, но уже в актуальной версии. В которой зачастую внесены исправления старых ошибок. А "защищать" теми же утилитами. Но кроме этого возникает другой вопрос - Что же такое секретное вы хотите запрятать в EXE, чтобы никому это не досталось ? Защитить пароль авторизации ? Это отпадает - любой сниффер покажет, что отправляет EXE модуль. Если вы собираетесь делать приложение для массового использования, то я бы вообще побрезговал непонятными утилитами неизвестного автора в пользу скрипта с открытым кодом. Вообще идею открытого кода уважаю в корне. Не в обиду.

P.S Если Вам в аккаунт нужно файлы какие-то заливать, то проще по FTP протоколу, сайт это позволяет, как я понимаю.


Option Explicit

Dim oIE
Dim oForm
Set oIE = CreateObject("InternetExplorer.Application")

oIE.Visible = True

oIE.Navigate "http://ucoz-tester.ucoz.ru/admin/"

SyncNavigate()

Set oForm = oIE.document.forms(0)

oForm("password").value = "pAsSwOrD"

oForm.submit()

SyncNavigate()

MsgBox "Авторизация завершена"

Sub SyncNavigate()
    Do While oIE.Busy
        WScript.Sleep 100
    Loop
End Sub
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

17

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

а старый компилятор чем мне нравится что после упаковки скрипта файл показывает что упакован Microsoft Visual C++.

alexii Вы про это?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

18

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Если Вам в аккаунт нужно файлы какие-то заливать, то проще по FTP протоколу, сайт это позволяет, как я понимаю.

Вот кстати, тоже интересно на фоне полного не знания FTP. Например, как залить/скачать файл с mail.ru ящика, наиболее просто?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

19

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Вообщем, не хочу конечно раздувать из мухи слона, поэтому только один вопрос:

Com_Invoke(com, "document.all[53].click") ; тут не кликает, порядковый номер элемента определен правильно.

Xameleon, вы извините меня но мне легче на AHK писать, для меня VBS не совсем понятен .

Как сказал мой дед - Я твой дед

20

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov пишет:

Если Вам в аккаунт нужно файлы какие-то заливать, то проще по FTP протоколу, сайт это позволяет, как я понимаю.

Вот кстати, тоже интересно на фоне полного не знания FTP. Например, как залить/скачать файл с mail.ru ящика, наиболее просто?

serzh82saratov, хм. Возможно это будет новостью, но для mail.ru и подобных почтовых серверов самый удобный способ это работа по SMTP и MAPI протоколам.


sergeiplugatyr пишет:

Вообщем, не хочу конечно раздувать из мухи слона, поэтому только один вопрос:

Com_Invoke(com, "document.all[53].click") ; тут не кликает, порядковый номер элемента определен правильно.

Xameleon, вы извините меня но мне легче на AHK писать, для меня VBS не совсем понятен .

Не вопрос. Но тогда хотя бы не возвращайтесь к каменному топору. ) Эволюция приветствуется. По поводу остальных вопросов что-нибудь прояснить можете ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

21

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Изначально была идея написать авторизацию на сайте через библиотеку com.ahk и вот столкнулся с такой проблемой как клик по кнопке. Еще есть вопрос: как сделать авторизацию на какой либо сайт(можно Ucoz) через WinHttpRequest(это чисто для познания, не обязательно ).

Как сказал мой дед - Я твой дед

22

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov, хм. Возможно это будет новостью, но для mail.ru и подобных почтовых серверов самый удобный способ это работа по SMTP и MAPI протоколам.

Раз уж Я начал задавать глупые вопросы, то продолжу. Можно увидеть пример использования одного из этих протоколов на анк, если конечно это не слишком большой код.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

23

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr пишет:

Еще есть вопрос: как сделать авторизацию на какой либо сайт(можно Ucoz) через WinHttpRequest(это чисто для познания, не обязательно ).

На AHK ломает писать. Так что вот Вам пример на JS.


// Создаём объект для запросов по HTTP протоколу
var oHttpRequest = new ActiveXObject("WinHttp.WinHttpRequest.5.1");

// Загружаем основную страницу входа
var oDoc = documentFromURL("http://ucoz-tester.ucoz.ru/admin/")

// Получаем первую по счёту форму
var oForm = oDoc.forms(0)

// Заполняем поле формы
oForm("password").value = "pAsSwOrD"

// Эмулируем отправку формы
submitForm(oForm);

// Загружаем полученный документ из данных HttpRequest-а
oDoc = documentFromHTML(oHttpRequest.responseText, oHttpRequest.Option(1))

// Сохраняем страничку с результатами авторизации
saveTextFile("ucoz.htm", oDoc.documentElement.outerHTML);

WScript.Echo("Страница сайта после авторизации сохранена")

/* Функция загрузки и построения документа с указанного URL */
function documentFromURL(sURL) {
    with (oHttpRequest) {
        open("GET", sURL, false);
        send();
        return documentFromHTML(responseText, sURL)
    }
}

/* Функция построения HTML документа на основании HTML кода 
sBaseURL задаётся для того чтобы ссылки внутри документа ссылались на нужный нам URL. Иначе будет подставляться "about:") */
function documentFromHTML(sHTMLCode, sBaseURL) {
    var oDoc = new ActiveXObject("htmlfile");
    oDoc.open();
    oDoc.write("<base href='" + sBaseURL + "'>")
    oDoc.close();
    oDoc.body.innerHTML = sHTMLCode
    return oDoc
}

/* Функция эмулятор отправки формы */
function submitForm(oForm){
    var oField
    var sBody = ""
    var i
    var sAction
    var sBaseHref

    /* Сборка строки запроса формы */
    for (i=0; i < oForm.elements.length; i++) {
        oField = oForm.elements[i];
        /* Берём только те поля у которых задано имя */
        if (oField.name != '') {
            sBody = sBody + encodeURIComponent(oField.name) + "=" + encodeURIComponent(oField.value) + "&"
        }
    }
    /* Отрезаем на хвосте последний амперсанд */
    sBody = sBody.substring(0, sBody.length - 1);

    /* Т.к сайт потребовал указания Referer, то пришлось вставить вот такую "затычку" */
    try {
        sBaseHref = oForm.document.all.tags("base")[0].href
    } catch (e) {}

    /* Преобразуем путь если он относительный */
    sAction = buildURL(sBaseHref, oForm.action)
    
    with (oHttpRequest) {
        open("POST", sAction, false);
        setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        if (sBaseHref != '') setRequestHeader("Referer", sBaseHref);
        send(sBody);
    }
}

/* Функция для построения полного пути из относительного для URL */
function buildURL(sBaseURL, sURL) {
    /* Для расчёта пути я решил использовать двигло самого HTML документа. */
    var oDoc = documentFromHTML("<a href='" + sURL + "'>", sBaseURL);
    return oDoc.all.tags("a")[0].href
}

/* Функция сохранения данных в текстовый файл 
Вставлена чисто для отладки */
function saveTextFile(sFileName, sText, lMode) {
    if (typeof lMode == 'undefined') lMode = 2;
    new ActiveXObject("Scripting.FileSystemObject").OpenTextFile(sFileName, lMode, true, -1).write(sText);
}
serzh82saratov пишет:

Раз уж Я начал задавать глупые вопросы, то продолжу. Можно увидеть пример использования одного из этих протоколов на анк, если конечно это не слишком большой код.

Конечно можно ) Кто ж Вам запретит. Учимся пользоваться фантастическим поиском гугла. http://lmgtfy.com/?q=AHK+smtp

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

24

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

alexii Вы про это?

alexii пропустил букву, так что смысл вышел прямо противоположный. Конечно же не «прочна», а «порочна». Поправил.

25

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr,  Так как вопрос был про пример на AHK, то совесть мучала, что я Вам код на VBS и JS скинул. В итоге посидел, изучил синтаксис, сваял Вам чудо на этом "фантастическом" языке. Даже с комментами расстарался. Надеюсь это прояснит ситуацию с авторизацией.


; Создаём объект для запросов по HTTP протоколу
global oHttpRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")

; Загружаем основную страницу входа
oHtmlDoc := documentFromURL("http://ucoz-tester.ucoz.ru/admin/")

;Получаем первую по счёту форму
oForm := oHtmlDoc.forms[0]

;Заполняем в форме поле пароля
oForm["password"].value := "pAsSwOrD"

;Эмулируем отправку формы
submitForm(oForm)

;Создаём HTML документ из полученных данных от HttpRequest-а
oHtmlDoc := documentFromHTML(oHttpRequest.responseText, oHttpRequest.Option(1))

;Получаем текст страницы
MsgBox % oHtmlDoc.body.outerText

;Функция загрузки и построения документа с указанного URL
documentFromURL(ByRef sURL) {
    ;Отправляем GET запрос на сервер
    oHttpRequest.open("GET", sURL, false)
    oHttpRequest.send()
    ;Строим из полученных данных документ и возвращаем из функции
    return documentFromHTML(oHttpRequest.responseText, sURL)
}

;Функция создания документа из HTML кода
documentFromHTML(ByRef sHTMLCode, ByRef sBaseURL) {
    ;Создаём объект для парсинга HTML кода
    oDoc := ComObjCreate("htmlfile")
    oDoc.open()
    ;Вставляем базовый тэг чтобы у относительных ссылок была верная адрессация от базового адреса
    oDoc.write("<base href=""" . sBaseURL . """>")
    oDoc.close()
    oDoc.body.innerHTML := sHTMLCode
    return oDoc
}

;Функция эмулятор отправки формы
submitForm(ByRef oForm){
    ;Получаем ссылку на объект Window от документа формы
    oScript := oForm.document.Script
    ;Сборка строки запроса формы
    loop , % oForm.elements.length 
    {
        i++
        if oForm.elements[i].name != ""  
        {
            ;Собираем значения полей формы в строку и кодируем их имена и значения
            sBody .= oScript.encodeURIComponent(oForm.elements[i].name) . "=" . oScript.encodeURIComponent(oForm.elements[i].value) . "&"
        }
    }
    StringLeft, sBody, sBody, StrLen(sBody)-1

    ;Получаем текущий адрес на котором мы находимся (для заполнения referer и настройки свойства "action" формы )
    sCurrentURL := oHttpRequest.Option(1)
    ;Для формы BASE hRef не срабатывает, поэтому искусственно вычисляем полный путь запроса формы
    oForm.action := buildURL(sCurrentURL,oForm.action)

    oHttpRequest.open("POST", oForm.action, false)
    ;Указываем метод кодирования данных
    oHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
    ;Выставляем Referer, дабы сайты не ругались, что мы себя плохо ведём.
    if sCurrentURL != "" 
    {
        oHttpRequest.setRequestHeader("Referer", sCurrentURL)
    }
    ;Отправляем данные формы
    oHttpRequest.send(sBody)
}

;Функция для построения полного пути из относительного для URL
buildURL(ByRef sBaseURL, ByRef sURL) {
    ;Создаём HTML документ с единственной ссылкой
    oDoc := documentFromHTML("<a href=""" . sURL . """>", sBaseURL)
    ;Берём href от этой ссылки.
    return oDoc.all.tags("a")[0].href
}

Готовый скрипт в аттаче.

Post's attachments

test.ahk 2.92 kb, 21 downloads since 2014-03-20 

You don't have the permssions to download the attachments of this post.
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

26

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

По верхнему скрипту, если поменять URL на https://login.vk.com, то все работает.

27

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon пишет:
...

Жутко непонятно и еще более жутко интересно.
Я так понимаю пример для случая, когда требуется ввести только пароль. А если пара логин - пароль?
Видимо кроме

oForm["password"].value := "pAsSwOrD"

еще что-то вроде

oForm["login"].value := "LoGiN"

?

28

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

многобанофф, именно так. )

Чуток допилил. Вот пример авторизации на сайте вконтакта. С логином и паролем как Вы хотели.

P.S Подробности о HTML DOM Document можно посмотреть тут:  ссылка

Люблю эту фразу - "На самом деле сложного в коде ничего нет."

Есть несколько "макро" функций для упрощения обработки HTML содержимого.

documentFromHTML - строит HTML DOM Document на основании переданного текстового содержимого.

documentFromURL - функция надстройка над documentFromHTML. Позволяет сразу загрузить документ с URL

submitForm - функция которая эмулирует отправку формы. На вход принимает объект формы.

Остальной функционал ( выборка тэгов, получение элементов по ID ) уже реализован внутри объектов, которые возвращают эти функции.

Так что всё сводится к простым этапам

1) Запрашиваем данные через documentFromURL.
2) Проверяем результаты загрузки через HttpRequest.Status ( Я это в коде вставлять не стал. Дабы упростить пример до минимума. )
3) Обрабатываем элементы документа через document.all / document.getElementByID и т.п

В итоге параллельно имеем HTTP статусы, HTTP заголовки и т.п ( то чего нам не хватало в IE ) и HTML DOM Document для удобного парсинга страницы.

Будут вопросы - задавайте.


;Константы используемые в WinHttpRequest
global WinHttpRequestOption_EnableRedirects := 6
global WinHttpRequestOption_MaxAutomaticRedirects := 14
global WinHttpRequestOption_EnableHttpsToHttpRedirects := 12

; Создаём объект для запросов по HTTP протоколу
global oHttpRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")

;Включаем автоматические редиректы
oHttpRequest.Option(WinHttpRequestOption_EnableRedirects) := -1
;Включаем автоматические редиректы с HTTP на HTTPS
oHttpRequest.Option(WinHttpRequestOption_EnableHttpsToHttpRedirects) := -1
;Выставляем максимальное количество редиректов
oHttpRequest.Option(WinHttpRequestOption_MaxAutomaticRedirects) := 20

writeLn("Загружаем основную страницу сайта")

; Загружаем основную страницу входа
oHtmlDoc := documentFromURL("http://vk.com")

writeLn("Получаем первую форму")

; Получаем первую по счёту форму
oForm := oHtmlDoc.forms[0]

; Заполняем в форме поле email
oForm["email"].value := "user@gmail.com"
; Заполняем в форме поле пароль
oForm["pass"].value := "pass"

; Эмулируем отправку формы
submitForm(oForm)

; Проверяем - есть ли в тексте сообщение о том, что авторизация прошла успешно
if InStr(oHttpRequest.ResponseText,"LoginDone") <= 0 {
    MsgBox % "Авторизация не удалась ! Проверьте логин и пароль"
    Exit
}

; Загружаем ленту новостей контакта
oHtmlDoc := documentFromURL("http://vk.com/")

; Получаем ссылку на наш основной профиль и "переходим по ней"
oHtmlDoc := documentFromURL(oHtmlDoc.GetElementByID("myprofile").href)

; Выводим текст из блока с именем и фамилией 
MsgBox % oHtmlDoc.GetElementByID("title").innerText

; Функция загрузки и построения документа с указанного URL
documentFromURL(ByRef sURL) {
    writeLn("documentFromURL")
    writeLn("   URL: " . sURL)
    
    ; Отправляем GET запрос на сервер
    oHttpRequest.open("GET", sURL, false)
    oHttpRequest.send()
    
    ; Строим из полученных данных документ и возвращаем из функции
    return documentFromHTML(oHttpRequest.responseText, sURL)
}

; Функция создания документа из HTML кода
documentFromHTML(ByRef sHTMLCode, ByRef sBaseURL) {
    writeLn("documentFromHTML")
    writeLn("   Base URL: " . sBaseURL)
    ; Создаём объект для парсинга HTML кода
    oDoc := ComObjCreate("htmlfile")
    oDoc.open()
    ; Вставляем базовый тэг чтобы у относительных ссылок была верная адрессация от базового адреса
    oDoc.write("<base href=""" . sBaseURL . """>")
    oDoc.close()
    ;oDoc.write(sHTMLCode)
    oDoc.body.innerHTML := sHTMLCode
    return oDoc
}

; Функция эмулятор отправки формы
submitForm(ByRef oForm){
    writeLn("submitForm")
    ; Получаем ссылку на объект Window от документа формы
    oScript := oForm.document.Script
    ; Сборка строки запроса формы
    loop , % oForm.elements.length 
    {
        i++
        if oForm.elements[i].name != ""  
        {
            ; Собираем значения полей формы в строку и кодируем их имена и значения
            sBody .= oScript.encodeURIComponent(oForm.elements[i].name) . "=" . oScript.encodeURIComponent(oForm.elements[i].value) . "&"
        }
    }
    StringLeft, sBody, sBody, StrLen(sBody)-1

    ; Получаем текущий адрес на котором мы находимся (для заполнения referer и настройки свойства "action" формы )
    sCurrentURL := oHttpRequest.Option(1)
    ; Для формы BASE hRef не срабатывает, поэтому искусственно вычисляем полный путь запроса формы
    oForm.action := buildURL(sCurrentURL,oForm.action)

    writeLn("   Referer: " . sCurrentURL)
    writeLn("   form action: " . oForm.action)
    writeLn("   Body: " . sBody)

    oHttpRequest.open("POST", oForm.action, false)
    ; Указываем метод кодирования данных
    oHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
    ; Выставляем Referer, дабы сайты не ругались, что мы себя плохо ведём.
    if sCurrentURL != "" 
    {
        oHttpRequest.setRequestHeader("Referer", sCurrentURL)
    }
    ; Отправляем данные формы
    oHttpRequest.send(sBody)
}

; Функция для построения полного пути из относительного для URL
buildURL(ByRef sBaseURL, ByRef sURL) {
    ; Создаём HTML документ с единственной ссылкой
    oDoc := documentFromHTML("<a href=""" . sURL . """>", sBaseURL)
    ; Берём href от этой ссылки.
    return oDoc.all.tags("a")[0].href
}

; Функция для вывода строки в консоль
writeLn(text){
    write(text . "`r")
}

; Функция для вывода текста в консоль
write(text){
    FileAppend, %text%, *
}

OFFTOP: Вы как хотите, а я в Warface рубиться пошёл. ) Скрипты надоели !

Post's attachments

vk_auth.ahk 4.41 kb, 20 downloads since 2014-03-21 

You don't have the permssions to download the attachments of this post.
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

29

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon пишет:

...
Чуток допилил. Вот пример авторизации на сайте вконтакта. С логином и паролем как Вы хотели.
P.S Подробности о HTML DOM Document можно посмотреть тут:  ссылка
...
Будут вопросы - задавайте.

Я, что называется, ФШОКЕ.
Так много, так просто и с предложением добавки я еще ничего не получал на этом форуме (кроме банов, разумеется).
Вы отныне - мой кумир.

30

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

многобанофф, Ахахах )))

Ну... Как говорится ...

+ открыть спойлер

http://demotivators.to/media/posters/298/27552_kushajte-ne-oblyapajtes.jpg

Ток заранее предупреждаю - я за AHK второй день как сел. Ранее опыта не было. Так что косяки могут быть. Синтаксис и функционал толком не знаю. Мож спецы поправят, если время найдут. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

31 (изменено: sergeiplugatyr, 2014-03-21 12:36:36)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

А как быть если у HTML элемента например у кнопки есть такое:

<a href="/forum" title="Перейти на форум">Форумник</a>

?

Как сказал мой дед - Я твой дед

32

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr, поясните пожалуйста. Не понял смысл вопроса. Что смущает ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

33

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Ладно тогда другой вопрос - почему именно первую форму получаем:

; Получаем первую по счёту форму
oForm := oHtmlDoc.forms[0]

И как тогда определить сколько всего форм и элементов которые относятся к каждой форме

Как сказал мой дед - Я твой дед

34 (изменено: sergeiplugatyr, 2014-03-21 18:03:41)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Да и еще вопрос, как можно остановить загрузку страницы, например в IE есть такое:

pwb.Quit 
Как сказал мой дед - Я твой дед

35

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr

1) Давайте решать вопросы постепенно.

2) Первую форму я взял лишь для простоты примера. Чес слово, я не виноват, что на сайте контакта она первая по счёту. Ну сложилось так.

3) Для определения количества форм можно взять oHtmlDoc.forms.length, а дальше уже перебором  .forms[n]

Как работать с массивами и коллекциями Вы наверняка знаете ? )

4) В случае IE процесс загрузки документа для вас "сокрыт" и управлять Вы им можете благодаря событиям. В нашем же случае с WinHttpRequest, загрузкой управляете Вы сами и Вы решаете - "скармливать" responseText функции построения документа или нет. Поэтому Quit или какое либо другое действие Вы можете совершать на основании необходимых условий.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

36 (изменено: sergeiplugatyr, 2014-03-21 19:57:01)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Как работать с массивами и коллекциями Вы наверняка знаете ?

Разберусь, спасибо.

Как сказал мой дед - Я твой дед

37

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Решил для начала просто запустить скрипт из поста #28 (естественно, вписав логин/пароль) и посмотреть как он работает.
Он выдает сообщение "Online Имя Фамилия". Так и должно быть? Имя и фамилия правильные.
Никаких признаков авторизации не наблюдаю. Или имеется в виду авторизация для дальнейшего получения данных средствами HTML DOM Document?
Проще говоря, я ожидал в результате работы скрипта увидеть в браузере свою страницу ВК. Видимо чего-то недопонимаю. Втолкуйте.

38

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

многобанофф,

многобанофф пишет:

Или имеется в виду авторизация для дальнейшего получения данных средствами HTML DOM Document?

Именно так. WinHttpRequest никак не связан с браузером(ами). Проводя аналогию - Если Вы запустите один браузер и в нём авторизуетесь на сайте VK, то другие браузеры об этом ничего не узнают.

Так что Вы правильно поняли - Дальнейшие действия по управлению страницей также ложатся на Вас.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

39

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Хотел попробовать заполнить текстовый документ залитый на ucoz'e, но выдает ошибку на code:

global oHttpRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
 oHtmlDoc := documentFromURL("http://ucoz-tester.ucoz.ru/panel/?a=fm;l=7;f=;file=test.txt") 
 oForm := oHtmlDoc.forms[0] 
 oForm["password"].value := "pAsSwOrD" 
 submitForm(oForm) 
 oForm["code"].value := "New Message"
 submitForm(oForm)
 oHtmlDoc := documentFromHTML(oHttpRequest.responseText, oHttpRequest.Option(1)) 
 
MsgBox % oHtmlDoc.body.outerText 
Как сказал мой дед - Я твой дед

40

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr пишет:

Хотел попробовать заполнить текстовый документ залитый на ucoz'e, но выдает ошибку на code

1) Естественно. Вы не авторизовались на сайте, а уже пытаетесь редактировать файл. Поэтому при первом запросе в documentFromURL у Вас произошёл автоматический редирект на страницу с формой авторизации. А на форме этой страницы нет поля code. Логично, что будет ошибка при попытке заполнить несуществующее поле. )

2) Опять же не понимаю, зачем таким образом работать с сайтом. Есть же FTP. Удобно быстро и просто. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

41

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon пишет:

Именно так. WinHttpRequest никак не связан с браузером(ами). Проводя аналогию - Если Вы запустите один браузер и в нём авторизуетесь на сайте VK, то другие браузеры об этом ничего не узнают.
Так что Вы правильно поняли - Дальнейшие действия по управлению страницей также ложатся на Вас.

Многие сайты сейчас предусматривают возможность входа посредством аккаунта в соцсетях. То есть если выбрать, к примеру, вход с аккаунта ВК, появится окошко авторизации на нем и после ввода логина/пароля произойдет авторизация и в ВК и в целевом сайте. В большинстве случаев можно отдельно авторизоваться в ВК, а потом идти на целевой сайт - он тогда не выдает окна авторизации в ВК.
Так вот после запуска скрипта этого не происходит, а мне в данный момент интересно именно это. Возможно ли достижение такого эффекта или чрезмерный гемор мыслю (сейчас все это приходится решать эмуляцией кликов мыши и нажатия клавиш, что, конечно, не очень изящно)?

42

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Вы не авторизовались на сайте, а уже пытаетесь редактировать файл. Поэтому при первом запросе в documentFromURL у Вас произошёл автоматический редирект на страницу с формой авторизации. А на форме этой страницы нет поля code. Логично, что будет ошибка при попытке заполнить несуществующее поле.

Можете помочь мне это реализовать, просто я не люблю искать легких путей поэтому не использую FTP .

Как сказал мой дед - Я твой дед

43

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

многобанофф, вот по этой самой причине, я в начале темы и интересовался - какая конечная цель. ) Тот метод (алгоритм), который я предложил больше подходит для случая, когда нужно с какого-то сайта дёргать информацию.
Я его использовал для сбора информации о рейтингах банка с сайта РБК и авторизации в API вконтакта. Вся прелесть его в том, что при этом не грузятся лишние стили, скрипты, изображения со страниц. Когда работаешь с API это и не нужно. Но при этом приходится изучать всю механику запросов, которые сайт осуществляет при переходах со страницы на страницу и т.п. Опять же в этом коде я не вставлял механику, которая эмулирует отправку формы в виде MultiPart данных. А такое имеет место быть при загрузке файлов на сервер. В случае с IE Вам не нужно задумываться о том, где и какие запросы нужно осуществлять, т.к вся механика уже реализована внутри движка IE. Но при этом все ресурсы страницы грузятся к вам полностью. А дальше уже выбор за Вами. ) Вы уже определились с конечной целью ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

44

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr пишет:

Можете помочь мне это реализовать, просто я не люблю искать легких путей поэтому не использую FTP .

Выяснил, у меня в коде косяк был. Первое поле не заполнялось. Вставил "i++" до цикла, а счётчик полей идёт с 0.

Всё же FTP предпочтительней.


;Константы используемые в WinHttpRequest
global WinHttpRequestOption_EnableRedirects := 6
global WinHttpRequestOption_MaxAutomaticRedirects := 14
global WinHttpRequestOption_EnableHttpsToHttpRedirects := 12

; Создаём объект для запросов по HTTP протоколу
global oHttpRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")

;Включаем редиректы
oHttpRequest.Option(WinHttpRequestOption_EnableRedirects) := -1
;Включаем редиректы с HTTP на HTTPS
oHttpRequest.Option(WinHttpRequestOption_EnableHttpsToHttpRedirects) := -1
;Выставляем максимальное количество автоматических редиректов
oHttpRequest.Option(WinHttpRequestOption_MaxAutomaticRedirects) := 20

global oHttpRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") 

;Первым делом авторизуемся
oHtmlDoc := documentFromURL("http://ucoz-tester.ucoz.ru/panel/") 
oForm := oHtmlDoc.forms[0] 
oForm["password"].value := "pAsSwOrD" 
submitForm(oForm) 
 
;Обрабатывать первую страницу смысла особого пока нет. Так что пропускаем этот шаг пока что 
;oHtmlDoc := documentFromHTML(oHttpRequest.responseText, oHttpRequest.Option(1))

;Теперь эмулируем переход по ссылке для открытия файла на редактирование.
oHtmlDoc := documentFromURL("http://ucoz-tester.ucoz.ru/panel/?a=fm;l=7;f=;file=test.txt")

;Получаем объектную модель формы редактирования файла
oForm := oHtmlDoc.forms[0] 

;Заполняем в форме значение поля code
oForm["code"].value := "SOME TEXT !"

;отправляем форму
submitForm(oForm)

;Разбираем тело ответа
if InStr(oHttpRequest.responseText,"Файл успешно изменен") <= 0
{
    MsgBox % "При сохранении файла произошла ошибка"
    Exit
}

oHttpRequest.Open("GET", "http://ucoz-tester.ucoz.ru/test.txt", False)
oHttpRequest.Send()

MsgBox % "Теперь содержимое файла: " . oHttpRequest.responseText

; Функция загрузки и построения документа с указанного URL
documentFromURL(ByRef sURL) {
    ; Отправляем GET запрос на сервер
    oHttpRequest.open("GET", sURL, false)
    oHttpRequest.send()
    
    ; Строим из полученных данных документ и возвращаем из функции
    return documentFromHTML(oHttpRequest.responseText, sURL)
}

; Функция создания документа из HTML кода
documentFromHTML(ByRef sHTMLCode, ByRef sBaseURL) {
    ; Создаём объект для парсинга HTML кода
    oDoc := ComObjCreate("htmlfile")
    oDoc.open()
    ; Вставляем базовый тэг чтобы у относительных ссылок была верная адрессация от базового адреса
    oDoc.write("<base href=""" . sBaseURL . """>")
    oDoc.close()
    ;oDoc.write(sHTMLCode)
    oDoc.body.innerHTML := sHTMLCode
    return oDoc
}

; Функция эмулятор отправки формы
submitForm(ByRef oForm){
    ; Получаем ссылку на объект Window от документа формы
    oScript := oForm.document.Script
    ; Сборка строки запроса формы
    i := 0
    loop , % oForm.elements.length 
    {
        if oForm.elements[i].name != ""  
        {
            writeLn(oForm.elements[i].name . ": " . oForm.elements[i].value)
            ; Собираем значения полей формы в строку и кодируем их имена и значения
            sBody .= oScript.encodeURIComponent(oForm.elements[i].name) . "=" . oScript.encodeURIComponent(oForm.elements[i].value) . "&"
        }
        i++
    }
    StringLeft, sBody, sBody, StrLen(sBody)-1

    ; Получаем текущий адрес на котором мы находимся (для заполнения referer и настройки свойства "action" формы )
    sCurrentURL := oHttpRequest.Option(1)
    ; Для формы BASE hRef не срабатывает, поэтому искусственно вычисляем полный путь запроса формы
    oForm.action := buildURL(sCurrentURL,oForm.action)

    writeLn("ACTION: " . oForm.action)
    writeLn("BODY: " . sBody)

    oHttpRequest.open("POST", oForm.action, false)
    ; Указываем метод кодирования данных
    oHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
    ; Выставляем Referer, дабы сайты не ругались, что мы себя плохо ведём.
    if sCurrentURL != "" 
    {
        oHttpRequest.setRequestHeader("Referer", sCurrentURL)
    }
    ; Отправляем данные формы
    oHttpRequest.send(sBody)
}

; Функция для построения полного пути из относительного для URL
buildURL(ByRef sBaseURL, ByRef sURL) {
    ; Создаём HTML документ с единственной ссылкой
    oDoc := documentFromHTML("<a href=""" . sURL . """>", sBaseURL)
    ; Берём href от этой ссылки.
    return oDoc.all.tags("a")[0].href
}

; Функция для вывода строки в консоль
writeLn(text){
    write(text . "`r")
}

; Функция для вывода текста в консоль
write(text){
    FileAppend, %text%, *
}
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

45

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon пишет:

...

Я вполне понял - средство неподходящее. Тянуть с сайтов мне нечего, мне надо в них тыкать, глазеть и клацать.
А цели у меня нет - это не мой топик.
Я просто смотрю, читаю и иногда мне кажется, что какой-то из примеров может сам по себе или после до(пере-)работки пригодиться для моих нужд уже оформившихся или потенциальных. Иногда мне просто становится интересно когда встречаются принципиально новые методы или возможности.
В данном случае я изначально ошибочно истолковал название топика, полагая, что речь идет об автоматизации авторизации при входе на сайт. Заглянув, не обнаружил ни кликов, ни распознаваний цветов пикселов или изображений, ни прочих подобных средств, которыми самому приходится пользоваться. Все это и привлекло внимание. Ну и человечье отношение, разумеется, о кумир.

46

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

многобанофф,

многобанофф пишет:

Тянуть с сайтов мне нечего, мне надо в них тыкать, глазеть и клацать.

Тогда конечно автоматизация через IE проще всего. ) Он и кликает и клацает и глазеть тут же даёт. С помощью него и VK авторизацию легко произвести. Но опять же уточню - это действительно только в пределах того браузера в котором Вы работаете. Т.е если сделать эту авторизацию через IE, она будет действительна только для окон IE. ) Другие браузеры про это ничего знать не будут.

А цели у меня нет - это не мой топик.

Не важно чей топик. ) Цель есть всегда. Вам же зачем-то нужно сделать авторизацию в ВК. Вот уже и есть цель.

Ну и человечье отношение, разумеется, о кумир.

Вторая заповедь запрещает :

*взято из википедии*

Не делай себе кумира и никакого изображения того, что на небе вверху и что на земле внизу, и что в водах ниже земли. Не поклоняйся им и не служи им; ибо Я Господь, Бог твой, Бог ревнитель, за вину отцов наказывающий детей до третьего и четвёртого рода, ненавидящих Меня, и творящий милость до тысячи [родов] любящим Меня и соблюдающим заповеди Мои.

Ох покараить.... ))) до четвёртого колена.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

47

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon пишет:

Тогда конечно автоматизация через IE проще всего. ) Он и кликает и клацает и глазеть тут же даёт. С помощью него и VK авторизацию легко произвести. Но опять же уточню - это действительно только в пределах того браузера в котором Вы работаете. Т.е если сделать эту авторизацию через IE, она будет действительна только для окон IE. ) Другие браузеры про это ничего знать не будут.

Пользуюсь исключительно гуглхромом, будь он неладен.

Xameleon пишет:

Не важно чей топик. ) Цель есть всегда. Вам же зачем-то нужно сделать авторизацию в ВК. Вот уже и есть цель.

Ну не в ВК, а в Одноклассниках. Да и не цель, а так, баловство одно - все и так авторизуется пресловутыми кликами. Просто у меня чрезвычайно беспокойное эстетическое чувство - пока оно ощущает, что сделанное мной коряво(~вато), постоянно жмет, тянет и не дает спокойно жить. Его можно немного обмануть тем, что прочие варианты недоступны или слишком трудоемки, но тут попадется на глаза вот эдакое... и понеслось опять...


Xameleon пишет:

Ох покараить.... ))) до четвёртого колена.

Не обольщайтесь, не до такой же степени. Максимум побанит, а это уж я до того привык, что долгий период без бана начинает настораживать чисто интуитивно.

48

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Если хром, то облом. ) Сам на него подсел. К нему если только плагин писать.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

49

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Я примерно к такому выводу и пришел в одной из соседних тем. Ан нет, нашлось средство для решения пары-тройки хромовых проблем. Кстати, надо напомниться...

50

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr

sergeiplugatyr пишет:

Можете помочь мне это реализовать, просто я не люблю искать легких путей поэтому не использую FTP .


Крайне рекомендую обратить внимание на Class модуль FTP.ahk через который реализован обмен с FTP
https://github.com/george2/ahk-libs/blo … /FTPv2.ahk

Ну и на пример по этой ссылке.
http://www.autohotkey.com/board/topic/6 … -as-1-2-3/


;; FTP Class Example - http://www.autohotkey.com/forum/viewtopic.php?t=73544
;; Asynchronous Mode example

;; PLEASE NOTE: 
;; 1. All output is logged to the stdout, can be only seen if debugger attached
;;    or you run it with Scite4Autohotkey
;; 2. The script can do any other work while waiting for AsyncRequestComplete notification

;;== USER SETTINGS ===============
Server     := "ftp.autohotkey.net"
UserName   := "my_username"
Password   := "my_password"
UploadFile := "D:\Temp\Test.zip"
;;== END USER SETTINGS ===========

; initialize and get reference to FTP object
ftp1 := new FTP(1) ; 1 = Async mode, use default callback function
ftp1 ? TTip("InternetOpen Success") : Quit("Could not load module/InternetOpen")

OnExit, Cleanup


; connect to FTP server
ftp1.Open(Server, UserName, Password) ? TTip("Connected to FTP") : Quit(ftp1.LastError)

; create a new directory 'testing'
ftp1.CreateDirectory("testing")
SleepWhile() ? TTip("Created Directory ""testing""") : Msg("Create Directory Failed")

; set the current directory to 'root/testing'
ftp1.SetCurrentDirectory("testing")
SleepWhile() ? TTip("SetCurrentDirectory ""testing""") : Msg("SetCurrentDirectory failed!")

; upload this script file
SplitPath,UploadFile,RemoteFile,,fExt
ftp1.PutFile(UploadFile, RemoteFile)
SleepWhile() ? TTip("PutFile success!") : Msg("PutFile failed!")

; rename script to 'testscript.ahk'
ftp1.RenameFile(RemoteFile, (NewLocalFile := "Delete_Me." . fExt))
SleepWhile() ? TTip("RenameFile success!") : Msg("RenameFile failed!")

IfExist, % NewLocalFile
  FileDelete, % NewLocalFile

; retrieve the file from the FTP server
ftp1.GetFile(NewLocalFile,A_ScriptDir . "" . NewLocalFile, 0)
SleepWhile() ? TTip("GetFile success!") : Msg("GetFile failed!")

; delete the file from the FTP server
ftp1.DeleteFile(NewLocalFile)
SleepWhile() ? TTip("DeleteFile success!") : Msg("DeleteFile failed!")

; set the current directory back to the root
ftp1.SetCurrentDirectory("/") 
SleepWhile() ? TTip("SetCurrentDirectory to original path: success!") : Msg("SetCurrentDirectory failed")

; remove the directory 'testing'
ftp1.RemoveDirectory("testing")
SleepWhile() ? TTip("RemoveDirectory ""\testing"" success!") : Msg("RemoveDirectory failed")
ExitApp

Cleanup:
; close the FTP connection, free library
ftp1 := ""  ; __Delete Called

sleep 1000 ;The request complete will not be triggered, as the last message recieved is 70 = INTERNET_STATUS_HANDLE_CLOSING
MsgBox done!
exitapp


SleepWhile() {
  global FTP
  While !FTP.AsyncRequestComplete
    sleep 50
  return (FTP.AsyncRequestComplete = 1) ? 1 : 0 ; -1 means request complete but failed, only 1 is success
}

Quit(Message="") {
    if Message
        MsgBox, 16, Error!, %Message%, 5
    ExitApp
}

Msg(Message="") {
    MsgBox, 64, , %Message%, 5
}

TTip(Message="") {
    ToolTip %Message%
}

#Include FTP.ahk

Уж очень красиво решение оформлено.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

51 (изменено: sergeiplugatyr, 2014-03-24 16:21:09)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Мне по душе копаться в элементах HTML и тыкать по ним, чем в FTP. Не обессудьте. Хотя спасибо за пример, возможно где нибудь реализую это.

Как сказал мой дед - Я твой дед

52

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

sergeiplugatyr, проблема в том, что HTML код сайта может меняться. Поменял автор дизайн и привет. ) Вся работа на смарку и снова в "debug", а в случае с FTP это отпадает. )

К тому же, как я где-то выше уже писал, через тот метод, который используется в submitForm нельзя "залить" файл на сервер. Для этого нужно отправляемые данные преобразовывать в Multipart формат. У меня есть готовый написанный класс для этого, но на AHK его не переписывал, т.к необходимости не было.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

53

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Поменял автор дизайн и привет. ) Вся работа на смарку и снова в "debug"

Ну знающий человек и под новый дизайн найдет решение.

Как сказал мой дед - Я твой дед

54

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Возможно чего-то не учитываю или не знаю, но ПМСМ зря сопротивляетесь.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

55 (изменено: Malcev, 2014-04-06 04:34:04)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Непонятно, как залогиниться на нашем форуме и поcтавить галочку "запомнить меня".
http://forum.script-coding.com/login.php
Скрипт при таких значениях выдает ошибку:
error 0x80020006
Specifically: encodeURIComponent

oHtmlDoc := documentFromURL("http://forum.script-coding.com/login.php") 
oForm := oHtmlDoc.forms[0] 
oForm["req_username"].value := "username" 
oForm["req_password"].value := "password" 
submitForm(oForm) 

56

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Допилил в AHK. )


;*** Авторизация на форуме ***

;Создание объекта для обмена данными по HTTP протоколу
global oHttpRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")

;Загружаем документ с нужного нам URL
oHtmlDoc := documentFromURL("http://forum.script-coding.com/login.php")

;Получаем объектную модель формы
oForm := oHtmlDoc.forms(0)

;Заполняем необходимые поля
oForm["req_username"].value := "user"
oForm["req_password"].value := "password"

;Эмулируем отправку формы
emulateFormSubmit(oForm)

;Строим документ из полученных данных
oHtmlDoc := documentFromHTML(oHttpRequest.responseText)

;Выводим сообщение о состоянии авторизации
print(oHtmlDoc.parentWindow.welcome.innerText)

;Функция эмулирующая отправку формы
emulateFormSubmit(form) {
    ;Если форма отправляется методом POST
    if (form.method = "post"){
        ;Проверяем метод кодирования. У нас реализован только - application/x-www-form-urlencoded
        if (form.enctype != "application/x-www-form-urlencoded") {
            throw "Unsupported enctype !"
        }
        ;Собираем в строку имена и значения полей
        varBody := buildVarBody(form.elements)
        ;Отправляем запроса
        oHttpRequest.open(form.method, form.action, false)
        ;Указываем заголовок типа данных, чтобы принимающая сторона поняла, что мы отправляем форму
        oHttpRequest.setRequestHeader("Content-Type", form.enctype)
        ;Передаём данные
        oHttpRequest.send(varBody)
    } 
    ;Если форма передаётся методом GET
    else if (form.method = "get")
    {
        ;Получаем URL куда должны передаться данные формы
        url := form.action
        ;Если в URL присутствует символ "?" значит там уже идут параметры. Их мы ликвидируем.
        i := InStr(url,"?")
        if (i > 0 ) { 
            StringLeft url, url, i-1 
        }
        ;Собираем поля и цепляем к URL формы
        varBody := buildVarBody(form.elements)
        if (varBody <> "") {
            url := url . "?" . varBody
        }
        ;Отправляем запрос
        oHttpRequest.open("GET",url,false)
        oHttpRequest.send()
    }
    else {
        throw "Unsupported request method !"
    }
}

;Функция сбора полей формы
buildVarBody(form) {
    ;Создаём пустой документ
    oHtmlDoc := documentFromHTML("")
    ;Включаем в нём возможность исполнения скриптов
    oHtmlDoc.designMode := "off"
    ;Получаем ссылку на основной объект скрипта
    oScript := oHtmlDoc.script
    ;Инициализируем JavaScript интерпретатор
    oScript.execScript("eval()")
    i := 0
    while (i < form.elements.length) {
        ;Получаем элемент формы
        element := form.elements(i)
        ;Собираем строку из закодированных имён полей и их значений 
        varBody := varBody . oScript.encodeURIComponent(element.name) . "=" . oScript.encodeURIComponent(element.value) . "&"
        i++
    }
    ;Отрезаем последний амперсанд на хвосте
    StringLeft varBody, varBody, StrLen(varBody)-1
    return varBody    
}

;Функция загрузки документа с указанного URL
documentFromURL(url){
    ;Формируем и отправляем HTTP запрос
    oHttpRequest.open("GET",url,false)
    oHttpRequest.send()
    ;Строим документ из полученных данных
    oHtmlDoc := documentFromHTML(oHttpRequest.responseText)
    ;Добавляем в документ тэг BASE, чтобы относительные пути преобразовать к абсолютным
    oBaseTag := oHtmlDoc.createElement("base")
    oBaseTag.href := url
    oHtmlDoc.all.tags("head")(0).appendChild(oBaseTag)
    return oHtmlDoc
}

;Функция построения документа из HTML кода
documentFromHTML(htmlCode){
    ;Создание документа
    oHtmlDoc := ComObjCreate("htmlfile")
    ;Отключаем скрипты
    oHtmlDoc.designMode := "on"
    ;Открытие документа
    oHtmlDoc.open("text/html")
    oHtmlDoc.write(htmlCode)
    oHtmlDoc.close()
    ;Отключение подгрузки доп. содержимого
    oHtmlDoc.execCommand("stop")
    return oHtmlDoc
}

;Функция для вывода текста в консоль
print(text){
    FileAppend, %text% `r, *
}
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

57

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Спасибо огромное!
А в чем разница между авторизацией в vk и на нашем форуме?
То что тут отправляется форма методом  POST?

58

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Malcev, нет, отправка формы в 99% случаев производится методом POST. Основная разница авторизации на VK и на форуме в именах полей. В коде я оставил вариант для отправки формы методом GET чисто для универсальности - мало ли. Вариант с отправкой формы с файлами вставлять не стал. Вроде нет необходимости.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

59

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon
А как будет выглядеть отправка письма с приложеннымми файлами, на почтовый ящик?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

60

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov, хм. Отправка писем к работе по HTTP протоколу имеет косвенное отношение. ) Я думаю для этого лучше завести отдельную тему. А вообще на форуме это не раз обсуждалось.

К примеру - http://forum.script-coding.com/viewtopic.php?id=8090

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

61

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

До этого найти не мог. По запросу CDO.Message нашёл рабочий код http://www.autohotkey.com/board/topic/6 … ntry383284.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

62

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon
А как например быть с закачкой больших файлов из интернета? Я так понимаю WinHttpRequest грузит их целиком в оперативку, а если оперативки не хватает, есть выход?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

63

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

На сколько помню, при превышении размера оперативки, часть данных пишется просто в кэш на диск. Выход есть - грузить блоками указывая Range. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

64

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Выход есть - грузить блоками указывая Range

Прикольно, а примерчик можно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

65

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

В принципе есть шаблончик http://forum.script-coding.com/viewtopi … 977#p82977, думаю проще на его примере.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

66

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Можно. ) Но ток не сегодня. Спать хочется очень.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

67

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon
Нашёл только такой код - http://stackoverflow.com/questions/1397 … oad-a-file, даже не знаю имеет ли отношение.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

68

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Не даёт Вам покоя эта тема ))).

Вот тут хорошо разобрано. http://habrahabr.ru/post/138504/

Хоть это и серверная часть, но автор очень грамотно поясняет как идёт анализ заголовков. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

69

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Просто хочется увидеть в итоге полноценную качалку файлов, несколько закачек с одного скрипта с прогрессом для каждой, думаю тема интересна не только мне.
Пример на РНР для меня увы совсем не понятен.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

70

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Вот этот код, как я понимаю, качает.
Осталось перевести на AHK.
http://stackoverflow.com/questions/1844 … g-vbscript

71

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Я так и не разобрался, возможно качает, но наверное один файл ведь используется синхронный запрос

req.open "GET", url, False

.
Тут наверное поможет https://github.com/infogulch/WinHttpRequest для установки сообщений о окончании загрузки каждого потока закачек. Вообщем без гуру не обойтись.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

72

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Пфф... Господа. Ну так лень это заново всё писать. ) Было время я на форуме заготовки выкладывал. Потом это всё зачистили, когда форум от мусора избавляли.

Там всё максимально просто. Сначала делаем HEAD запрос, чтобы получить только информацию о файле (размер файла из заголовка - Content-Length и проверить заголовок Accept-Ranges на значение bytes). Таким образом узнаём что сервер может отдавать содержимое блоками. Далее делаем GET запросы указывая Заголовок Range: bytes=[start]-[end] и обычным циклом перебора смещаем стартовую позицию. Делов то. )
Сами по себе запросы можно хоть синхронно, хоть асинхронно посылать. Кому как удобнее. )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

73 (изменено: serzh82saratov, 2014-06-04 11:41:25)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Всё, что наверное смог понять:


chunk := 1048576   ;  часть закачки 1 мегабайт
url := "http://ahkscript.org/download/ahk-install.exe"
file := A_Desktop "\ahk-install.exe"
 
pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
pWHttp.Open("HEAD", url, 0)
pWHttp.Send() 

If (pWHttp.GetResponseHeader("Accept-Ranges") != "bytes")
    MsgBox Невозможно качать частями
    
MsgBox, % pWHttp.getAllResponseHeaders()

Length := pWHttp.GetResponseHeader("Content-Length")

Loop  
{
    i := A_Index-1
    
    first := i * chunk 
    first := first >= Length ? Length - 1 : first
    
    last := first + chunk - 1 
    last := last >= Length ? Length - 1 : last
    
    MsgBox, % "next chunk: " first "-" last " in " Length
    
    
    pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
    pWHttp.Open("GET", url, 0)
    pWHttp.setRequestHeader("Range", "bytes=" first "-" last)
    pWHttp.Send() 
    
    pADODB := ComObjCreate("ADODB.Stream")
    pADODB.Open()
    pADODB.Type := 1
    pADODB.Write(pWHttp.ResponseBody)
    pADODB.SaveToFile(file, 2)
    pADODB.Close(), pWHttp := ""
} Until (last = Length - 1)

MsgBox Готово
Return

Получается файл в 500 КБ.

Тем более тёмный лес с ассинхронными запросами с Range. Проверять их все на готовность в цикле, совсем нехорошо.

Xameleon пишет:

Там всё максимально просто.

Только не для простых смертных.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

74

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest


chunk := 1048576   ;  часть закачки 1 мегабайт
url := "http://ahkscript.org/download/ahk-install.exe"
file := A_Desktop "\ahk-install.exe"
 
pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
pWHttp.Open("HEAD", url, 0)
pWHttp.Send() 

If (pWHttp.GetResponseHeader("Accept-Ranges") != "bytes")
    MsgBox Невозможно качать частями
    
MsgBox, % pWHttp.getAllResponseHeaders()


pADODB := ComObjCreate("ADODB.Stream")
pADODB.Open()
pADODB.Type := 1
Length := pWHttp.GetResponseHeader("Content-Length")
    
Loop  
{
    i := A_Index-1
    
    first := i * chunk 
    first := first >= Length ? Length - 1 : first
    
    last := first + chunk - 1 
    last := last >= Length ? Length - 1 : last
    
    MsgBox, % "next chunk: " first "-" last " in " Length
    
    pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
    pWHttp.Open("GET", url, 0)
    pWHttp.setRequestHeader("Range", "bytes=" first "-" last)
    pWHttp.Send()
    
    If (pWHttp.Status = 206)
        pADODB.Write(pWHttp.ResponseBody) 
        
} Until (last = Length - 1)

pADODB.SaveToFile(file, 2)
pADODB.Close(), pWHttp := ""

MsgBox Готово
Return

Этот код качает. Но в таком виде не понятен смысл, ведь все данные сначала записываются в ADODB Stream, а это как я понимаю - оперативка.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

75 (изменено: serzh82saratov, 2014-06-04 15:19:52)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Вроде так:


chunk := 1048576   ;  часть закачки 1 мегабайт
url := "http://ahkscript.org/download/ahk-install.exe"
destfile := A_Desktop "\ahk-install.exe"

pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
pWHttp.Open("HEAD", url, 0)
pWHttp.Send()  

If (pWHttp.GetResponseHeader("Accept-Ranges") != "bytes")
    MsgBox Невозможно качать частями
    
File := FileOpen(destfile, "w"), File.Length := 0, File.Close()
 
MsgBox, % pWHttp.getAllResponseHeaders()
 
Length := pWHttp.GetResponseHeader("Content-Length")
    
Loop  
{
    i := A_Index-1
    
    first := i * chunk
    first := first >= Length ? Length - 1 : first
    
    last := first + chunk - 1 
    last := last >= Length ? Length - 1 : last
    
    ToolTip, % "next chunk: " first "-" last " in " Length
     
    pWHttp.Open("GET", url, 0)
    pWHttp.setRequestHeader("Range", "bytes=" first "-" last)
    pWHttp.Send() 
    
    StreamToFile(pWHttp.ResponseStream, destfile, last-first+1) 

} Until (last = Length - 1)

pWHttp := ""
ToolTip
MsgBox Готово
Return

StreamToFile(Stream, fileName, size)   { 
    If (ComObjType(Stream) != 0xD)  
        Return 0
    pIStream := ComObjQuery(Stream, "{0000000c-0000-0000-C000-000000000046}") 
    VarSetCapacity(Buffer, size)
    DllCall(NumGet(NumGet(pIStream + 0) + 3 * A_PtrSize)
        , "ptr", pIStream, "ptr", &Buffer, "uint", size, "ptr*", size) 
    oFile := FileOpen(fileName, "a"), oFile.RawWrite(&Buffer, size)
    ObjRelease(pIStream), oFile.Close()
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

76

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

WinHttpRequest хорош asynchronous mode, можно запустить кучу "закачек" (но только в оперативку?), а есть варианты нескольких закачек в файл из одного процесса AutoHotkey ?

http://forum.script-coding.com/viewtopi … 016#p83016

Нужно загружать не целую страницу, а только часть, например первые 300 строк или 2кб.

http://forum.script-coding.com/viewtopi … 286#p67286

Получается что всё таки возможно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

77

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Может, проще использовать ResponseBody, как у меня в недавнем примере? Взять оттуда указатель на данные и сразу писать в файл. Не надо будет IStream и дополнительный буфер для него. Ведь тут, наверно, идёт копирование из буфера в буфер. Лишняя трата времени и памяти.

78

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Интересно, можно код? Пример видел, но сейчас без ПК не соображу.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

79 (изменено: YMP, 2014-06-08 15:22:09)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Получаете указатель на данные:


Body := HTTP.ResponseBody
pData := NumGet(ComObjValue(Body), A_PtrSize = 8? 16:12, "ptr")

А дальше его используете в методе RawWrite как адрес буфера вместо &Buffer.


File.RawWrite(pData+0, Bytes)

80

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Спасибо, теперь значительно проще:


chunk := 262144   ;  часть закачки 256 KB
url := "http://ahkscript.org/download/ahk-install.exe"
fileName := A_Desktop "\ahk-install.exe"

oWHR := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
oWHR.Open("HEAD", url, 0)
oWHR.Send()  

Length := oWHR.GetResponseHeader("Content-Length")

If (oWHR.GetResponseHeader("Accept-Ranges") != "bytes")
    chunk := Length 

MsgBox, % oWHR.getAllResponseHeaders()

oFile := FileOpen(fileName, "a"), oFile.Length := 0
  
Loop  
{
    i := A_Index-1
    
    first := i * chunk
    first := first >= Length ? Length - 1 : first
    
    last := first + chunk - 1 
    last := last >= Length ? Length - 1 : last
    
    ToolTip, % "next ranges: " first "-" last " in " Length
    
    oWHR.Open("GET", url, 0)
    oWHR.setRequestHeader("Range", "bytes=" first "-" last)
    oWHR.Send()  
    
    oBody := oWHR.ResponseBody
    pData := NumGet(ComObjValue(oBody), A_PtrSize = 8? 16:12, "ptr")
    oFile.RawWrite(pData+0, last-first+1)
    
} Until (last = Length - 1)

oFile.Close()
oWHR := ""
ToolTip
MsgBox Готово
Return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

81

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon честно изучил Ваш пост, но не могу решить задачку авторизации на этом сайте, видимо невыходит получить форму авторизации. Похоже она находится не в загружаемой странице, а подгружается позднее, как быть в таких случаях?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

82

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

serzh82saratov, а вот этот код удалось понять?
http://forum.script-coding.com/viewtopi … 480#p83480
Я сколько не пытался, так и не смог применить его на других форумах.

83

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Не удалось, наверное потому и возник вопрос.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

84 (изменено: Malcev, 2015-04-04 09:25:02)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Xameleon пишет:

Допилил в AHK. )


;*** Авторизация на форуме ***

;Создание объекта для обмена данными по HTTP протоколу
global oHttpRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")

;Загружаем документ с нужного нам URL
oHtmlDoc := documentFromURL("http://forum.script-coding.com/login.php")

;Получаем объектную модель формы
oForm := oHtmlDoc.forms(0)

;Заполняем необходимые поля
oForm["req_username"].value := "user"
oForm["req_password"].value := "password"

;Эмулируем отправку формы
emulateFormSubmit(oForm)

;Строим документ из полученных данных
oHtmlDoc := documentFromHTML(oHttpRequest.responseText)

;Выводим сообщение о состоянии авторизации
print(oHtmlDoc.parentWindow.welcome.innerText)

;Функция эмулирующая отправку формы
emulateFormSubmit(form) {
    ;Если форма отправляется методом POST
    if (form.method = "post"){
        ;Проверяем метод кодирования. У нас реализован только - application/x-www-form-urlencoded
        if (form.enctype != "application/x-www-form-urlencoded") {
            throw "Unsupported enctype !"
        }
        ;Собираем в строку имена и значения полей
        varBody := buildVarBody(form.elements)
        ;Отправляем запроса
        oHttpRequest.open(form.method, form.action, false)
        ;Указываем заголовок типа данных, чтобы принимающая сторона поняла, что мы отправляем форму
        oHttpRequest.setRequestHeader("Content-Type", form.enctype)
        ;Передаём данные
        oHttpRequest.send(varBody)
    } 
    ;Если форма передаётся методом GET
    else if (form.method = "get")
    {
        ;Получаем URL куда должны передаться данные формы
        url := form.action
        ;Если в URL присутствует символ "?" значит там уже идут параметры. Их мы ликвидируем.
        i := InStr(url,"?")
        if (i > 0 ) { 
            StringLeft url, url, i-1 
        }
        ;Собираем поля и цепляем к URL формы
        varBody := buildVarBody(form.elements)
        if (varBody <> "") {
            url := url . "?" . varBody
        }
        ;Отправляем запрос
        oHttpRequest.open("GET",url,false)
        oHttpRequest.send()
    }
    else {
        throw "Unsupported request method !"
    }
}

;Функция сбора полей формы
buildVarBody(form) {
    ;Создаём пустой документ
    oHtmlDoc := documentFromHTML("")
    ;Включаем в нём возможность исполнения скриптов
    oHtmlDoc.designMode := "off"
    ;Получаем ссылку на основной объект скрипта
    oScript := oHtmlDoc.script
    ;Инициализируем JavaScript интерпретатор
    oScript.execScript("eval()")
    i := 0
    while (i < form.elements.length) {
        ;Получаем элемент формы
        element := form.elements(i)
        ;Собираем строку из закодированных имён полей и их значений 
        varBody := varBody . oScript.encodeURIComponent(element.name) . "=" . oScript.encodeURIComponent(element.value) . "&"
        i++
    }
    ;Отрезаем последний амперсанд на хвосте
    StringLeft varBody, varBody, StrLen(varBody)-1
    return varBody    
}

;Функция загрузки документа с указанного URL
documentFromURL(url){
    ;Формируем и отправляем HTTP запрос
    oHttpRequest.open("GET",url,false)
    oHttpRequest.send()
    ;Строим документ из полученных данных
    oHtmlDoc := documentFromHTML(oHttpRequest.responseText)
    ;Добавляем в документ тэг BASE, чтобы относительные пути преобразовать к абсолютным
    oBaseTag := oHtmlDoc.createElement("base")
    oBaseTag.href := url
    oHtmlDoc.all.tags("head")(0).appendChild(oBaseTag)
    return oHtmlDoc
}

;Функция построения документа из HTML кода
documentFromHTML(htmlCode){
    ;Создание документа
    oHtmlDoc := ComObjCreate("htmlfile")
    ;Отключаем скрипты
    oHtmlDoc.designMode := "on"
    ;Открытие документа
    oHtmlDoc.open("text/html")
    oHtmlDoc.write(htmlCode)
    oHtmlDoc.close()
    ;Отключение подгрузки доп. содержимого
    oHtmlDoc.execCommand("stop")
    return oHtmlDoc
}

;Функция для вывода текста в консоль
print(text){
    FileAppend, %text% `r, *
}

Так я и не понял зачем такие сложности, когда можно обойтись всего парой строчек:

url := "http://forum.script-coding.com/login.php"
login := "login"
password := "pass"
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WebRequest.Open("GET", url)
WebRequest.Send()
RegExMatch(WebRequest.ResponseText,"csrf_token"" value=""(\w+)"" />", match)
token := match1
loginBody := "form_sent=1&redirect_url=http%3A%2F%2Fforum.script-coding.com%2Flogin.php&csrf_token=" token "&req_username=" login "&req_password=" password "&login=%D0%92%D0%BE%D0%B9%D1%82%D0%B8"
WebRequest.Open("POST", url)
WebRequest.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
WebRequest.Send(loginBody)
If Instr(WebRequest.ResponseText, "Вы вошли как")
   msgbox All Ok!
Else
   msgbox Failed!

85 (изменено: sergeiplugatyr, 2015-04-07 18:20:09)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Я делал давно еще через IE авторизацию по API:

wb := ComObjCreate("InternetExplorer.Application")
wb.Visible := true
url := "http://forum.script-coding.com/login.php"
login := "sergeiplugatyr"
password := "12349876"
wb.Navigate(url, 0x8)
while wb.ReadyState <> 4 or wb.Busy
   continue
HTML := wb.document.body.InnerHTML
Loop, parse, HTML, `n
{
   If InStr(A_LoopField, "token") {
      RegExMatch(A_LoopField, "value=(.*)", token)
   }
}
StringTrimLeft, out, token1, 1
StringTrimRight, out2, out, 2
data := "form_sent=1&redirect_url=http%3A%2F%2Fforum.script-coding.com%2Flogin.php&csrf_token=" out2 "&req_username=" login "&req_password=" password "&login=%D0%92%D0%BE%D0%B9%D1%82%D0%B8"
header := "Content-Type: application/x-www-form-urlencoded" + Chr(10) + Chr(13)
wb.Navigate2(url, , , PostData(data), header)
while wb.ReadyState <> 4 or wb.Busy
   continue

PostData(str, enc="UTF-8") 
{ 
  VarSetCapacity(buff, StrPut(str, enc) * (enc="UTF-16" || enc="CP1200" ? 2 : 1)) 
  size := StrPut(str, &buff, enc) 
  arr := ComObjArray(0x11, size) 
  loop % size 
    arr[A_Index-1] := NumGet(buff, A_Index-1, "Uchar") 
  return arr 
}
Как сказал мой дед - Я твой дед

86 (изменено: Malcev, 2015-04-04 09:40:38)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Но вот как ответить, например, в этом топике - для меня темный лес.
Надо сформировать и отправить POST-запрос в формате multipart/form-data к веб-серверу.
Есть кто разбирается?

87 (изменено: Malcev, 2015-06-05 17:43:05)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Возможна ли какая-то защита сервера против WinHttpRequest?
Например, у меня иногда не получается поймать обновление контента сайта (не этого).
То есть в броузере видна новая информация, а в ответе от WinHTTPRequest нет.
При том если скрипт перезапустить, то новую информацию он видит.
Может ли такое быть из-за того, что запущено сразу 2 скрипта стучащиеся к серверу (следящие за разными ссылками)?
Вот пример кода:

link := "http://forum.script-coding.com/index.php"
WebRequest := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
loop
{
   WebRequest.Open("GET", link)
   WebRequest.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)")
   WebRequest.Send()
   If A_Index = 1
      Content := WebRequest.ResponseText
   if (WebRequest.ResponseText != Content)
      msgbox, % WebRequest.ResponseText
}  

88

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Может, из какого-то кэша ответ выдаётся. Возможно, есть какой-то хедер или опция, чтобы это исключить.

89 (изменено: Malcev, 2015-06-05 20:02:43)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Вот что выдает GetAllResponseHeaders() в первый раз:

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: keep-alive
Date: Fri, 05 Jun 2015 15:57:13 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Age: 0
Server: xxx
Set-Cookie: csrf_p_cookie=0d97aa23f9cc43e256e1ea60a9f78b29; expires=Fri, 05-Jun-2015 17:57:13 GMT; path=/; domain=xxx.lv
Set-Cookie: TPSN=6db3tugjcegkc4csh7dp2fph77; expires=Sun, 07-Jun-2015 15:57:13 GMT; path=/; domain=xxx.lv
Set-Cookie: dL=lv_LV; expires=Sat, 04-Jun-2016 15:57:13 GMT; path=/; domain=xxx.lv
Set-Cookie: piguVisitor=13590169; expires=Fri, 05-Jun-2015 17:57:13 GMT; path=/; domain=xxx.lv
Set-Cookie: piguVisitorWallet=12072190; expires=Tue, 08-Dec-2015 15:57:13 GMT; path=/; domain=xxx.lv
Set-Cookie: wrap=72; expires=Sun, 05-Jul-2015 15:57:13 GMT; path=/
Vary: Accept-Encoding
X-Backend: web1
X-Cache: MISS
X-Cache-node: lv-proxy1

А вот что в последующие:

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: keep-alive
Date: Fri, 05 Jun 2015 15:57:44 GMT
Pragma: no-cache
Content-Length: 503905
Content-Type: text/html; charset=utf-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Accept-Ranges: bytes
Age: 0
Server: xxx
Set-Cookie: csrf_p_cookie=0d97aa23f9cc43e256e1ea60a9f78b29; expires=Fri, 05-Jun-2015 17:57:44 GMT; path=/; domain=xxx.lv
Set-Cookie: piguVisitor=13590169; expires=Fri, 05-Jun-2015 17:57:44 GMT; path=/; domain=xxx.lv
Set-Cookie: piguVisitorWallet=12072190; expires=Tue, 08-Dec-2015 15:57:44 GMT; path=/; domain=xxx.lv
Set-Cookie: wrap=72; expires=Sun, 05-Jul-2015 15:57:44 GMT; path=/
Vary: Accept-Encoding
X-Backend: web1
X-Cache: MISS
X-Cache-node: lv-proxy1

90 (изменено: Malcev, 2015-06-06 20:42:05)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Если

WebRequest := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")

вставить в цикл, то сервер при каждом обращении возвращает эти хедеры:

Set-Cookie: TPSN=6db3tugjcegkc4csh7dp2fph77; expires=Sun, 07-Jun-2015 15:57:13 GMT; path=/; domain=xxx.lv
Set-Cookie: dL=lv_LV; expires=Sat, 04-Jun-2016 15:57:13 GMT; path=/; domain=xxx.lv

Может в этом все дело и для оповещания изменений на сайте эти кукисы надо получать?

91

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Malcev пишет:

То есть в броузере видна новая информация, а в ответе от WinHTTPRequest нет.

Нашлось решение?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

92

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Да. Использование ComObjCreate("InternetExplorer.Application").
Видно, там новый контент появлялся через джаваскрипт и поэтому через WinHTTPRequest не отлавливался.

93

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Врядли это так, джаваскрипт просто автоматически отображает новое содержимое с сервера без перезагрузки страницы в окне браузера. WinHTTPRequest при каждом запросе Open - Send тоже должен получать с сервера новые данные, но заголовки обновляются, а данные нет. Как сказал YMP, это связано с кэшем. Опций я не нашёл, заголовки типа "If-Modified-Since" и.т.п. не дают результата.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

94 (изменено: Malcev, 2015-07-17 21:07:02)

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Ну вот пример:

WebRequest := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
WebRequest.Open("GET", "http://www.parachat.com/live-chat-software.php")
WebRequest.Send()
If InStr(WebRequest.ResponseText, "Treat your site visitors like")
   msgbox all ok

95

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Непонимаю, о чём говорит этот пример?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

96

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Если сайт http://www.parachat.com/live-chat-software.php загрузить в броузере, то выходит поп-ап:

Treat your site visitors like stars! Track, chat & engage them with ParaChat LiveHelp.

97

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Ну это к вопросу про выполняемые скрипты, у меня то вопрос простой, после авторизации через WinHTTPRequest, загрузив с сервера страницу мы получаем её содержимое, но загрузив повторно и оставшись авторизованными получаем снова и снова её старое содержимое, хотя на сервере всё уже давно поменялось.
Даже если снова получить ComObjCreate("WinHTTP.WinHTTPRequest.5.1") и пройти авторизацию, результата нет.
И только перезапустив скрипт, и соответственно заново авторизовавшись, можно получить новое содержимое.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

98

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Может кто то объяснить смысл авторизации с использованием WinHttpRequest?

Почему после авторизации второй и далее запросы


    oHttpRequest.open("GET", sURL, false)
    oHttpRequest.send()
    oHttpRequest.responseText

возвращают содержание HTML актуальное только на момент авторизации.

Там видимо перед запросами надо сначала отправить "всякие" токены и куки, кто то в теме?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

99

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Вот тут это обсуждают:
http://ahkscript.org/boards/viewtopic.php?t=92

100

Re: AHK: Авторизация на сайтах с использованием WinHttpRequest

Я там ничего непонял, а ты?
Думаю тут без пояснений от посвящённых не обойтись.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui