Как работать с Human Emulator во многопотоке.

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

Первое, что хотелось бы отметить — для работы в многопоточном режиме требуется
версия Advanced.
Можно так же запустить несколько копий Human Emulator Standart, но все они будут работать с одними куками,
кэшом и прокси, что в большинстве случаев не даст нормально работать в многопоточном режиме.

Для работы в многопотоке разработчики Human Emulator создали специальный инструмент Xhe Manager.
Exe-файл этого инструмента лежит в папке с программой. Но про него мы поговорим в отдельной статье.
В этой статье мы расскажем, как организовывать работу без каких-либо инструментов.

Вообще, многопоточность в Human Emulator выглядит как одновременный запуск нескольких копий программы.
Все эти копии имеют свои настройки, настройки браузера, кэш, куки, прокси и т.д.
Как показала практика использования программы в многопоточном режиме самый оптимальный вариант это не просто запуск
одного exe из одной папки, а раскопирование папки с программой и запуск этих копий. У данного метода есть
много критиков, но опыт показывает, что такая организация многопоточности является наиболее стабильно работающей,
так как каждая копия программы работает со своим php и со своей копией скрипта, таким образом, при падении одного
из потоков все остальные потоки продолжают работать.

Итак, Вы счастливый обладатель Human Emulator Advanced и какого то скрипта, который Вам нужно запустить в 5 потоков.
Для этого нужно просто раскопировать папку с программой пять раз. Например: программа установлена в папку C:\XWeb MT\Human Emulator.
Вы делаете ещё 4 копии программы, указывая в именах порты на которых будут работать потоки.
Дело в том, что каждый новый поток будет использовать для работы свой порт, и запуск программы на одном порту не возможен.
В результате мы имеем пять папок C:\XWeb MT\Human Emulator, который по умолчанию работает на 7010 порту,
C:\XWeb MT\Human Emulator 7011, C:\XWeb MT\Human Emulator 7012, C:\XWeb MT\Human Emulator 7013,
C:\XWeb MT\Human Emulator 7014.

Примечание: Лучше не просто раскопировать папку с программой,
а поставить нужное количество Human Emulator-в с помощью программы установки.
Тогда не придётся править пути к папкам My Scripts и PHP.

После того как все копии установлены Вы копируете скрипт в папку My Scripts для запуска его в каждом потоке.
Далее вы запускаете поочерёдно каждую копию и запускаете на выполнение в ней скрипт.
Если для работы в скрипте требуются файлы с аккаунтами или проксями или какие то другие входные данные,
то обычно их делят на части и каждую часть используют в своём потоке. Хотя можно организовать и обращение всех потоков к одному файлу,
но это несколько сложнее и об этом мы поговорим в отдельной статье.

При запуске каждой копии вы не забываете менять порт. Это можно сделать не запуская Human Emulator.
Для этого достаточно перед запуском выставить нужный порт в файле port.txt, который лежит в папке с программой.

Максимальное количество потоков ограничивается ресурсами Windows и параметрами Вашего компьютера.
Известны случаи стабильной работы программы в 200-300 потоков.

Так же для увеличения скорости выполнения скрипта и числа потоков можно использовать RT версию программы — XWeb Human Emulator MT RT.exe.
RT (run time) версия, которая специально была разработана для запуска в многопоточном режиме.
Эта версия представляет из себя полностью обрезанный Human Emulator, в котором остался только браузер.
Exe-шник этой версии лежит в папке с программой.

Распознавание капчи с помощью Human Emulator

Цитата WikipediaCAPTCHA (от англ. Completely Automated Public Turing test to tell Computers and Humans Apart — полностью автоматизированный публичный тест Тьюринга для различия компьютеров и людей) — товарный знак Университета Карнеги — Меллона, в котором разработали компьютерный тест, используемый для того, чтобы определить, кем является пользователь системы: человеком или компьютером.

Данный тест широко применяется при регистрации, при добавлении сообщений, комментариев, объявлений и т.д.

Примеры капч для распознавания:

Примеры капч для распознавания

Примеры капч для распознавания

В Human Emulator есть три функции для распознавания капчи:

recognize_captcha – распознать картинку с диска как капчу

recognize_by_anticaptcha – распознать капчу картинки через сервис антикапча

recognize_by_captchabot – распознать капчу картинки через сервис капчабот

recognize_captcha функция самостоятельно разгадывает 10 видов простых капч. Что за капчи и каков процент их правильного разгадывания
можно посмотреть в документации к программе http://humanemulator.net/objects/DOM/image/recognize_captcha.php

recognize_by_anticaptcha и recognize_by_captchabot используют сервисы распознания antigate.com и captchabot.com. Для расширения работы с этими сервисами были добавлены объекты anticapcha(http://humanemulator.net/objects/DOM/anticapcha.php)
и captchabot(http://humanemulator.net/objects/DOM/captchabot.php).

Так же для ручного распознания в Хумане есть функции, которые показывают капчу в отдельном диалоге и
дают вам возможность ввести капчу самому:

dlg_captcha_from_image_number – диалог ввода капчи из картинки c заданным номером

dlg_captcha_from_url – показать диалог ввода капчи из картинки по заданному урлу

dlg_captcha_from_url_exactly – показать диалог ввода капчи из картинки по заданному урлу с соотвествием урла
(см. http://humanemulator.net/objects/WINDOW/app.php)

Приведём несколько примеров скриптов для использования различных капч.

Для начала используем функцию для распознания капч средствами Human Emulator. Для примера возьмём форму регистрации на сайте xanga.com. Этот сайт использует капчу 9 типа, которую Хуман разгадывает с 45%-м правильным разгадыванием.

Функция $image->recognize_captcha($file_path,$type); на вход принимает путь к файлу с картинкой и тип картинки. Поэтому перед тем как вызывать эту функцию нам нужно сохранить картинку в файл на диск. Для этого используем функцию $image->screenshot_by_src.

Примечание: Лучше всего работать с картинками по их src или по части их src. Для того, что бы посмотреть src картинки можно открыть информацию о ней в Инспекторе Элементов, щёлкнув на ней правой кнопкой мыши и в появившемся контекстном меню выбрать пункт “Посмотреть в инспекторе элементов” или в этом же меню можно выбрать Щёлкнуть и далее $image->click_by_src и в скрипт вставиться функция клика с полным src, из которого можно будет взять нужный кусок, который будет одинаковый при каждом обновлении страницы.

В данном случае функция будет выглядеть следующим образом: $image->screenshot_by_src(«C:\\Temp\\tmp.jpeg»,»randletters.aspx?fy»,false);
Тогда функция $image->recognize_captcha(«C:\\Temp\\tmp.jpeg»,9);

Теперь добавим в этот же скрипт вызов диалога ввода капчи $str_captcha=$app->dlg_captcha_from_url_exactly(«randletters.aspx?fy»,false); и переменную-флаг для настройки работы через распознание или через диалог ввода. В итоге наш скрипт будет:

$xhe_host ="127.0.0.1:7011";

// The following code is required to properly run XWeb Human Emulator
require("../../Templates/xweb_human_emulator.php");

// показывать через диалог
$b_show_dlg=true;

// переход на добавление объявления
$browser->navigate("http://www.xanga.com/register.aspx");
// строка с символами
$str_captcha="";
// распознать капчу
if($b_show_dlg)  // используя диалог
   $str_captcha=$app->dlg_captcha_from_url_exactly("randletters.aspx?fy",false);
else
{
    // сохранить картинку в файл по части src 
    $image->screenshot_by_src("C:\\Temp\\tmp.jpeg","randletters.aspx?fy",false);
    // распознать картинку
    $str_captcha=$image->recognize_captcha("C:\\tmp.jpeg",9);
}
// задать значение в поле ввода капчи
$input->set_value_by_name('registrationModule$txtLetters',$str_captcha);

// Quit
$app->quit();

Теперь напишем скрипт, который использует сервисы распознавания antigate.com и captchabot.com. Для примера возьмём сайт с flash капчей http://snappages.com/register. В данной форме регистрации для отображения капчи используется flash объект, который проигрывает символы в flash проигрывателе. Для того что бы распознать такую каптчу, мы используем одну из функций screenshot_by_*, которая сохраняет картинку элемента на диск и затем уже будем отправлять сохранённую картинку на сервис распознания.

Примечание: К сожалению, описания функций screenshot_by_* пока нет в документации к Human Emulator. Данные функции работают для всех объектов и сохраняют их снимок на диск по заданному пути. То есть вы можете сделать фотографию любого элемента страницы, используя тот или иной атрибут элемента. Для вызова этих функций можно использовать контекстное меню элемента->пункт меню «Сохранить» и выбрать нужную функции из появившегося списка.

Для http://snappages.com/register сохранение флэш объекта будет выглядеть следующим образом:

$object->screenshot_by_name("C:\\Temp\\tmp.jpeg","captchaSwf");

, а вызов фунций для сервисов распознания:

// распознать капчу с помощью antigate.com 
$str_captcha=$image->recognize_by_anticaptcha("","C:\\Temp\\tmp.jpeg",$api_key,$path='http://antigate.com',$is_verbose = true, $rtimeout = 5, $mtimeout = 120, $is_phrase = 0, $is_regsense = 1, $is_numeric = 0, $min_len = 0, $max_len = 0);

// распознать капчу с помощью captchabot.com 
$str_captcha =$image->recognize_by_captchabot($api_key,"C:\\Temp\\tmp.jpeg","");

, где $api_key – это ключ сервиса распознания

Обернём все вызовы для распознания капчи в оператор switch и добавим флаг для выбора механизма распознавания. Теперь наш скрипт будет выглядеть следующим образом:

$xhe_host ="127.0.0.1:7011";
// The following code is required to properly run XWeb Human Emulator
require("../../Templates/xweb_human_emulator.php");

// что использовать для распознания
// 0 - диалог ввода каптчи
// 1 - antigate.com
// 2 - captchabot.com
$b_use=2;

// ключ антикаптчи
$api_key_antg="ваш ключ";
// ключ каптчабот
$api_key_cpt="ваш ключ";
// путь куда сохранить картинку
$img_path="C:\\Temp\\tmp.jpeg";

// переход на добавление объявления
$browser->navigate("http://snappages.com/register ");
// строка с символами
$str_captcha="";
// сохраним элемент на диск
$object->screenshot_by_name($img_path,"captchaSwf");
// распознать капчу
switch($b_use)  // используя диалог
{
   case 0:
   {
		// показать диалог ввода каптчи
		$str_captcha=$app->dlg_captcha_from_url($img_path);
		break;
   } 
   case 1:
   {
     // распознать капчу с помощью antigate.com 
     $str_captcha=$image->recognize_by_anticaptcha('',$img_path,$api_key_antg,$path='http://antigate.com',$is_verbose = true, $rtimeout = 5, $mtimeout = 120, $is_phrase = 0, $is_regsense = 1, $is_numeric = 0, $min_len = 0, $max_len = 0);
     break;
   }
   case 2:
   {
     // распознать с помощью captchabot
     $str_captcha =$image->recognize_by_captchabot($api_key_cpt,$img_path);
     break;
   }
   default: // показать диалог ввода каптчи
    	$str_captcha=$app->dlg_captcha_from_url($img_path);
    
}
// задать значение капчи
$input->set_value_by_name("captcha",$str_captcha);

// Quit
$app->quit();

Скрипты написаны в XHE 4.4.19 MT.

скачать примеры скриптов

Удалённое управление Human Emulator.

Одно из малоизвестных свойств Human Emulator это возможность удалённого управления.
Допустим, у вас есть Linux-сервер, на котором выполняется какой-то скрипт php по сбору данных.
Вам нужно отправить эти данные на обработку в Human Emulator и получить результаты работы обратно.
Но, как известно, XHE не работает в Linux-системах.

Можно поставить на Linux сервер эмулятор Windows и работать как обычно,
а можно поставить Human Emulator на комп с Windows и управлять им c Linux-сервера или с любого хостинга, который поддерживает php.
По такой же аналогии Хуман может стоять на одном компе с Windows, а запускать его можно, например, с ноутбука в одной локальной сети.
Для этого достаточно знать ip и порт, на котором запущенна программа.

Предположим, что Human Emulator стоит на сервере ip которого 190.90.198.14 на порту 7010 и пароль в настройках программы
для управления Хуманом не задан. Программа открыта и готова к работе. Для начала можно проверить связь с ней.
Для этого сделаем вызов команд XHE из любого браузера. Берём и вводим в адресную строку следующий текст
http://190.90.198.14:7010/Browser.navigate?url=google.ru
и нажимаем перейти. XHE на сервере должен перейти на страницу google.com. Если это произошло, то связь с программой установлена, если нет,
то нужно проверить ip, порт и пароль в настройках программы, а так же посмотреть, не блокирует ли файервол или антивирусник заданный порт.
Через браузер можно передавать любые команды Human Emulator. Например:

http://190.90.198.14:7010/Browser.navigate?url=http%3A%2F%2Fgoogle.com&use_cache=1
— Переходим на Google.com

http://190.90.198.14:7010/Input.SetValueByName?name=q&value=human
— Вводим поисковую строку в поле поиска google.

http://190.90.198.14:7010/InputButton.ClickByNumber?number=0
— Нажимаем на кнопку поиска.

Текст команд можно брать из панели информации или из шаблона XHE.

Итак, связь с Хуманом проверена и установлена. Теперь можно запустить скрипт. Для того что бы скрипт выполнялся на XHE,
который стоит на удалённом сервере, нам необходимо в скрипт передать IP и порт на котором запущена программа.
Для этого используется переменная $xhe_host.

В скрипте это будет выглядеть следующим образом:

navigate('http://google.com');
// вводим поисковую строку в поле поиска google
$input->set_value_by_name('q',"human");
// нажимаем на кнопку поиска
$button->click_by_number(0);

// Quit
$app->quit();
?>

Примечание: При использовании в скрипте работы с файлами средствами php все действия с ними будут выполняться на компе, на котором запускается скрипт. Если работа с файлами реализована с помощью команд Human Emulator, то все манипуляции будут выполняться там же где стоит программа. Так, если есть в скрипте, который запускается на компе без XHE чтение/запись из/в файл, то для их корректной работы нужно использовать php функции.

Для запуска скрипта на том компе где не стоит хуман вам необходимо иметь установленный php. И через командную строку запустить этот скрипт на выполнение.

Пример командной строки: C:\PHP\php.exe «C:\My Scripts\MyScript22.php». Эту строку можно поместить в .bat файл и запускать его.

По аналогии можно управлять Human Emulator со страниц вашего сайта. Для этого нужно встроить на сайт форму, которая будет запускать скрипт и передавать в него параметры.

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

Введите строку для поиска:

При этом файл run_search.php будет лежать там же где и страница с формой и выглядеть следующим образом:

navigate('http://google.com');
// вводим поисковую строку в поле поиска google
$input->set_value_by_name('q',"human");
// нажимаем на кнопку поиска
$button->click_by_number(0);

echo "выполнено!";
}
else
echo "запрос не введён. введите запрос!";

// Quit
$app->quit();
?>

Более подробно про передачу параметров с помощью HTML-форм можно прочитать в мануале по php. Если у вас есть вопросы или какие-то соображение
по данной теме всегда можно спросить на форуме.

Загрузка файла на сайт. Использование объекта inputfile. Функция execute_open_file.

По многочисленным просьбам наших читателей мы решили начать цикл статей, которые помогут вам понять, как самостоятельно можно решать те или иные задачи с помощью Human Emulator. И начнём мы с загрузки файла на сайт.

Очень часто, когда мы даём объявление на доску то нам предлагают загрузить фото размещаемого товара на сайт.

Это может выглядеть следующим образом:

Доска объявлений ria.ua

Доска объявлений emarket.ua

Доска объявлений slando.ua

Или же нам нужно залить файл на файлообменник, например на depositfiles.com:

Файлообменник depositfiles.com

Или же на любой другой сайт, где используются поля загрузки файла

Примеры полей загрузки файла на полигоне humanemulator.net

Загрузка файла в html осуществляется через тэг

Для работы с этим тэгом в Human Emulator есть объект inputfile.
Возможности этого объекта описаны тут
Для заполнения полей загрузки файла используются команды $inputfile->set_value_by_name и $inputfile->set_value_by_number. Скрипты с примерами этих команд можно найти в закладке Быстрый старт в папке «Tests\DOM\inputfile\common\».

Теперь напишем скрипт для доски emarket.ua.
Итак, переходим в Хумане на emarket.ua. Далее заходим на страницу добавления товара и находим поле, в которое нужно добавить фотографии. Вместо поля ввода пути к файлу видим кнопку с текстом «+Добавить». После нажатия на неё у нас появляется системный диалог открытия файла с заголовком «Выберите файлы для отправки с помощью emarket.ua». На разных системах заголовок диалога может отличаться.

Для обработки этих диалогов в Human Emulator есть специальная функция $window->execute_open_file($text,$path,$btn_text,$exactly=true,$thread=false);. Теперь в скрипте нам просто нужно нажать на кнопку и вызвать обработку появившегося диалога.

Для этого кликнем правой кнопкой мыши на кнопке с текстом добавить «+Добавить». Выберем пункт меню «Щелкнуть», подменю $object->click_in_by_name(«uploadButton»);. Эта строка появиться в скрипте.

Примечание: Для работы с объектами лучше использовать функции, которые работают по имени или id или другому уникальному атрибуту элемента, так как при добавлении ещё одного элемента такого же типа номера могут измениться и скрипт прекратит работу. Вам опять придётся проставлять в скрипте номера. Если сайт меняется не часто, то в принципе в этом нет ничего страшного, если же сайт меняется регулярно, то это может быстро утомить.

Запустим скрипт. Ничего не происходит. Функция click_in_by_name имеет параметры($name,$x=-1,$y=-1,$frame=-1); Попробуем передать координаты кнопки в эту функцию. Для получения координат воспользуемся функциями $object->get_x_by_name и $object->get_y_by_name в скрипте это будет выглядит так:

// получить координаты элемента
echo $x=$object->get_x_by_name("uploadButton")+5;
echo $y=$object->get_y_by_name("uploadButton")+5;

Если кнопка не видима в браузере, то клик на неё может не пройти. Поэтому при клике на какой-либо элемент в Human Emulator, браузер программы автоматом переходит на этот элемент, так что бы он стал видимым. При этом может измениться Y координата элемента. Но элемент при этом будет всегда в нижней части браузера, поэтому мы можем привязать Y элемента к высоте браузера.
В итоге скрипт будет:

// получить координаты элемента
echo $x=$object->get_x_by_name("uploadButton")+5;
echo $y=$object->get_y_by_name("uploadButton")+5;

// вычислить Y координату элемента через высоту браузера
if($browser->get_window_height()<$y) $y=$browser->get_window_height()-25;

// кликнуть на элемент 
$object->click_in_by_name("uploadButton",$x,$y);

Запускаем скрипт. Открылся диалог выбора файла. Теперь нам нужно добавить обработку этого диалога с помощью функции $window->execute_open_file($text,$path,$btn_text,$exactly=true,$thread=false).
К сожалению, описания этой функции на humanemulator.net нету. Поэтому опишем параметры, которые нужно передавать в функцию:
$text — это заголовок диалога полностью или частично;
$path — путь к одной или нескольким картинкам, если вы передаёте несколько картинок, то они должны быть в кавычках и через пробел — «c:\\picture1.jpg» «c:\\picture2.jpg» «c:\\picture3.jpg» и т.д.;
$btn_text — текст кнопки, на которую надо кликнуть, причём текст этот должен полностью соответствовать тексту внутри окна кнопки. То есть, если мы нажмём на alt, то увидим подчёркнутую букву, значит перед этой буквой стоит символ &. Так в нашем случае текст кнопки будет &Открыть.
$exactly — говорит о том полностью или частично задан заголовок диалога. По умолчанию этот параметр true, то есть строгое соответствие параметра $text заголовку диалога.
$thread — последний параметр говорит, о том нужно ли запускать эту функцию в отдельном потоке или нет. Что это значит? Диалоги могут быть модальные и не модальные.
Модальный диалог блокирует все остальные окна приложения так, что пользователь не может с ними ничего сделать, пока не закроет диалог.
Не модальный диалог больше похож на обычные окна, т. к. он даёт пользователю возможность доступа к остальным окнам приложения.
Самый простой способ определить модальный или не модальный диалог это открыть его и кликнуть на любое другое окно программы, если мы услышим звук beep, то это модальный диалог, если же мы перешли на окно, значит диалог не модальный. В случае с модальным диалогом параметр thread должен быть равен true и функция execute_open_file должна вызываться перед кликом на элемент, который открывает диалог выбора файла. Для не модального диалога thread=false и функцию можно вызывать после появления диалога.

На emarket.ua как и на большинстве досок используется модальный диалог, то есть он блокирует доступы ко всем остальным окнам программы. Теперь скрипт будет:

// получить координаты элемента
echo $x=$object->get_x_by_name("uploadButton")+5;
echo $y=$object->get_y_by_name("uploadButton")+5;

// вычислить Y элемента  
if($browser->get_window_height()<$y) $y=$browser->get_window_height()-25;

// задать обработку для диалога добавления файла
$window->execute_open_file("Выберите файлы","путь к загружаемому файлу","&Открыть",false,true);
// кликнуть на элемент 
$object->click_in_by_name("uploadButton",$x,$y);

Вот и готово. Но у данного способа есть свои минусы. При многопоточном использовании скрипта с таким кодом может возникнуть ситуация, когда один скрипт вставляет файлы в диалоговое окно открытое другим скриптом. Если файлы одинаковые то это не страшно, а вот если нет, то это уже не хорошо. Можно, конечно, написать код который будет проверять обрабатывает ли в данный момент какой то скрипт этот диалог или нет, но лучше пойти по пути использования
непосредственно поля <input type=»file»> через функции set_value_by_*. Обработка загрузки файлов таким способом будет проще и работать быстрее. В последних версиях программы данная проблема решена и теперь каждая копия работает со своим открытым диалогом.

Для данной доски это можно решить через нажатие на ссылку с текстом «простой формой загрузки фото». После нажатия на эту ссылку показываются поля ввода пути к файлу, который надо загрузить. И в данном случае скрипт будет:

// простые inputfile
$anchor->click_by_inner_text("простой формой загрузки фото");
// заполнить поле путём к файл
$inputfile->set_value_by_name("file_$i","путь к загружаемому файлу");

Из практики написания скриптов, есть моменты, когда $inputfile->set_value_by_name нужно вызывать дважды иначе он не заполняет поле. Или если поле находится в форме, то он может не отображать текст в поле на сайте, но при сабмите формы этот путь будет проходить. Так же можно, находить скрытые элементы <input type=»file»>, в которые добавляется вводимый вами путь через java script и пробовать добавлять путь к файлу напрямую в этот элемент, даже если его не видно на странице. Так же нужно обратить внимание на то, что при добавлении пути к файлу должен быть соблюден формат пути, то есть путь должен начинаться с диска, например: c:\\, иначе текст может не вставляться в поле.

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

Скрипт добавления нескольких файлов на emarket.ua

get_all_items($str_img_path);
// разобьём строку на массив путей
$a_images=explode("\n",$str_images);

// какой способ использовать для добавления картинки
$b_use_obj=true;

// переход на добавление объявления
$browser->navigate("http://emarket.ua/adding/");

// каким способом добавлять фото
if($b_use_obj)
{
   // добавим сразу все фото
   $str_files="";
	for($i=0;$i<count($a_images);$i++)
      $str_files.="\"".trim($a_images[$i])."\" " ;
		
  // если есть что добавлять
  if($str_files!="")
  {
     // получить координаты элемента
		echo $x=$object->get_x_by_name("uploadButton")+5;
		echo $y=$object->get_y_by_name("uploadButton")+5;

      	// вычислить Y элемента  
		if($browser->get_window_height()<$y)
		  $y=$browser->get_window_height()-25;

		// задать обработку для диалога добавления файла
		$window->execute_open_file("Выберите файлы",$str_files,"&Открыть",false,true);
		// кликнуть на элемент 
		$object->click_in_by_name("uploadButton",$x,$y);
  }
}
else
{
   // простые inputfile
	$anchor->click_by_inner_text("простой формой загрузки фото");
	for($i=0;$iset_value_by_name("file_$i",$a_images[$i]);
}



// Quit
$app->quit();
?>

Скрипт добавления нескольких файлов на ria.ua

get_all_items($str_img_path);
// разобьём строку на массив путей
$a_images=explode("\n",$str_images);

// какой способ использовать для добавления картинки
$b_use_obj=true;


// переход на добавление объявления
$browser->navigate("http://www.ria.ua/advertisement/addstep1");

// каким способом добавлять фото
if($b_use_obj)
{
   // добавим сразу все фото
   $str_files="";
	for($i=0;$i<count($a_images);$i++)
      $str_files.="\"".trim($a_images[$i])."\" " ;
		
  // если есть что добавлять
  if($str_files!="")
  {
		// задать обработку для диалога добавления файла
		$window->execute_open_file("Выберите файлы",$str_files,"&Открыть",false,true);
		// кликнуть на элемент 
		$object->click_in_by_name("SWFUpload_0");
  }
}
else
{
   $anchor->click_by_inner_text("Упрощенная система загрузки фотографий");

	for($i=0;$i<count($a_images);$i++)
   {
		$inputfile->set_value_by_number($i,$a_images[$i]);
       $anchor->click_by_inner_text("добавить еще фото");
      sleep(1);
   }
}

// Quit
$app->quit();
?>

Скрипт добавления нескольких файлов на depositfiles.com

get_all_items($str_img_path);
// разобьём строку на массив путей
$a_images=explode("\n",$str_images);

// переход на добавление объявления
$browser->navigate("http://depositfiles.com/");

// добавим фото
for($i=0;$i<count($a_images);$i++)
{
   // задать путь
   $inputfile->set_value_by_name("files",trim($a_images[$i]));
   // загрузить фото
   $button->click_by_inner_text("Загрузить сейчас");

   sleep(5);
   // загрузить следующий
   $anchor->click_by_inner_text("Загрузить другой файл");
}
// Quit
$app->quit();
?>

Пример загрузки фото на одну из досок, используя функцию set_value_by_name

// устанавливаем фокус на поле
$inputfile->set_focus_by_name("photo");

// дважды задаём значение
$inputfile->set_value_by_name("photo",'C:\XWeb MT\Human Emulator 7011\My Scripts\images\22a.jpg');
//sleep(1);
$inputfile->set_value_by_name("photo",'C:\XWeb MT\Human Emulator 7011\My Scripts\images\22a.jpg');
// кликаем мышкой в любую точку страницы для того что бы введённый текст появился в поле
$mouse->click(61,402);
// нажимаем на кнопку загрузить
$button->click_by_name("logoUploadButton");

Скрипты написаны в Xweb Human Emulator 4.4.19 MT.

скачать примеры скриптов

Циклы в скриптах php и Human Emulator

Итак, у вас есть простой скрипт, который вы хотели бы запускать в цикле.

Первый способ зациклить ваш XHE скрипт это воспользоваться расписанием скриптов.
В программе есть настройки, которые позволяют запускать скрипт раз в минуту, раз в 5 минут и т.д. Это пожалуй самый простой способ, но у этого способа
есть существенные минусы — например если нужно читать из файла какие-либо данные, то придётся хранить индекс прочитанной строки, где то в отдельном файле
и потом подставлять его в скрипт. Согласитесь это не очень удобно.

Вместо этого можно организовать цикл основанный на чтении данных из файла. Предположим у нас есть некий файл с проксями «proxy.txt», из которого нам
нужно взять прокси подставить его в скрипт и перейти на какой то сайт. При этом, как только мы подставим все прокси из файла скрипт должен остановиться.
Для этого первым делом мы получим прокси из файла в массив следующим кодом . Теперь когда у нас все прокси получены в массив
делаем цикл for на основе этого массива следующим кодом — где
— это количество элементов в массиве. В результате у нас получается следующий код скрипте:

// получить прокси из файла в массив
$proxies= file("proxy.txt");
// цикл пройтись по всем прокси в массиве
for($i=0;$i<count($proxies);$i++) { // получить прокси из массива $proxy = $proxies[$i]; // задать прокси браузеру $browser->enable_proxy("all connections",$proxy); 
   // перейти на сайт проверки ip
   $browser->navigate('2ip.ru');
   $browser->wait_for(60,0);

   // идём куда то дальше и что то делаем ещё ... 
}

Если нужно что бы цикл выполнил действия заданное количество раз, например 10, то тогда код в скрипте будет выглядеть следующим образом:

// выполнить цикл 10 раз
for($i=0;$i<10;$i++) { // перейти на сайт google.com $browser->navigate('google.com');
   $browser->wait_for(60,0);

   // идём куда то дальше и что то делаем ещё ... 
}

Ещё один способ организовать цикл в скрипте это использовать while. Например нам нужно подобрать логин на сайт,
который ещё не занят. При этом когда в поле логина вводим значение на странице регистрации появляется текст «is already taken».
Для начала после заполнения поля логина сделаем проверку есть ли этот текст на странице следующим кодом
— где strpos это функция получения индекса заданного текста в строке, если строки нет то возвращает false; $webpage->get_body() — функция получения body текущей страницы в браузере;.
Теперь мы организовываем цикл на основе этого индекса следующим кодом — то есть
выполнять действие до тех пор пока индекс равен false. В итоге имеем следующий код в скрипте:

 
// перед этим переходим на страницу регистрации и заполняем поле login
 
// проверим не появился ли текст сигнализирующий о том что логин уже занят
$ind = strpos($webpage->get_body(),"is already taken");
// делаем цикл - если не нашли нужный текст повторяем операцию заново
while($ind!==false)
{
  // тут задаём новое значение в поле логина
 
  // проверяем опять не появился ли текст после ввода нового логина в поле
  $ind = strpos($webpage->get_body(),"is already taken");
}

С помощью for и while можно создавать бесконечные циклы — . В скрипте это будет выглядеть так:

 
// делаем бесконечный цикл while 
while(true)
{
  // что то делаем...
  
  // условие для выхода из бесконечного цикла
  if(какое то условие)
     break;
}
// бесконечный цикл for
for ($i = 1;;$i++) 
{
  // что то делаем.... 
  
  // условие для выхода из бесконечного цикла
  if(какое то условие)
     break;
}

Оператор break служит для выхода из цикла.

Более подробно про циклы в php можно найти тут www.phpfaq.ru/php5.ru/study/chapter3.html#loop

Работа с файлами в скриптах Human Emulator

Для работы с файлами в XWeb Human Emulator предусмотрены два объекта — file_os и textfile.
Как не трудно догадаться объект file_os служит для работы со всеми файлами, а объект textfile служит для работы
с текстовыми файлами. Рассмотрим основной функционал этих объектов.

Объект file_os:
copy – копировать файл

move – переместить файл

rename – переименовать файл

delete – удалить файл

Пример работы с объектом в скрипте:

// The following code is required to properly run XWeb Human Emulator
require("../../../Templates/xweb_human_emulator.php");

// копировать файл
// параметры:
// $path – путь к существующему файлу
// $new_file_place – новый путь к файлу(новое место хранения файла)
// $flag_fail_exist – флаг, определяющий поведение функции при существовании файла с таким же именем на новом месте
echo $file_os->copy("C:Doc1.txt","C:Doc2.txt","true");

// переместить файл
// параметры:
// $path – путь к существующему файлу
// $new_file_place – новый путь к файлу(новое место хранения файла)
echo $file_os->move("C:Doc1.txt","C:2.txt");

// переименовать файл
// параметры:
// $path – путь к существующему файлу
// $new_file_name – новое имя файла
echo $file_os->rename("C:Doc1.txt","C:Doc2.txt");

// удалить файл
// параметры:
// $path – путь к существующему файлу
echo $file_os->delete("C:Doc1.txt");

// Quit
$app->quit();

Объект textfile:

read_file – прочитать файл

write_file – записать файл

add_string_to_file – добавить строку в файл

get_line_from_file – получить случайную строку из файла

Пример работы с объектом в скрипте:

// The following code is required to properly
// run XWeb Human Emulator
require("../Templates/xweb_human_emulator.php");

// считать файл C:1.txt с диска в переменную text
// параметры :
// $file – путь к файлу
// $timeout – таймаут на обработку файла, параметр существенен
// для работы с большими файлами
$text = $textfile->read_file('C:1.txt',10);

// записать файл C:1.txt на диск с содержимым TEST
// параметры :
// $file – путь к файлу
// $str – содержимое
// $timeout – таймаут на обработку файла
$textfile->write_file('C:1.txt','TEST',60);

// добавить строку в файл
// параметры :
// $file – путь к файлу
// $str – строка
// $timeout – таймаут
$textfile->add_string_to_file('C:1.txt',"добавить строку в файл."rn",60);

// получить заданную строку из файла (нумерация строк(линий) начинается с 0)
// параметры :
// $file – путь к файлу
// $rand – с помощью этого параметра задаём получать случайную строку или заданную. Параметр может быть true или false.
// $line – номер строки, которую нам надо получить. Если параметр $rand задан как true, то данный параметр не работает.
// $timeout – таймаут
// с помощью оператора echo выведем строку в окно отладки программы

echo $textfile->get_line_from_file("c:testproxy_1.txt","false",5,60) ." - заданная строка 
" ;

// Quit
$app->quit();

Более подробное описание по этим объектам можно найти тут и
тут

Помимо встроенных объектов в скриптах XHE доступна вся работа с файлом, которая есть в языке PHP.
Например, такие функции как file, file_get_contents, file_put_contents, fopen, fread, fwrite, file_exists, is_file, сору, rename и многие другие.
Описание всех этих функций можно найти в мануалах по PHP.

Пример использования некоторых PHP функций работы с файлом в скриптах XHE:

// The following code is required to properly run XWeb Human Emulator
require("../../../Templates/xweb_human_emulator.php");

// получение данных из файла в массив - каждая строка это элемент массива
// в данном примере получаем прокси из файла в массив
$proxies= file("proxy.txt");

// прочитать весь файл в переменную text
$text = file_get_contents('people.txt');

// Читаем 14 символов, начиная с 21 символа
$section = file_get_contents('people.txt', NULL, NULL, 20, 14);

// проверяем существует ли файл в папке где лежит сам скрипт
if (!file_exists("proxy.txt"))
{
// если файла не существует создаём файл и пишем в него строку "прокси"
file_put_contents("proxy.txt","прокси");
}

// открыть файл на чтение
$handle = fopen("res.txt", "r");
while (!feof($handle))
{
// читаем строку из файла
$buffer = fgets($handle, 1024);
// покажем что прочитали в окне отладки
echo $buffer."
";

// что делаем ещё со строкой ...
}
// закрываем файл
fclose($handle);

// Quit
$app->quit();

Эмуляция действий пользователя на странице

Мы решили раскрыть весь арсенал XHE для этой задачи. Причём, вопросы анонимности и возможности менять параметры браузера мы рассмотрим в отдельной статье, а тут расскажем что именно и как может эмулировать XWeb Human Emulator.

Что делает человек когда приходит на какой то сайт. Он его просматривает, перелистывая вверх вниз полосу прокрутки или колесо мыши, переходит по внутренним ссылкам. Всё это может делать Хуман.

Для работы с мышью в XHE есть объект $mouse, который может кликать правой и левой кнопкой мыши, передвигать мышь, прокручивать колесо мыши. При этом есть два режима, в которых работают функции этого объекта. Это в режиме отправки сообщений и в режиме реального использования курсора мыши. При работе с реальной мышью, вы не сможете пользоваться компом, и нужно будет что бы xhe был открыт на экране. Понятное дело, что этот режим не приемлем для работы в многопоточном режиме, та и вообще, хотелось бы иметь доступ к своему компу. Поэтому лучше работать через отправку сообщений. К режиму отправки сообщений относятся все функции, которые начинаются $mouse->send_*, например: $mouse->send_click или $mouse->send_wheel. Посмотреть описание объекта можно тут.

Для работы с клавиатурой в XHE используется объект $keyboard. Этот объект эмулирует нажатие кнопок клавиатуры. Он так же как объект $mouse может работать в двух режимах. В режиме отправки сообщений и нажатия реальных кнопок клавиатуры. И как в случае с мышью, к режиму отправки сообщений относятся все функции, которые начинаются $keyboard->send_*, например: $keyboard->send_key. Посмотреть описание объекта можно тут.

Для того что прокрутить скроллы в браузере можно использовать функции $browser->set_vertical_scroll_pos и $browser->set_horizontal_scroll_pos.

Для работы ссылками используется объект $anchor, с помощью него можно кликать по ссылкам получать по ним данные типа href и внутреннего текста, координаты и размеры, задавать на них фокус и многое многое другое. Посмотреть описание объекта можно тут.

Для ожидания на странице можно использовать функцию sleep(секунды);

Ниже приведу пример простой функции эмуляции действий пользователя на странице:

// функция эмуляции пользователя
function emul_user()
{
// объявим глобальные объекты
global $mouse,$browser,$textfile;
// ожидаем - время паузы получим случайно от 1 до 3 секунд
sleep(rand(1,3));
// покрутим колесо мыши вниз случайное количество раз
$mouse->send_wheel(-rand(1,7),1200,300);

// ожидаем - время паузы получим случайно от 1 до 5 секунд
sleep(rand(1,5));

// получить размеры браузера
$h = $browser->get_window_height(); // высота
$w=$browser->get_window_width(); // ширина
// пошлём движение мыши от 3 до 10 раз
for($ii=0;$ii<rand(3,10);$ii++)
{
$mouse->send_move(rand(10,$w),rand(10,$h));
// сюда можно добавить случайную паузу
$mouse->send_move(rand(10,$w),rand(10,$h));
$mouse->send_move(rand(10,$w),rand(10,$h));
$mouse->send_move(rand(10,$w),rand(10,$h));
}

// ожидаем - время паузы получим случайно от 1 до 3 секунд
sleep(rand(1,3));
// покрутим колесо мыши вверх
$mouse->send_wheel(rand(1,5),1200,300);

// ожидаем - время паузы получим случайно от 1 до 3 секунд
sleep(rand(1,3));
}