Автор Тема: Загрузка файлов в Интернет. Пример для rghost.ru  (Прочитано 5779 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн inververs [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 2135
  • Репутация: 461
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
AutoIt: 3.3.8.1
Версия: 1.0

Категория: Интернет, Автоматизация, Загрузка файлов

Ключевые слова: WinHTTP, Upload, rghost.ru, Закачать, multipart/form-data, boundary

Описание: Функция для загрузки файла на файлохранилище rghost.ru.
В функции показан принцип формирование запроса формы multipart/form-data для отправки файлов на сервер.
Для работы понадобится библиотека WinHTTP. Взять ее можно здесь
Все важные строчки прокомментированы, что бы легче было разбираться.


Код/Пример для официальной версии:
Код: AutoIt [Выделить]
#include "WinHTTP.au3"
Local $sFileOpenDialog = FileOpenDialog('Выбрать файл для загрузки', @DesktopDir, 'Все файлы (*.*)', 1)
If @error Then
    Exit MsgBox(16, "Отмена", "Файл не выбран. Конец.")
EndIf

Local $URL = FileUpload_Rghost($sFileOpenDialog)
If @error Then
    MsgBox(16, "Ошибка", "Файл не загружен. Ошибка: " & @error & ":" & @extended)
Else
    MsgBox(64, "Ок", "Файл загружен." & @CRLF & "URL = " & $URL)
EndIf
Exit


Код/Пример для бета версии:
Код: AutoIt [Выделить]
#include "WinHTTP.au3"
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
Local $sFileOpenDialog = FileOpenDialog('Выбрать файл для загрузки', @DesktopDir, 'Все файлы (*.*)', $FD_FILEMUSTEXIST)
If @error Then
    Exit MsgBox($MB_OK + $MB_ICONERROR, "Отмена", "Файл не выбран. Конец.")
EndIf

Local $URL = FileUpload_Rghost($sFileOpenDialog)
If @error Then
    MsgBox($MB_OK + $MB_ICONERROR, "Ошибка", "Файл не загружен. Ошибка: " & @error & ":" & @extended)
Else
    MsgBox($MB_OK + $MB_ICONINFORMATION, "Ок", "Файл загружен." & @CRLF & "URL = " & $URL)
EndIf
Exit


Сама функция FileUpload_Rghost:
Код: AutoIt [Выделить]
Func FileUpload_Rghost($sFilePath)
    #cs
        Функция загружает файл на хостинг http://rghost.ru/
        Файл хранится с параметрами по умолчанию

        В случае успеха возвращает URL файла.

        В случае ошибок устанавливает @error:
        1 - Файл не существует
        2 - Не удалось создать подключение к rghost.ru
        3 - Не удалось отправить данные на rghost.ru
        4 - Не удалось получить тэги input из кода страницы сайта rghost.ru
        5 - Не удалось создать подключение к kaon.rghost.ru
        6 - Не удалось отправить данные на kaon.rghost.ru
        7 - Не удалось получить правильный URL из ответа
        @extended - Устанавливает причину ошибок.
    #ce


    Local $hOpen, $hConnect
    Local $error, $extended, $return
    Do
        If Not FileExists($sFilePath) Then ;Файл не существует
            $error = 1
            ExitLoop
        EndIf

        $hOpen = _WinHttpOpen('Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0') ;Строка useragent

        ;Установим тайм-ауты ожиданий. Если большие файлы не загружаются, то увеличивайте значения.
;~      ;Сейчас установлено 3 минуты на отправку запроса и 2 минуты на ожидание ответа.
        _WinHttpSetTimeouts($hOpen, 0, 60 * 1000, 3 * 60 * 1000, 2 * 60 * 1000)

        $hConnect = _WinHttpConnect($hOpen, 'rghost.ru') ;Подключаемся к rghost.ru
        If @error Then
            $extended = @error
            $error = 2
            ExitLoop
        EndIf
        Local $vData = _WinHttpSimpleRequest($hConnect, 'GET', '/', Default, Default, Default, Default, 1) ;Получаем главную страницу, кодировка UTF-8
        If @error Then
            $extended = @error
            $error = 3
            ExitLoop
        EndIf
        _WinHttpCloseHandle($hConnect)

        ;Для отправки формы нам нужно собрать значения следующих полей:
        Local $aNames[3][2] = [['utf8'],['authenticity_token'],['commit']]

        $vData = StringRegExpReplace($vData, "(?s)<!--.*?-->", "") ; Удаление комментариев
        $vData = StringRegExpReplace($vData, "(?s)<!\[CDATA\[.*?\]\]>", "") ; Удаление CDATA

        ;Все эти поля - это тэги input, поэтому собираем все тэги input со страницы
        Local $_Temp, $aTags = StringRegExp($vData, '<\s*' & 'input' & ' [^>]+>', 3)
        If Not IsArray($aTags) Then
            $error = 4
            $extended = 0
            ExitLoop
        EndIf

        ;Все тэги собраны, ищем среди них нужные нам
        For $iData = 0 To UBound($aNames) - 1
            For $Tag In $aTags
                StringRegExp($Tag, 'name' & '\s*=\s*(?:"|''|)(\Q' & $aNames[$iData][0] & '\E)(?:"|''| |\Z)', 1)
                If @error Then ContinueLoop
                $_Temp = StringRegExp($Tag, 'value\s*=\s*(?:"|''|)(.*?)(?:"|''| |\Z)', 1) ;Тэг найден, ищем чему равен value
                If @error Then ContinueLoop
                $aNames[$iData][1] = $_Temp[0]
                ExitLoop
            Next
        Next

        ;Подготавливаем заголовки и тело запроса. Форма: multipart/form-data
        Local $sBoundary = StringFormat("%s%.5f", "----WinInetBoundaryLine_", Random(10000, 99999))
        Local $sHead = ''
        $sHead &= 'X-Requested-With: XMLHttpRequest' & @CRLF
        $sHead &= 'X-Awesome-Uploader: is awesome' & @CRLF
        $sHead &= 'Referer: http://rghost.ru/' & @CRLF
        $sHead &= 'Origin: http://rghost.ru' & @CRLF
        $sHead &= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' & @CRLF
        $sHead &= 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3' & @CRLF
        $sHead &= 'Host: kaon.rghost.ru' & @CRLF
        $sHead &= 'Content-Type: multipart/form-data; boundary=' & $sBoundary & @CRLF

        ;Добавляем в запрос собранные пары name=value
        Local $sData = '--' & $sBoundary & @CRLF
        For $iNames = 0 To UBound($aNames) - 1
            $sData &= 'Content-Disposition:form-data; name="' & $aNames[$iNames][0] & '"' & @CRLF & @CRLF & $aNames[$iNames][1] & @CRLF & '--' & $sBoundary & @CRLF
        Next

        ;Добавляем в конец содержимое файла отправки
        ;Т.к. в имени файла может быть кириллица, то перекодируем имя в URLEncode
        $sData &= 'Content-Disposition:form-data; name="file"; filename="' & __WinHttpURLEncode(StringRegExpReplace($sFilePath, ".*\\", "")) & '"' & @CRLF ;
        $sData &= 'Content-Type: ' & __WinHttpMIMEType($sFilePath) & @CRLF & @CRLF & FileRead($sFilePath) & @CRLF

        ;Все содержимое добавлено, закрываем запрос
        $sData &= '--' & $sBoundary & "--" & @CRLF

        ;подключаемся к другому домену, запрос на сохранение уходит туда
        $hConnect = _WinHttpConnect($hOpen, 'kaon.rghost.ru')
        If @error Then
            $extended = @error
            $error = 5
            ExitLoop
        EndIf

        ; Отправляем запрос методом POST по пути kaon.rghost.ru/files. Передаем заголовки и тело.
        $vData = _WinHttpSimpleRequest($hConnect, 'POST', '/files', Default, $sData, $sHead, Default, 1)
        If @error Then
            $extended = @error
            $error = 6
            ExitLoop
        EndIf

        ;Закрываем хэндлы
        _WinHttpCloseHandle($hConnect)
        _WinHttpCloseHandle($hOpen)

        ;Разбираем ответ регуляркой. Достаем URL файла
        Local $_URL = StringRegExp($vData, 'top\.location\.href\s*=\s*(?:"|''|)(.*?)(?:"|''| |\Z)', 1)
        If @error Then
            $extended = @error
            $error = 7
            ExitLoop
        EndIf

        ;Ответ разобран. Помещаем его в $return
        $error = 0
        $extended = 0
        $return = $_URL[0]
    Until 1

    If $hConnect Then _WinHttpCloseHandle($hConnect)
    If $hOpen Then _WinHttpCloseHandle($hOpen)

    ;Конец функции
    Return SetError($error, $extended, $return)
EndFunc   ;==>FileUpload_Rghost
 


История версий:
(нажмите для показа/скрытия)

Источник: autoit-script.ru
Автор(ы): inververs
« Последнее редактирование: Ноябрь 14, 2013, 14:41:40 от inververs »

Русское сообщество AutoIt

Загрузка файлов в Интернет. Пример для rghost.ru
« Отправлен: Ноябрь 12, 2013, 18:47:23 »

Оффлайн inververs [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 2135

  • Автор темы
  • Репутация: 461
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Через Internet Explorer.

Что бы не нажимать на кнопку "Обзор" , не отлавливать окно и не вставлять имя файла, то имитируем отправку формы, попутно собираем все поля имеющие имя.

Код: AutoIt [Выделить]
Func _IEFormSendFile(ByRef $oIE, ByRef $oForm, $sFilePath)
    Local $sBoundary = StringFormat("%s%.5f", "----IEBoundaryLine_", Random(10000, 99999))
    Local $sHead = ''
    $sHead &= 'Content-Type: multipart/form-data; boundary=' & $sBoundary & @CRLF
    Local $sFileData = ''
    Local $sData = '--' & $sBoundary & @CRLF
    Local $oFormElements = _IEFormElementGetCollection($oForm)
    If IsObj($oFormElements) Then
        For $oElement In $oFormElements
            If Not IsObj($oElement) Then ContinueLoop
            If Not $oElement.name Then ContinueLoop
            If $oElement.type == 'file' Then
                $sFileData &= 'Content-Disposition: form-data; name="' & $oElement.name & '"; filename="' & __WinHttpURLEncode(StringRegExpReplace($sFilePath, ".*\\", "")) & '"' & @CRLF ;
                $sFileData &= 'Content-Type: ' & __WinHttpMIMEType($sFilePath) & @CRLF & @CRLF & FileRead($sFilePath) & @CRLF
            Else
                $sData &= 'Content-Disposition:form-data; name="' & $oElement.name & '"' & @CRLF & @CRLF & $oElement.value & @CRLF & '--' & $sBoundary & @CRLF
            EndIf
        Next
    EndIf
    $sData &= $sFileData
    $sData &= '--' & $sBoundary & "--" & @CRLF
    __IENavigate($oIE, $oForm.action, 1, 0, '', StringToBinary($sData), $sHead)
EndFunc   ;==>_IEFormSendFile
 


Простой пример:
Код: AutoIt [Выделить]
#include "WinHTTP.au3"
#include <IE.au3>
Local $oForm = _IEFormGetObjByName($oIE, 'NameOfForm') ;Нужно передать объект формы
Local $sFilePath = @ScriptDir & '\send.jpg' ;путь к файлу
_IEFormSendFile($oIE, $oForm, $sFilePath)
 


Русское сообщество AutoIt

Re: Загрузка файлов в Интернет. Пример для rghost.ru
« Ответ #1 Отправлен: Ноябрь 14, 2013, 16:09:24 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
12 Ответов
7085 Просмотров
Последний ответ Январь 04, 2010, 20:13:12
от Garrett
6 Ответов
5489 Просмотров
Последний ответ Август 10, 2010, 23:58:02
от anton1157752
8 Ответов
7911 Просмотров
Последний ответ Декабрь 16, 2017, 13:28:56
от ra4o
6 Ответов
4554 Просмотров
Последний ответ Март 20, 2011, 17:55:14
от HungryDwarf
12 Ответов
8016 Просмотров
Последний ответ Апрель 05, 2011, 23:14:55
от zlo-kazan
1 Ответов
4214 Просмотров
Последний ответ Апрель 03, 2012, 11:41:00
от ShAG1992D
10 Ответов
4853 Просмотров
Последний ответ Февраль 25, 2013, 08:33:52
от joiner
3 Ответов
2023 Просмотров
Последний ответ Август 02, 2014, 20:07:42
от Garrett
7 Ответов
2435 Просмотров
Последний ответ Август 14, 2015, 14:18:45
от inververs
8 Ответов
1056 Просмотров
Последний ответ Январь 15, 2018, 17:56:36
от warwar52