Все ленты — последние статьи

Как сделать простой скрепер на PHP без регулярных выражений.

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

В данном уроке мы создадим простой скрепер, который получает заголовок и фавикон с  HTML страницы.

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

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

<html>
<title>Заголовок страницы | Имя сайта</title>
<link rel="shortcut icon" href="http://www.site.com/favicon.ico"/>
…
<body>
…
<h1>Title</h1>
…
</body>
</html>

Мы собираемся получить заголовок и фавикон из секции meta, а если заголовок отсутствует, то будем искать тег h1 в разделе body. Данные операции могут быть выполенены с использованием только двух функций.

function strInBetween($text,
$separatorStart,
$separatorEnd,
&$positionOut = null,
$after = null,
$afterIndex = 0)
{
$CYCLE_LIMIT = 500;
$stop = false;
$pos = 0;
$current = strInBetween($text, $separatorStart, $separatorEnd, $pos);
$matching = strpos($current, $containing);
$i = 0;
$afterIndex = 0;
while ($pos >= 0 && $matching === false && $i < $CYCLE_LIMIT)
{
$afterIndex += $pos + strlen($current);
$current = strInBetween($text, $separatorStart, $separatorEnd, $pos, null, $afterIndex);
$matching = strpos($current, $containing);
$i++;
}
if ($matching)
return $current;
else
return null;
}

Данная функция возвращает первую подстроку, найденную в аргументе $text, заключенную в два разделителя: $separatorStart и $separatorEnd. Опционально, другая подстрока или индекс могут быть определены для начала поиска после них:

  • $text — текст, где ищется подстрока
  • $separatorStart — разделитель строки слева
  • $separatorEnd — разделитель строки справа
  • &$positionOut — опциональный параметр вывода, содержит позицию, где находится подстрока.
  • $after — опциональный параметр, если определен, то поиск будет проводиться после подстроки $after
  • $afterIndex — опциональный параметр, используется если $after имеет значение null. Содержит индекс, с которого надо начинать поиск.
function strInBetweenContaining($text,
$separatorStart,
$containing,
$separatorEnd,
&$pos = null,
$after = null,
$afterIndex = 0)
{
if ($after != null)
{
$pos = strpos($text, $after);
if ($pos !== false)
$afterIndex = $pos;
}
$start = -1;
$pos = strpos($text, $separatorStart, $afterIndex);
if ($pos !== false)
$start = $pos;
$end = -1;
$pos = strpos($text, $separatorEnd, $start + strlen($separatorStart));
if ($pos !== false)
$end = $pos;
if ($start < 0 && $end < 0)
{
if ($positionOut != null)
$positionOut = -1;
return null;
}
else
{
if ($positionOut != null)
$positionOut = -1;
return substr($text, $start + strlen($separatorStart), $end — ($start + strlen($separatorStart)));
}
}

strInBetweenContaining основана на предыдущей функции. Она возвращает строку только если она содержит заданную подстроку.

А это код скрепера:

require_once('util/getpage.php');
require_once('util/stringutils.php');
$url = $_GET['u'];
$page = getpage($url);
function getTitle($page) { return strInBetween($page, '<title>', '</title>'); }
function getH1($page) { return strInBetween($page, '<h1', '</h1>'); }
function getLink($page)
{
$block = strInBetweenContaining($page, '<link', 'rel="shortcut icon"', '/>');
return strInBetween($block, 'href="', '"');
}
echo getTitle($page) . '<br>';
echo strip_tags('<h1' . getH1($page)) . '<br>';
$favicon = getLink($page);
if ($favicon == null)
$favicon = $url . 'favicon.ico';
//echo $favicon;
echo "<img src='$favicon' />";

Код достаточно простой и очевидный. Извлекается заголовок и первый тег h1, а затем наступает очередь фавикона. Если фавикон для страницы не найден, то код возвращает используемый по умолчанию (в соответствии с условиями в корневом каталоге сайта должен располагаться “favicon.ico”).

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

Использование парсера на основе регулярных выражений позволяет сделать более гибкое решение, но оно требует хороших знаний. Учите матчасть!

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: php-html.net/tutorials/how-to-write-a-simple-scrapper-in-php-without-regex/
Перевел: Сергей Фастунов
Урок создан: 15 Сентября 2010