Простой парсинг данных средствами PHP

Простой парсинг данных средствами PHP

Рано или поздно любой программист встречается с задачей, когда необходимо слить позаимствовать данные с других ресурсов. Если у этих сторонних ресурсов нет API или каких бы то ни было технологий, что бы структурно получить данные, приходится прибегать к парсингу (Scraping).

В данной статье будет рассмотрен пример того, как можно получить данные со стороннего ресурса (на примере будет рассмотрен сайт bash.im), проанализировать их и вывести необходимую информацию на страницу.

Первым делом нам необходимо задать настройки для проекта и вынести их в отдельный файл «settings.php», в папку «conf» с содержимым:

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
date_default_timezone_set('Europe/Moscow');
header('Content-type: text/html; charset=cp1251');

$time = 60*60*1;
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $time) . ' GMT');
header("Cache-Control: private, max-age=$time");

 

Так же нам необходимо создать функцию для того, что бы забирать все данные по определенному URL и разместим ее в файл «function.php» папки «core»

//отправка get запроса
function my_file_get_contents(string $url = '', array $headers = null, string $cookie = null, string $proxy = null, string $proxyauth = null): string {
    //возвращаемые данные
    $data = null;
    try{
        $curl = curl_init();
        curl_setopt_array($curl,[
            CURLOPT_URL => $url, //url отправки данных
            CURLOPT_ENCODING => "UTF-8", //кодировка данных
            CURLOPT_HEADER => false, //не возвращать заголовки
            CURLOPT_RETURNTRANSFER => true, //необрабатывать ответ
            CURLOPT_AUTOREFERER => true, //автоматическая установка поля Referer
            CURLOPT_FOLLOWLOCATION => true, //автопереходы при редиректах
            CURLOPT_TIMEOUT => 15, //время ожидание в секундах
            CURLOPT_CONNECTTIMEOUT => 5, //время конекта в секундах
            CURLOPT_SSL_VERIFYPEER => false, //для обращения к https
            CURLOPT_SSL_VERIFYHOST => false, //для обращения к https
        ]);
        //если используется дополнительные заголовки
        if( $headers and is_array($headers) and count($headers) ) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        } else { // вбиваем юзер агент для стандарта
            curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0');
        }
        //если используется файл кук
        if( $cookie ){
            if( !file_exists($cookie) ){
                $fp = fopen($cookie, "w+");
                fwrite($fp, "");
                fclose($fp);
            }
            curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
            curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie);
        }
        //проверка параметров для прокси соединения
        if( $proxy ){
            //прокси сервер
            curl_setopt($curl, CURLOPT_PROXY, $proxy);
            //используемый драйвер
            curl_setopt($curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
            //необходимо ли авторизироваться
            if($proxyauth){
                curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyauth);
            }
        }
        //получам данные
        $data = curl_exec($curl);
        //проверка на ошибку
        $data = $data ? $data : curl_error($curl);
        //закрываем соединение
        curl_close($curl);
    } catch (Exception $e) {
        $data = null;
    }
    return $data;
}

 

В данную функцию («my_file_get_contents») можно передать 5 параметров:

  • $url — url по которому будем забирать всю структуру данных
  • $headers — массив передаваемых заголовков
  • $cookie — путь до файла, где будут содержаться все используемые куки на сайте
  • $proxy — прокси сервер, через который будет идти подключение
  • $proxyauth — логин и пароль для авторизации на прокси сервере

 

После получения данных с ресурса нам необходимо привести их в «божеский» вид. Для этого нам понадобится библиотека Simple HTML DOM, которая преобразует полученную HTML строку в понятный объект HTML, где можно просто осуществлять поиск и переходы между элементами DOM дерева страницы. Зайдем на официальный репозиторий, скачиваем архив с библиотекой и разархивируем в папку «vendor».

Теперь необходимо объединить получение данный с ресурса и преобразования их в объект, для этого создадим функцию «my_parser_url», в которую будет передаваться сам URL, искомый объект и запускаемая функция после получения и преобразования данных.

// основные параметры парсинга
function my_parser_url(string $url = null, string $find = null, callable $callable = null ) {
    if( !$url ) return false;
    $dataText = my_file_get_contents(
        $url, //url для чтения
        [ //передаваемые заголовки
            'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3',
            'Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3',
            'Accept-Encoding: gzip,deflate',
            'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7',
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        ],
        dirname(__FILE__) . '/../cookie.txt' //файл для сохранения кук
    );
    //если в поиск передается "NULL", то данные передаются в функцию без преобразования
    //на случай если нам необходимо отпарсить json
    if( $find === null ){
        //если запускаемая функция не передана, возвращаем полученные данные в исходном состоянии
        return $callable ? $callable($dataText) : $dataText;
    }
    //преобразуем данные в объект
    $dataObject = str_get_html( $dataText );
    //получаем необходимый элемент в DOM
    $dataObject = $find ? $dataObject->find($find, 0) : $dataObject;
    //возвращаем результат функции с переданными данными или полученный объект
    return $callable ? $callable($dataObject) : $dataObject;
}

 

Данную функцию также помещаем в файл «function.php».

Теперь остался последний штрих, объединить все файлы и получить данные.

Добавляем в файл «index.php» содержимое:

// файл общей конфигурации
require_once("conf/settings.php");
// библиотека для парсинга
require_once ("vendor/simple_html_dom/simple_html_dom.php");
// набор статических функций
require_once("core/functions.php");
//домен для парсинга
$urlPars = "bash.im";
//получение данных
$result = my_parser_url(
    "https://$urlPars/", // URL для получения данных
    "#body", // искомый глобальный блок
    function ( $body ) use ($urlPars) { // функция для обработки содержимого
        // переменная для сохранения результата
        $res = '';
        // проход по каждому элементу списка
        foreach ( $body->find('.quote') as $list ){
            // сохраняем данные прохода
            $res .= "<p><a href='//$urlPars".$list->find('a.id', 0)->href."'>".$list->find('.text', 0)->innertext."</a></p>";
        }
        return $res; // возвращаем результат
    }
);
// вывод результата полученный в результате парсинга
echo $result;

 

После подключения всех файлов запускается функция «me_parser_url», в которую передается URL, искомый объект, в котором содержится необходимый список, и анонимная функция, где идет проход по каждому элементу с классом «quote», где идет поиск и вывод текста цитаты и ссылка на ее страницу.

 

Полезные ссылки:

GitHub страница с исходником

Опубликовано:
Пожертвование
На развите проекта, продление хостинга и на корм бобику - Дикуше :)