Простой парсер на PHP

phpxdbg.jpgНа сегодняшний день встречается очень много проектов, в которых необходимо собирать определённую информацию с чужих сайтов. Этот процесс называется «граббингом» или «парсингом». Оставим в стороне вопросы этичности этого процесса, предполагается, что вы знаете, что такое хорошо и что такое плохо, и не будете применять сие знание во вред кому-либо.

В этой статье мы создадим простой парсер на популярном языке PHP.

Заранее извиняюсь перед своими читателями, которые не знакомы с программированием, но специфика SEO зачастую предполагает наличие и программерских навыков. Приступим.

Что будем парсить? В качестве учебного примера предлагаю создать средство для сбора статей широкоизвестного технического журналиста Криса Касперски (популярного автора журнала «Хакер»).

Getting started

Статьи Криса расположены по этому адресу: h++p://www.xakep.ru/post/35410/default.asp. Это и будет нашей отправной точкой. Скачивание страницы для парсинга будем выполнять, используя библиотеку cURL. Итак, инициализируем библиотеку и скачиваем нашу страницу:

$ch = curl_init (); // инициализация
curl_setopt ($ch , CURLOPT_URL , "http://www.xakep.ru/post/35410/default.asp"); // адрес страницы для скачивания
curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.12) Gecko/20050919 Firefox/1.0.7"); // каким браузером будем прикидываться
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 ); // нам нужно вывести загруженную страницу в переменную
$content = curl_exec($ch); // скачиваем страницу
curl_close($ch); // закрываем соединение

Расчленение

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

<p>Название статьи<br>
<a href="адрес_статьи">адрес_статьи</a></p>

Напишем регулярное выражение, которое будет «выдирать» интересующие нас названия и адреса из кода страницы:

preg_match_all("/<p>(.*)<br>\r\n<a href=\"(.*)\">.*<\/a><\/p>/isU", $content, $matches, PREG_PATTERN_ORDER);

В рамки этой статьи не входит объяснение необъятной темы регулярных выражений, поэтому отсылаю вас к коротенькому справочнику по ним. Также рекомендую посмотреть информацию о функции preg_match_all для лучшего понимания кода.

Вырезка

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

Просматривая код страницы, можно обнаружить, что текст статьи всегда обрамлён следующими тегами

<hr width="200" size="1" noshade align="left">
..текст статьи..
<center><p><a href="../">Содержание</a>

На основе этого закона мы и постоим парсер. Все необходимые поянения даны в комментариях:

for ($i = 0; $i < count($matches[1]); $i++) // цикл по всем, извлеченным из стартовой страницы, адресам
{
echo "<h1>".$matches[1][$i]."</h1>"; // выводим название статьи как заголово
flush(); // заставляем вывести текст немедленно
$ch = curl_init (); // инициализация
curl_setopt ($ch , CURLOPT_URL , $matches[2][$i]); // ссылка на текущую статью, адрес которой мы извлекли из первой страницы
curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.12) Gecko/20050919 Firefox/1.0.7");
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 );
$content = curl_exec($ch);
curl_close($ch);

preg_match_all("/<hr width=\"200\" size=\"1\" noshade align=\"left\">(.*)<center><p><a href=\"\.\.\/\">.*<\/a>/isU", $content, $matches_art, PREG_PATTERN_ORDER); // выдираем текст статьи
echo $matches_art[1][ 0]; // выводим её (опять же смотри описание функции preg_match_all в справочнике)
flush(); // заставляем вывести текст немедленно
sleep(2); // отдыхаем две секунды, чтобы не вызвать подозрение у сервера
}

Finish

Ну вот, собственно, и всё! В итоге мы получим ленту статей Криса, без рекламы, оформления сайта и прочих радостей.

Полный код скрипта:

$ch = curl_init ();
curl_setopt ($ch , CURLOPT_URL , "http://www.xakep.ru/post/35410/default.asp");
curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.12) Gecko/20050919 Firefox/1.0.7");
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 );
$content = curl_exec($ch);
curl_close($ch);

preg_match_all("/<p>(.*)<br>\r\n<a href=\"(.*)\">.*<\/a><\/p>/isU", $content, $matches, PREG_PATTERN_ORDER);

for ($i = 0; $i < count($matches[1]); $i++)
{
echo "<h1>".$matches[1][$i]."</h1>";
flush();
$ch = curl_init ();
curl_setopt ($ch , CURLOPT_URL , $matches[2][$i]);
curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.12) Gecko/20050919 Firefox/1.0.7");
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 );
$content = curl_exec($ch);
curl_close($ch);

preg_match_all("/<hr width=\"200\" size=\"1\" noshade align=\"left\">(.*)<center><p><a href=\"\.\.\/\">.*<\/a>/isU", $content, $matches_art, PREG_PATTERN_ORDER);
echo $matches_art[1][ 0];
flush();
sleep(2);
}

h++p://westseo.ru/simple-php-parser/

3 комментария

Оставить комментарий

Ваш электронный адрес не будет опубликован.


*


5 × пять =