Бесплатный парсер контента сайтов — Top Analyzer

.

Блог веб-разработчика / Статьи / php

cURL для начинающих. Пишем парсер

cURL для начинающих. Пишем простой парсер сайтов

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

Итак, что же такое cURL? Вообще, cURL — это консольная программа, которая предназначена для передачи файлов по различным протоколам. Само название cURL — это сокращение от «client urls». В PHP же cURL — это подключаемый модуль. Раскомментируйте строчу extension=php_curl.dll в файле php.ini, перезагрузите сервер и модуль подключен! (Имеется ввиду локальный сервер под Виндовс, типа денвера, а на большинстве хостингов этот модуль установлен и включён)

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

//Инициализация cURL и задание адреса $ch = curl_init(‘http://example.com/page2’); //Установка опций curl_setopt($ch, CURLOPT_USERAGENT, ‘KOZ1024 Site Parser’); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_REFERER, ‘http://example.com’); //выполнение (результат отобразится на экран) curl_exec($ch); //Закрытие соединения curl_close($ch);

Просто? Ещё бы… А сейчас с помощью курла мы сейчас напишем небольшой парсер сайтов. Этот парсер сможет зайти на любой сайт по протоколу http, найти все ссылки на определённый тип документов и скачать эти документы к себе. Итак, приступим. В этой задаче, так же будем использовать такую технологию, как аякс (это только для красоты)

<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Transitional//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd»> <html> <head> <meta http-equiv=»Content-type» content=»text/html; charset=utf-8″ /> <title>KOZ1024 Site Parser</title> <script> var xmlHttp = false; function start(){ //»включаем» картинку загрузки document.getElementById(‘progressbar’).innerHTML = ‘<img src=»https://rpilot62.ru/wp-content/uploads/2018/06/54242.gif» border=»0″ alt=»Loading, please wait…» />’; //инициализация ajax<!— Кстати, форму можно не делать, т.к. при отправке мы обращаемся к инпутам с помощью getElementById и отправляем с помощью аякс —> <table> <tr> <td>Адрес начальной страницы:</td> <td><input type=»text» size=»40″ id=»url» value=»http://» /></td> </tr> <tr> <td>Типы файлов:</td> <td><input type=»text» size=»10″ id=»types» value=»doc» /></td> </tr> <tr> <td>Максимальное количество файлов</td> <td><input type=»text» size=»5″ id=»max» value=»0″ /></td> </tr> <tr> <td colspan=»2″><input type=»button» value=»Начать» onclick=»start()» /></td> </tr> </table> </center> </body> </html>

И обработчик (файл parser.php):

//Ставим время выполнения 10 минут ini_set(‘max_execution_time’, 600); //замеряем время начала работы скрипта $st_time = microtime(true); //устанавливаем переменные… $url = $_POST[‘url’]; $types = $_POST[‘types’]; $maxPages = (int)$_POST[‘max’]; $host = explode(‘/’, substr($url, 7)); $host = substr($url, 0, 7).$host[0].’/’; //про последние 2 строчки подробней: таким вот образом получаем Адрес сайта (на случай, если ввели //адрес странички сайта) — разбиваем на массив по слешу и берём первую часть…//для удобства работы с КУРЛом, напишем простенькую функцию //параметры: $host — адрес, $referer — откуда пришли (можно подделать, в статистике парсимого сайта будет отображаться, что мы пришли, например, с Яндекса :)) //$file — идентификатор файла (если мы хотим скачать файл, то передаём его идентификатор) function curl_get($host, $referer = null, $file = null){ //инициализация curl и задание основных параметров $ch = curl_init($host); curl_setopt($ch, CURLOPT_USERAGENT, ‘KOZ1024 Site Parser’); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_REFERER, $referer); //если дали ссылку на файл if (!is_null($file)){ //то устанавливаем опцию записи в файл, curl_setopt($ch, CURLOPT_FILE, $file); //и выполняем curl_exec($ch); //не забываем закрыть соединение curl_close($ch); }else{ //если же ссылку на файл не дали, то возвращаем страничку ob_start(); curl_exec($ch); print(curl_error($ch)); curl_close($ch); return ob_get_clean(); } } //получаем html-код исходной страницы $page = curl_get($url); //регулярным выражением ищем вхождение ссылок preg_match_all(‘#href=»([A-z0-9.-]+)»#’, $page, $matches); //получаем массив всех-всех ссылок с этой старницы $links = $matches[1]; $cnt = 0; //цикл: пока не прошли весь массив ссылок, либо пока не скачали макс. количество файлов (не действет в случае 0) for($i=0; ($i<sizeof($links)&&($cnt<$maxPages||$maxPages==0)); $i++){ //если в ссылке есть нужное нам расширение if (strpos($links[$i], $types)!==false){ //то открываем файл, «курлим» в него содержимое файла на сервере, закрываем, увеличиваем счётчик $fp = fopen($links[$i], ‘w’); curl_get($host.$links[$i], $url, $fp); fclose($fp); $cnt++; }else{ //иначе это ещё одна ссылка, перейдём по ней, найдём все ссылки и занесём их в массив $page = curl_get($links[$i], $url); preg_match_all(‘#href=»([A-z0-9.-]+)»#’, $page, $matches); $links = array_merge($links, $matches[1]); } } //замеряем время окончания работы и выводим… $en_time = microtime(true); print ‘Скачано файлов: ‘.$cnt.'<br />Время выполнения: ‘.($en_time-$st_time);

Также, приведу некоторые параметры — опции курла. Применяются они, как вы могли увидеть выше, таким образом: curl_setopt(идентификатор, опция, параметр);

Опция Описание Пример
CURLOPT_UPLOAD Указываем, что мы хотим выгрузить файл на сервер. Поставтье в ненулевое значение //указываем дескриптор открытого на чтение файла, которого собираемся передать curl_setopt($ch, CURLOPT_INFILE, $fp); //указываем размер отправляемого файла curl_setopt($ch, CURLOPT_INFILESIZE, $filesize); //указываем, что файл передается методом PUT curl_setopt($ch, CURLOPT_PUT, true); //указываем, что будет производиться закачка на удаленный сервер curl_setopt($ch, CURLOPT_UPLOAD, true);
CURLOPT_INFILE Указываем дескриптор выгружаемого файла
CURLOPT_INFILESIZE Указываем размер выгружаемого файла
CURLOPT_PUT Указываем, что будем передавать методом put.

Поставьте в ненулевое значение

CURLOPT_POST Указываем, что хотим отправить POST-запрос. Обычно, для стандартной формы укажите application/x-www-form-urlencoded curl_setopt($ch, CURLOPT_POST, ‘application/x-www-form-urlencoded’);
curl_setopt($ch, CURLOPT_POSTFIELDS, ‘search=text&param1=value2’);
CURLOPT_POSTFIELDS Указываем строку, содержащую данные для передачи через POST
CURLOPT_TIMEOUT Указываем время (в секундах), по проишествии которого соединение будет оборвано
CURLOPT_RESUME_FROM Указываем смещение в байтах, с которого нужно начинать приём файла
CURLOPT_URL Указываем URL старницы (если не сделали это в функции curl_init();) $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ‘http://example.com’);
CURLOPT_REFERER Указываем заголовок referer (откуда перешли) curl_setopt($ch, CURLOPT_REFERER, ‘http://google.com’);
CURLOPT_USERAGENT Указываем заголовок UserAgent (пользовательский браузер, грубо говоря) curl_setopt($ch, CURLOPT_USERAGENT, ‘Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.17) Gecko/2009122116 Firefox/3.0.17’)
CURLOPT_COOKIE Указываем заголовок COOKIE
CURLOPT_PROXY Указываем прокси для соединения с Интернетом (если Вы используете Интернет через прокси) curl_setopt($ch, CURLOPT_PROXY, ‘username:password@192.168.0.3:3128’)

Это далеко не все опции курла, только небольшая, но наиболее востребованная их часть. Более полный список ищите в мануалах…

Примечание. Будьте внимательы! На шаред-хостинге Вам, вероятно, откажут в выполении скрипта более 30 секунд, а если ваш скрипт повесит весь сервер, то Вас могут отключить! Прочтите правила

Заключение. Вот мы и написали небольшой, но тем не менее работющий парсер сайтов. По-хорошему, его можно неплохо оптимизировать, сделать более универсальным, да чего там — можно применить к нему ООП. Но цель данной статьи была — объяснить работу cURLа на примере. Надеюсь, я этой цели достиг… Удачи в освоении!

Следующая статья: PHP sendmail: отправка почты с вложениями посредством PHP

Вы нашли то, что искали? Да  Нет

Вам понравилась статья? Да  Нет

Как написать простой скрипт парсер на Human Emulator

Предположим у нас стоит задача собрать контактные данные организаций с какого то сайта. Для примера возьмём сайт «Желтые страницы Рунета» http://www.yellowpagesrussia.ru. Нам нужно собрать данные организаций из раздела «Морской транспорт – организации» http://www.yellowpagesrussia.ru/190/154/.

Для начала работы нам понадобится стандартная заготовка скрипта. Её можно создать по нажатию в меню Файл->Новый->Скрипт или по нажатию «горячих» клавиш «Ctrl+N». После чего создать папку в папке My Scripts с именем нашего будущего скрипта в нашем случае yellowpages и переместить наш скрипт в эту папку через меню «Файл->Сохранить как» yellowpages.php.

Далее мы вставляем шапку с настройками:

$xhe_host =»127.0.0.1:7010″; // The following code is required to properly run XWeb Human Emulator require(«../../Templates/xweb_human_emulator.php»); // //////////////////////// настройки скрипта ///////////////////////// // файл с результатами $str_res=»res/result.txt»; // скрипт работает в режиме отладки $dbg = true; // сайт $site = «http://www.yellowpagesrussia.ru/190/154/»; // ожидание $wt = 5; $wt_long = 10; // текущая страница $crnt_page = 1; // количество страниц $cnt_pages = -1; // //////////////////////// дополнительные модули /////////////// // функции require_once(«tools/functions.php»); // /////////////////////// скрипт ///////////////////////////////////////////

Примечание: Файл functions.php можно взять из любого скрипта, который вы можете скачать у нас на сайте. Его нужно поместить в папку tools, которую создать в папке со скриптом.

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

$browser->navigate($site);

Далее нам нужно через правую панель «Дерево элементов» найти общий id контекста кликаем по данным правой кнопкой и выбираем «посмотреть в дереве элементов» находим наиболее подходящий элемент, подглядывая в «инспектор», чтобы внутренний текст (или html код) содержал максимум нужной нам информации! Найдя нужным идентификатор, с помощью функции Human Emulator выпарсиваем все данные со страницы в нашем случае это id = content для объекта $div пишем в скрипте(либо правой кнопкой мыши вызываем контекстное меню и кликаем на нужный нам контент и выбираем нужный пункт):

$content = $div->get_all_inner_texts_by_attribute(«id»,»content»);

после выполнения этого шага хуманом мы получаем массив с данными, которые сохраним с помощью функции добавления строки в файл:

$textfile->add_string_to_file($str_res,$content.»\r\n»);

данные будут добавлены в указанный текстовый файл. Тело скрипта теперь выглядит следующим образом:

// /////////////////////// скрипт /////////////////////////////////////////// // переходим на сайт $browser->navigate(«$site»); sleep($wt); // получаем нужные данные со страницы $content = $div->get_all_inner_texts_by_attribute(«id»,»content»); sleep($wt); // записываем в файл $textfile->add_string_to_file($str_res,$content); sleep($wt);

Далее проверяем результат…и видим, что записались лишние данные! используем для решения этой проблемы заранее написанную нами функцию get_string().

Исходники её лежат в файле «tools/functions.php».

// получение строки по префиксам function get_string($str1, $pr1, $pr2, &$ind_st = 0) { //echo $str1.»
«; $ind1 = strpos($str1, $pr1, $ind_st); // echo «index 1 «.$ind1.»
«; if($ind1 === false) return «»; $ind2 = strpos($str1, $pr2, $ind1+ strlen($pr1)); //echo «index 2 «.$ind2.»
«; if ($ind2 === false) return «»; // запомним стартовый индекс $ind_st = $ind2 + 1; // $sres = substr($str1, $ind1 + strlen($pr1), $ind2 — $ind1-strlen($pr1)); return trim($sres); }

C помощью этой функции выкусываем нужные данные:

$text = get_string($content[0],»Морской транспорт – организации»,»Страницы»); затем записываем полученные данные в файл $textfile->add_string_to_file($str_res,$text);

В итоге у нас должен получится следующий скрипт:

// переходим на сайт $browser->navigate(«$site»); //sleep($wt); // получаем нужные данные со страницы $content = $div->get_all_inner_texts_by_attribute(«id»,»content»); sleep($wt); // удаляем лишнее echo $text = get_string($content[0],»Морской транспорт – организации»,»Страницы» ); sleep($wt); // записываем данные в файл $textfile->add_string_to_file($str_res,$text); sleep($wt);

Так же можно использовать заранее написанную нами функцию для перехода на следующую страницу next_page();, которая так же находится в файле «tools/functions.php».

// функция осуществляющая переход со страницы на страницу // $crnt_page — текущая страница // $cnt_pages — количество страниц для обработки function next_page() { global $anchor, $browser, $app,$crnt_page, $cnt_pages; // количество поисковых страниц $crnt_page = $crnt_page + 1; // если $cnt_pages == -1, значит скрипт будет искать все страницы до конца поиска if ($cnt_pages != -1) { // если обработали все нужные нам страницы — останавливаем скрипт if ($crnt_page > $cnt_pages) { debug_mess(«обработали все заданные страницы «.($crnt_page — 1)); $crnt_page = 1; return false; } } // перейдём на следующую страницу if (!$anchor->click_by_inner_text($crnt_page, true)) { debug_mess(«обработали все доступные страницы » .

($crnt_page — 1)); $crnt_page = 1; return false; } debug_mess(«обработали страницу » . ($crnt_page — 1)); return true; }

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

debug_mess(» скрипт запустили»); // переходим на сайт $browser->navigate(«$site»); sleep($wt); while(true) { // получаем нужные данные со страницы $content = $div->get_all_inner_texts_by_attribute(«id»,»content»); sleep($wt); // удаляем лишнее echo $text = get_string($content[0],»Морской транспорт – организации»,»Страницы» ); sleep($wt); // записываем данные в файл $textfile->add_string_to_file($str_res,$text); sleep($wt); // перейти на следующую страницу debug_mess(«
переходим на следующую страницу
«); next_page(); sleep($wt_long); } debug_mess(«скрипт закончил работу»); // Quit $app->quit();

В итоге за 15 минут мы накидали скрипт парсер, который собирает данные со всех страниц, либо только с заданных.

Если бы мы стали писать парсер на php, то это заняло у нас гараздо больше времени.

<< Другие статьи

Добавить комментарий

Закрыть меню