Нескольким читателям моего блога было интересно узнать «как объединить крон, базу данных и php парсер». Я постарался написать максимально простой и лаконичный скрипт, чтобы любой новичок смог в нём разобраться. Он состоит всего из одного файла index.php и 50 строк кода.
Я использовал 2 библиотеки:
Парсить в учебных целях мы будем один сайт о моде и красоте. Остановимся мы только на парсинге 10 статей, чтобы понять суть.
require 'db.php'; // подключаем библиотеку ReadbeenPHP и соединяемся с базой данных require('/phpQuery/phpQuery.php'); // подключаем phpQuery define('HOST','http://tbeauty.ru'); // сюда мы вписываем адрес сайта-донора, который необходимо спарсить R::wipe('post'); // удаляем все записи из таблицы post R::wipe('postprev'); // удаляем все записи из таблицы postprev $data_site = file_get_contents(HOST); // получаем страницу сайта-донора $document = phpQuery::newDocument($data_site); $content_prev = $document->find('.news .post'); // перебираем в цикле все посты foreach ($content_prev as $el) { // Парсим превьюшки статей $pq = pq($el); // pq это аналог $ в jQuery $h2 = $pq->find('.post-title h2 a')->attr('title'); // парсим заголовок статьи $link = $pq->find('.post-title h2 a')->attr('href'); // парсим ссылку на статью $text = $pq->find('.post-content p'); // парсим текст в превью статьи $img = $pq->find('.wp-post-image')->attr('src'); // парсим ссылку на изображение в превью статьи // Записываем информацию о превьюшках в базу данных $post_prev = R::dispense('postprev'); if(!empty($h2)) $post_prev->h2 = strip_tags($h2); // strip_tags удаляет HTML тэги из строки if(!empty($link)) $post_prev->link = HOST.$link; if(!empty($text)) $post_prev->text = strip_tags($text); if(!empty($img)) $post_prev->img = HOST.$img; R::store($post_prev); // пробегаемся по всем ссылкам на посты и парсим контент из открытых статей if(!empty($link)) $data_link = file_get_contents(HOST.$link); $document_с = phpQuery::newDocument($data_link); $content = $document_с->find('.broden-ajax-content'); foreach ($content as $element) { $pq2 = pq($element); $h1 = $pq2->find('.post-title h1'); // парсим главный заголовок статьи $text_all = $pq2->find('.article__content .txt'); // парсим контент часть статьи } // Записываем информацию о статьях в базу данных $post = R::dispense('post'); if(!empty($h1)) $post->h1 = strip_tags($h1); if(!empty($text_all)) $post->text = strip_tags($text_all); R::store($post); }
require 'libs/rb.php'; R::setup( 'mysql:host=127.0.0.1;dbname=parserlinio','root', '' ); if ( !R::testconnection() ) { exit ('Нет соединения с базой данных'); }
Если мы запустим парсер, то в базе данных автоматически появятся 2 таблички. В таблице postprev запишется информация о превью статей (картинка, заголовок, небольшой текст и ссылка на сам пост). В таблицу post запишется уже полная информация о статьях.
Вот такая красота в итоге получается.
P.S. Данный парсер очень простой и его функционал можно расширять до бесконечности. Тестировался парсер на OpenServer. Версия PHP 5.6. На момент написания статьи всё работало. Если у вас не работает, то возможно у сайта-донора поменялся дизайн и соответственно вёрстка.
Скачать php парсер + дамп базы
Купить/заказать парсер под свои нужны
По поводу удаления:
1. Либо ключом сделать ссылку на статью (и 2 две таблицы объединить), но если ссылку изменят, что странно, но возможно, то статья продублируется.
Либо сделать md5 из заголовка статьи и его сделать ключом.
2. Искать, по ключу и если найдена — обновлять, иначе добавлять.