Помимо регистрации и сабмита данных на различные ресурсы может встать задача по сбору каких либо данных в сети.
Предположим нам нужно собрать, обработать и сохранить данные по торгам на RTS бирже. Перейдём на сайт биржи,
где предоставляется необходимая нам информация http://www.rts.ru/ru/spot/.
Перед нами таблицы с индексами, объёмами торгов и акциями. Напишем скрипт, который будет собирать и хранить данные по индексам.
Как всегда создадим новый скрипт используя Ctrl+N и заменим http://www.google.com на http://www.rts.ru/ru/spot/.
Запустим скрипт на выполнение и перейдём на нужную нам страницу. Создадим папку RTS в папке My Scripts и, используя команду Save as…,
сохраним наш скрипт под именем rts_ru.php в только что созданную нами папку.
Примечание: При переименовании файла нужно обращать внимание на строку require(«../../Templates/xweb_human_emulator.php»);.
Это строка путь к шаблону php с объектами XHE. Если этот путь будет неправильным, скрипт работать не будет.
В папке My Scripts у скриптов эта строка задаётся как require(«../Templates/xweb_human_emulator.php»);,
так как файл xweb_human_emulator.php лежит на одну папку выше в папке Templates. Из-за того что мы создали папку
RTS и поместили туда скрипт получается что файл шаблон лежит на две папки выше. Для того что бы наш скрипт
видел этот файл мы должны добавить ../ в путь к шаблону. Если вам тяжело работать с относительным путём к
файлу шаблона вы всегда можете использовать абсолютный путь,
который будет выглядеть например как require(«C:\XWeb\Human Emulator\Templates\xweb_human_emulator.php»);.
При первом же рассмотрении сайта через Дерево Элементов или через Инспектор Элементов мы видим огромное количество таблиц на сайте. Для того что бы определить какая именно таблица нам нужна напишем простенький скрипт, который будет получать первый ряд у всех таблиц на странице и записывать его в файл:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$xhe_host ="127.0.0.1:7010"; // The following code is required to properly run XWeb Human Emulator require("../../Templates/xweb_human_emulator.php"); // navigate to google $browser->navigate("http://www.rts.ru/ru/spot/"); // wait on browser $browser->wait_for(); //получить количество таблиц на странице echo $cnt = $table->get_count(); // пройдёмся по всем таблицам for($ii=0;$ii<$cnt;$ii++) { // получим первый ряд $ii-той таблицы $str = $ii." таблица ряд 0\n\n\n"; $str = $str.$table->get_row_by_number($ii,0,true)."\n\n\n"; // запишем результат в файл $textfile->add_string_to_file("tables.txt",$str,0) ; } // Quit $app->quit(); |
Просматривая файл с результатами находим следующие строки:
24 таблица ряд 0
B>Индексы/B>
Теперь мы знаем номер нужной нам таблицы с данными. Опять, используя команду Save As…, сохраним наш текущий скрипт как get_tables.php. Пригодится. Затем закроем его и откроем скрипт rts_ru.php. Удалим из него лишнее, оставив только навигацию на нужную нам страницу.
Итак, у нас есть номера нужных таблиц. Можно найти эту таблицу через Дерево Элементов и через Элемент Инспектор посмотреть какие атрибуты у неё есть. К сожалению, кроме номера и размера с координатами ничего нет, поэтому будем работать с ними через их номера.
Примечание: Описание всех объектов и их функций можно найти на сайте humanemulator.net. Документация по объекту table находится по адресу http://humanemulator.net/objects/DOM/table.php.
При дальнейшем рассмотрении таблицы обнаружилось, что в неё вложены другие таблицы. Это затрудняет работу с ними через объект table и его функции получения рядов и колонок, поэтому будем работать через разбор полученных исходников таблиц. Для этого используем функцию get_inner_html.
Сделаем вызов этой функции для 24 таблицы и сохраним исходники в файл для дальнейшего изучения. Для этого добавим код:
1 2 3 4 5 |
// получить исходники таблицы $tb1=$table->get_inner_html(24); // запишем результат в файл $textfile->write_file("table.txt",$tb1,0) ; |
Просмотрим созданный файл и выберем префиксы для разбора. Первое что нас интересует это название индекса. Он заключён в следующем коде: A class=Thurl href=»/ru/index/rtsi/»>RTSI/A> Первый префикс будет A class=Thurl href=», с помощью него мы будем находить эту строку и уже из неё вырезать название индекса. Для этого добавим следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// перфикс для нахождения строки с названием идекса $pref = "A class=Thurl href=\""; // префикс перед названием индекса $pref1 = "\">"; // префикс после названия индекса $pref2 = "/A>"; // номер в строке первого префикса $ind1= strpos($tb1,$pref); // номер в строке второго префикса относительно первого $ind2= strpos($tb1,$pref1,$ind1); // номер в строке третьего префикса относительно второго $ind3= strpos($tb1,$pref2,$ind2); // название индекса заключено между номером второго префикса + длина самого префикса // и номером третьего префикса echo $ind_name = substr($tb1,$ind2+strlen($pref1),$ind3-$ind2-strlen($pref1)); |
Запустим скрипт на выполнение и получим в окне отладки название первого индекса. Так как этот код нам придётся вызывать несколько раз оформим его в функцию, в которую будем передавать строку и номер символа, с которого надо будет выполнять поиск и разбор. Этот номер символа будем изменять на последний найденный нами. Для этого перед названием передаваемого в функцию параметра ставится символ &. Функция будет выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// получить название индекса function get_index_name($tb1,&$ind_st) // & { // перфикс для нахождения строки с названием идекса $pref = "A class=Thurl href=\""; // префикс перед названием индекса $pref1 = "\">"; // префикс после названия индекса $pref2 = "/A>"; // номер в строке первого префикса $ind1= strpos($tb1,$pref,$ind_st); // номер в строке второго префикса относительно первого $ind2= strpos($tb1,$pref1,$ind1); // номер в строке третьего префикса относительно второго $ind3= strpos($tb1,$pref2,$ind2); // изменим стартовый индекс $ind_st=$ind3; // название индекса заключено между номером второго префикса + длина самого префикса // и номером третьего префикса return substr($tb1,$ind2+strlen($pref1),$ind3-$ind2-strlen($pref1)); } |
Вызов функции и проверка изменения стартового номера символа в строке:
1 2 3 4 5 6 |
// стартовый номер символа для поиска префиксов $ind_st=0; // получить название индекса echo $ind_name = get_index_name($tb1,$ind_st); // покажем изменение индекса echo $ind_st; |
Весь скрипт будет выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
$xhe_host ="127.0.0.1:7010"; // The following code is required to properly run XWeb Human Emulator require("../../Templates/xweb_human_emulator.php"); // navigate to google $browser->navigate("http://www.rts.ru/ru/spot/"); // wait on browser $browser->wait_for(); // получить исходники таблицы $tb1=$table->get_inner_html(24); // стартовый индекс для поиска префиксов $ind_st=0; // получить название индекса echo $ind_name = get_index_name($tb1,$ind_st); // покажем изменение индекса echo $ind_st; // получить название индекса function get_index_name($tb1,&$ind_st) { // перфикс для нахождения строки с названием идекса $pref = "A class=Thurl href=\""; // префикс перед названием индекса $pref1 = "\">"; // префикс после названия индекса $pref2 = "/A>"; // номер в строке первого префикса $ind1= strpos($tb1,$pref,$ind_st); // номер в строке второго префикса относительно первого $ind2= strpos($tb1,$pref1,$ind1); // номер в строке третьего префикса относительно второго $ind3= strpos($tb1,$pref2,$ind2); // изменим стартовый индекс $ind_st=$ind3; // название индекса заключено между номером второго префикса + длина самого префикса // и номером третьего префикса return substr($tb1,$ind2+strlen($pref1),$ind3-$ind2-strlen($pref1)); } // Quit $app->quit(); |
При запуске этого скрипта он выдаст название первого индекса и изменённый стартовый номер символа для поиска и разбора.
Для удобочитаемости скриптов функции лучше сносить в отдельные файлы и их уже подключать в скрипт. Для этого через Save As сохраним текущий скрипт как functions.php в эту же папку. Теперь удалим из него всё лишнее. Файл functions.php будет выглядеть следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// получить название индекса function get_index_name($tb1,&$ind_st) { // перфикс для нахождения строки с названием идекса $pref = "A class=Thurl href=\""; // префикс перед названием индекса $pref1 = "\">"; // префикс после названия индекса $pref2 = "/A>"; // номер в строке первого префикса $ind1= strpos($tb1,$pref,$ind_st); // номер в строке второго префикса относительно первого $ind2= strpos($tb1,$pref1,$ind1); // номер в строке третьего префикса относительно второго $ind3= strpos($tb1,$pref2,$ind2); // изменим стартовый индекс $ind_st=$ind3; // название индекса заключено между номером второго префикса + длина самого префикса // и номером третьего префикса return substr($tb1,$ind2+strlen($pref1),$ind3-$ind2-strlen($pref1)); } |
Теперь закроем его и откроем опять файл rts_ru.php, в котором находится наш скрипт. Удалим оттуда всё лишнее и подключим файл function.php к нему. После всех проделанных операций наш скрипт будет выглядеть:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
$xhe_host ="127.0.0.1:7010"; // The following code is required to properly run XWeb Human Emulator require("../../Templates/xweb_human_emulator.php"); // подключить файл с функциями include("functions.php"); // navigate to google $browser->navigate("http://www.rts.ru/ru/spot/"); // wait on browser $browser->wait_for(); // получить исходники таблицы $tb1=$table->get_inner_html(24); // стартовый индекс для поиска префиксов $ind_st=0; // получить название индекса echo $ind_name = get_index_name($tb1,$ind_st); // покажем изменение индекса echo $ind_st; // Quit $app->quit(); |
При запуске этого скрипта получим тот же результат что и до переноса функции в отдельный файл.
Теперь продолжим изучение исходников таблицы в файле table.txt для дальнейшего разбора данных.
Нужные нам данные помещены в следующие тэги:
1 |
<TD align=right><B>1516.20</B></TD>; |
По аналогии с написанным выше добавим функцию разбора для этой части исходного кода таблицы. В данном случае обойдёмся без предварительного префикса нахождения нужной нам строки. В итоге код функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// получить данные для индекса function get_data($tb1,&$ind_st) { // первый префикс $pref1 = "<TD align=right>"; // второй префикс $pref2 = "</TD>"; // номер в строке первого префикса $ind1= strpos($tb1,$pref1,$ind_st); // номер в строке второго префикса $ind2= strpos($tb1,$pref2,$ind1); // нужные нам данные $data = substr($tb1,$ind1+strlen($pref1), $ind2- $ind1-strlen($pref1)); // запомним последний найденый номер префикса $ind_st = $ind2; // уберём лишнее из полученных данных $data= str_replace("<B>","",$data); $data= str_replace("</B>","",$data); $data= str_replace("font color=red>","",$data); $data= str_replace("/font>","",$data); $data= str_replace("font color=green>","",$data); return $data; } |
Добавим её в файл functions.php. И сделаем вызов в нашем скрипте таким кодом:
1 2 |
// покажем полученные данные echo get_data($tb1,$ind_st); |
После запуска этого кода в окне отладки будет отображать содержимое первой колонки первого ряда таблицы.
Теперь нам надо добавить цикл, что бы получать данные для каждого индекса и формировать из них строку для записи в файл. После детального изучения исходного кода таблицы выяснилось, что она состоит из 8 колонок. В первой колонке, сразу за названием индекса, либо график либо ничего нет, поэтому эта колонка нам не интересна и мы её будем пропускать. Цикл организуем через оператор while следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
// результирующая строка $str_res=""; // цикл для разбора всех данных таблицы while($ind_st!==false) { // укажем что используем глобальную переменную global $str_res; // получить название индекса $str_res = $str_res.get_index_name($tb1,$ind_st); // остановить как только не сможем найти нужный префикс if(!$ind_st) break; // цикл для разбора данных текущего индекса for ($ii=0;$ii<8;$ii++) { // покажем полученные данные $dts = get_data($tb1,$ind_st); // добавим все кроме первого значения с графиком if($ii!=0) { // укажем что используем глобальную переменную global $str_res; // добавим данные в строку $str_res =$str_res.";".$dts; } } // прибавим перенос строки $str_res =$str_res."\n"; } |
Для того что бы этот цикл останавливался надо добавить проверку в функцию получения названия индекса get_index_name, которая определена в файле functions.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// получить название индекса function get_index_name($tb1,&$ind_st) { // перфикс для нахождения строки с названием идекса $pref = "A class=Thurl href=\""; // префикс перед названием индекса $pref1 = "\">"; // префикс после названия индекса $pref2 = "/A>"; // номер в строке первого префикса $ind1= strpos($tb1,$pref,$ind_st); // проверка если не нашли то выходим if($ind1===false) { $ind_st = false; return ""; } // номер в строке второго префикса относительно первого $ind2= strpos($tb1,$pref1,$ind1); // номер в строке третьего префикса относительно второго $ind3= strpos($tb1,$pref2,$ind2); // изменим стартовый индекс $ind_st=$ind3; // название индекса заключено между номером второго префикса + длина самого префикса // и номером третьего префикса return substr($tb1,$ind2+strlen($pref1),$ind3-$ind2-strlen($pref1)); } |
Добавим запись в файл. Наш скрипт теперь будет выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
$xhe_host ="127.0.0.1:7010"; // The following code is required to properly run XWeb Human Emulator require("../../Templates/xweb_human_emulator.php"); // подключить файл с функциями include("functions.php"); // navigate to google $browser->navigate("http://www.rts.ru/ru/spot/"); // wait on browser $browser->wait_for(); // получить исходники таблицы $tb1=$table->get_inner_html(24); // стартовый индекс для поиска префиксов $ind_st=0; // результирующая строка $str_res=""; // цикл для разбора всех данных таблицы while($ind_st!==false) { // укажем что используем глобальную переменную global $str_res; // получить название индекса $str_res = $str_res.get_index_name($tb1,$ind_st); // остановить как только не сможем найти нужный префикс if(!$ind_st) break; // цикл для разбора данных текущего индекса for ($ii=0;$ii<8;$ii++) { // покажем полученные данные $dts = get_data($tb1,$ind_st); // добавим все кроме первого значения с графиком if($ii!=0) { // укажем что используем глобальную переменную global $str_res; // добавим данные в строку $str_res =$str_res.";".$dts; } } // прибавим перенос строки $str_res =$str_res."\n"; } // запишем данные $textfile->write_file("res.csv",$str_res,0) ; // Quit $app->quit(); |
Можем немного усовершенствовать запись в файл. Так как в одном из столбцов содержится время, будем получать его и создавать файл по этому времени. И так же будем добавлять данные в общий результирующий файл res.csv. Перед этим создадим папку с именем res, куда будем писать все файлы с результатами, что бы не захламлять папку где лежит сам скрипт. После всех проделанных операций имеем:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
$xhe_host ="127.0.0.1:7010"; // The following code is required to properly run XWeb Human Emulator require("../../Templates/xweb_human_emulator.php"); // подключить файл с функциями include("functions.php"); // navigate to google $browser->navigate("http://www.rts.ru/ru/spot/"); // wait on browser $browser->wait_for(); // получить исходники таблицы $tb1=$table->get_inner_html(24); // стартовый индекс для поиска префиксов $ind_st=0; // результирующая строка $str_res=""; // время индекса $i_time = ""; // цикл для разбора всех данных таблицы while($ind_st!==false) { // укажем что используем глобальную переменную global $str_res; // получить название индекса $str_res = $str_res.get_index_name($tb1,$ind_st); // остановить как только не сможем найти нужный префикс if(!$ind_st) break; // цикл для разбора данных текущего индекса for ($ii=0;$ii<8;$ii++) { // покажем полученные данные $dts = get_data($tb1,$ind_st); // добавим все кроме первого значения с графиком if($ii!=0) { // укажем что используем глобальную переменную global $str_res; // добавим данные в строку $str_res =$str_res.";".$dts; } // получение времени индекса if($ii==1) { global $i_time; // заменим : на - чтобы можно было создавать файл $i_time=str_replace(":","-",$dts); } } // прибавим перенос строки $str_res =$str_res."\n"; } // запишем данные в файл с указанием времени $textfile->write_file("/res/res".$i_time.".csv",$str_res,0) ; // запишем данные в общий файл $textfile->add_string_to_file("/res/res.csv",$str_res,0) ; // Quit $app->quit(); |
После запуска этого скрипта в созданной вами папке res появится два файла один res.csv, второй типа res14-27.csv. При повторном запуске добавиться ещё один файл типа res14-29.csv и т.д. Так как данные на сайте для индексов обновляются практически каждую минуту, то можно в расписании запуска скриптов добавить запуск этого скрипта скажем каждые две минуты.
Скрипт написан 25.01.2012 в Human Emulator 4.2 Advanced.
На момент публикации статьи 25.01.2012 скрипт был рабочий.