X-Scripts

Power by humanemulator

НАШИ КОНТАКТЫ:
ICQ My ICQ 625657402: 625657402
Наш скайп: igor_sev2
Email : order@x-scripts.com

Сообщество программистов и манимейкеров


Human Emulator Free!
Бесплатная версия программы Human Emulator!
Скачать программу можно тут!

Скрипт для добавления объявлений на сайт localmart.ru

В этой статье мы рассмотрим один из примеров написания скрипта для добавления объявлений на сайт localmart.ru, в раздел Недвижимость.

Начнем с подготовительной части - просмотрим сайт и узнаем какие поля обязательны для заполнения и какие нам бы хотелось заполнить дополнительно.

Перед написанием скрипта необходимо определиться с требованиями к функционалу скрипта:

* Публикуем объявления в один раздел: "Недвижимость => Аренда => Квартиры, комнаты"

* Город: Москва

* Скрипт должен работать постоянно и публиковать новые объявления по мере их появления в указанной дирректории.

* Авторизация на localmart.ru: не нужно, т.к. будем писать контактные данные в описании объявления.

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

* Текстовый файл, в кот-ом будут располагаться объявления должен называться "ad.txt".

* Объявления не готовые к публикации (черновики) должны располагаться в дирректории с названием начинающемся на "[draft]".

* Опубликованные объявления: после публикации объявления дирректория с объявлением будет переименована:
  в начало названия объявления будет добавлено "[published]", перед публикацией было:

  "Сдам комнату" после публикации будет: "[published] Сдам комнату"

* После публикации объявления в файл url.txt будет сохранена ссылка на опубликованное объявление.

Описание формата файла "ad.txt" с содержанием объявления.

Файл ad.txt - это обычный текстовый файл в кодировке "windows-1251". Формат файла - ini (такое же форматирование имеет, например, файл конфигурации PHP -- php.ini).

Ini-формат легок для чтения/редактирования человеком, а также,с данным форматом легко работать из PHP.

Все строки начинающиеся на точку с запятой ";" - комментарии и не учитываются скриптом.

Все поля указанные в ad.txt -- обязательны к заполнению.Полностью рабочий пример заполнения ad.txt можно посмотреть в "data/ads/[draft] New ad/".

Определившись с функционалом можно приступить к составлению алгоритма работы скрипта.

1) Т.к. скрипт должен работать постоянно и по мере появления новых объявлений публиковать их, то скрипт будет работать в бесконечном цикле.

2) Чтобы избежать утечек RAM и зависания HumanEmulator реализуем рестарт скрипта каждые N итераций.

3) Если есть объявления для публикации, то выбираем первое попавшееся, если нет, то ждём N мин. и проверяем еще раз.

4) Т.к. после анонимной подачи объявления localmart.ru автоматически авторизует пользователя, то перед каждым заходом на сайт будем производить очистку браузера.

5) Заходим на страницу подачи объявления.

6) Заполняем необходимые поля.

7) Загружаем фото.

8) Публикуем объявление.

9) Получаем ссылку на опубликованное объявление и сохраняем её в файл url.txt

10) Переименовываем дирректорию с объявлением - добавляем в начало "[published]".

11) Чтобы слишком не флудить на доске - после публикации объявления должна выдерживаться пауза перед публикацией следующего объявления.

Теперь можно приступить к реализации публикатора.

Создадим главный файл скрипта "add_to_localmart.php" с базовым содержимым:

  // coding: windows-1251
  
    // Настройка HumanEmulator
  // -----------------------------------------------
  
  // Где запущен XHE
  $xhe_host = "127.0.0.1:7010";
  
  // HumanEmulator lib
  require "../../Templates/xweb_human_emulator.php";
  
  require "tools/functions.php";
  
    // Настройки скрипта
  // -----------------------------------------------
    
  // Скрипт
  // -----------------------------------------------

Чтобы скрипт публиковал объявления по мере их появления сделаем бесконечный цикл.

while(true)
  {
      //
  } // end while true

Для избегания утечек RAM и зависания HumaEmulator добавим в скрипт возможность рестарта каждые N итераций.

В настройках скрипта укажем через сколько итераций рестартовать скрипт:

$restart = 10;

Добавим в скрипт счётчик итераций (перед началом while):

$iter_count = 1;
  
  while(true)
  {
      //
  }

Теперь можно добавить реализацию рестарта (в самом начале while):

while(true)
  {
    if($iter_count >= $restart)
    {
      $app->restart($debug->get_cur_script_path(), "", $app->get_port());
    }
  }

Далее приступим к реализации получения объявления для публикации.

Храниться объявления будут в дирректории "data/ads". Получается примерно такая структура:


- data/

- ads/ : список объявлений

- "Готовое к публикации объявление (название не важно)/"

- img/ : фото для объявления (названия фото м.б. любыми)

- ad.txt : содержимое объявления

- "[draft] Черновик объявления (публиковаться не будет)/"

- "[published] Опубликованное объявление/"

- img/ : фото для опубликованного объявления

- ad.txt : содержимое опубликованного объявления

- url.txt : ссылка на опубликованное объявление

Для этого добавим в настройки дирректорию, где будут храниться объявления и время паузы, если объявлений нет:

  // Где хранятся объявления
  $ads_dir = "data/ads";
 
  // Время ожидания (мин.)
  $wtm = 10;

В реализации получения объявления для публикации необходимо учесть, что объявлений может не быть, и что объявления не смогли получить:

  // Получаем объявление для публикации
    $ad = get_ad($ads_dir);
    
    if($ad === false)
    {   // Что-то пошло не так
        $app->quit();
    }
    elseif(!$ad)
    {   // Нет объявлений для публикации
        echo "Ждём {$wtm} мин." . PHP_EOL;
        
        $iter_count++;
        
        sleep(mins2secs($wtm));
        
        continue;
    }
    
    echo "Публикуемое объявление: '{$ad['title']}'" . PHP_EOL;

Реализация функции get_ad() довольно проста:

* Выбираем одно объявление (из готовых к публикации)

* Проверяем существует ли файл ad.txt

* Считываем и парсим его с пом. встроенной PHP-функцией "parse_ini_file"

* Если есть фото, то сохраняем полные пути к ним.

Перед тем как зайти на сайт необходимо почистить браузер (куки и т.п.),чтобы сбросилась старая авторизация.

  // Чистим и настраиваем браузер
    $browser->close_all_tabs();
    $browser->navigate("about:blank");
    $browser->clear_address_bar_history();
    $browser->clear_cache();
    $browser->clear_history();
    $browser->clear_cookies("", true, true);
    $browser->recreate();
    $app->clear();
    
    if(!$browser->is_enable_java_script()) $browser->enable_java_script(true, false);

Сейчас можно открыть страницу подачи объявления.

$browser->navigate("http://localmart.ru/add");

Приступаем к заполнению полей формы публикации объявления:

fill_fields($ad);

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

  // Заголовок
    $input->set_focus_by_attribute("name", "Ad[title]");
    $input->set_value_by_attribute("name", "Ad[title]", True, $ad["title"]);
    sleep(1);
    
  // Рубрика: недвижимость
    $anchor->click_by_inner_text("Выбрать", true);
    sleep(1);
    $input->click_by_number_by_form_name(1, "item-add-form");
    $input->set_value_by_number_by_form_name(1, "недвижимость", "item-add-form");
    sleep(1);
    $anchor->click_by_inner_text("Недвижимость");
    sleep(1);

Паузы расставляем, чтобы успевал отрабатывать javascript.
Т.к., при публикации объявления localmart.ru автоматически создаёт уч. запись для указанного email, то нормальный адрес будем указывать в описании,
а в спец. поле будем генерировать фейковый email.

Для этого воспользуемся встроенной возможность HumanEmulator по генерации имени и фамилии:

$submitter->generate_random_name(),
$submitter->generate_random_second_name()

Также можно рандомизировать домен фейкового email - составим простой список доменов для фейковой почты и при генерации будем выбирать случайный домен.

$hosts = ["mail.ru", "rambler.ru", "gmail.com", "hotmail.com", "yandex.ru", "ya.ru", "yandex.com"];
    $email = $submitter->generate_random_name()
        . $submitter->generate_random_second_name()
        . "@"
        . $hosts[rand(0, count($hosts)-1)];
    $input->set_focus_by_attribute("id", "Ad_email");
    $input->set_value_by_attribute("id", "Ad_email", True, $email);

Следующий этап - загрузка фото, если есть.

if($ad["img"])
    {
        // ...
    }

Если есть фото, то $ad["img"] будет содержать список строк с полными путями до всех фото к объявлению, если фото нет, то будет просто пустой массив.

Сама загрузка фото происходит в 5 этапов:

* Копируем фото во временную дирректорию. Т.к. Internet Explorer лочит дирректорию из которой загружает файлы, это не даст нам возможности переименовать дирректорию с объявлением.

date_default_timezone_set("Europe/Moscow"); // Необходимо для генерации $p2
    $img = [];
    foreach($ad["img"] as $p)
    {
        // Получаем расширение файла ".jpg", ".png"
        $p_ext = explode(".", basename($p));
        $p_ext = $p_ext[count($p_ext)-1];
        // Генерируем новый путь к временному файлу
        $p2 = "res/tmp/" . (date_timestamp_get(date_create()) + rand(99, 9999)) . ".{$p_ext}";
        
        copy($p, $p2);
        
        $img[] = realpath($p2);
    }

* Генерируем строку с полными путями к фото:

  // Генерируем список фото для загрузки
    $files = "";
    foreach($img as $p)
    {
        if(!file_exists($p)) continue;
        
        $files .= "\"{$p}\" ";
    }

* Вызываем метод $window->execute_open_file для того, чтобы HumanEmulator ожидал диалогового окна для загрузки файлов.

$window->execute_open_file("Выбор выкладываемого файла",$files,"&Открыть", true, true);

* Кликаем на кнопку, которая открывает диалоговое окно.

* Удаляем временные файлы. Временные файлы лучше удалять после рестарта HumanEmulator. Например, добавим этот код перед циклом while().

// Удаляем временные файлы
if(!file_exists($tmp_path)) mkdir($tmp_path, 0777, true);
$tmp_path_list = scandir($tmp_path);
foreach($tmp_path_list as $p)
{
    if($p === "." or $p === "..") continue;
    
    unlink($p);
}

Добавим настройку:

// Временные файлы
$tmp_path = "res/tmp";

После загрузки фото можно кликнуть по кнопке для публикации объявления на сайте:

$mouse->send_click($anchor->get_x_by_inner_text("Разместить объявление") + 10,
$anchor->get_y_by_inner_text("Разместить объявление") + 10);

Проверим - опубликовалось ли объявление?

$url2 = $webpage->get_location_url();
    if($url2 !== "http://localmart.ru/features")
    {
        echo "[ERROR] Ошибка публикации объявления." . PHP_EOL;
        
        $app->quit();
    }

Иногда объявления перед публикацией могут ожидать проверки,проверим - активно ли наше объявление?

Для этого пройдём на страницу с активными объявлениями и поищем его:

$browser->navigate("http://localmart.ru/cabinet/items?view=active");
    
    $ad_link = $anchor->get_attribute_by_inner_text($ad["title"], true, "href");
    
    if(!$ad_link)
    {
        // объявление не активно
    }
    else
    {
        // объявление активно
    }

Если всё ок, то сохраняем ссылку на объявление в файл url.txt

file_put_contents("{$ad['_base_path']}\\url.txt", $ad_link);

И переименовываем дирректорию в "[published] Ad name".

$new_path = str_replace($ad["_dir_name"], "[published] {$ad['_dir_name']}", $ad["_base_path"]);
rename($ad["_base_path"], $new_path);

Перед переходом на след. итерацию необходимо увеличить счётчик итераций "$iter_count"

$iter_count++;

Не забывайте при создании нового объявления к имени дирректории добавлять "[draft]", чтобы скрипт пропускал черновики объявлений.

Так же учтите, что если объявление готово к публикации, то вам необходимо перед публикацией:

* Закрыть текстовый редактор с файлом ad.txt

* Закрыть просмоторщики/редакторы фото с фотографиями для объявления.

* Файловый менеджер (проводник, компьютер): выйти из дирректории с объявлением.

Это необходимо для того, чтобы скрипт мог переименовывать дирректорию с объявлением.

* Убрать из названия дирректории "[draft]".

А это для того, чтобы скрипт увидел, что объявление можно публиковать.


Скрипт написан 24.04.2015 в Human Emulator 4.9.18 Advanced.

скачать скрипт

<< Другие скрипты