На моей практике довольно часто встречались задачи вроде: спарсить таблицу с какого-то сайта в csv-файл, сграбить картинки с какого-то сайта и т.д. Все эти задачи можно обобщить термином парсинг сайтов. Большинство из нас, как и я раньше для решения таких проблем использовали стандартные средства php для парсинга xml-файлов (html все-таки является подвидом xml) совместно с регулярными выражениями.
Скрипты получались довольно громоздкими и непонятными. К счастью для себя, я недавно наткнулся на библиотеку под названием phpQuery (http://code.google.com/p/phpquery/), которая является портированным jQuery в php.
Если Вы пользовались jQuery, то должны знать о его очень удобном механизме селекторов, который мог бы быть чрезвычайно полезным при парсинге сайтов.
Допустим у нас есть такой кусок кода:
<ol class="results" start="1">
...
<li>
<div class="title">
<i style="background-image: url(http://favicon.yandex.net/favicon/www.medvedev-da.ru);"/>
<a target="_blank" href="http://www.medvedev-da.ru/" onmousedown="w(this,'80.22.82','84=85,186=80');" tabindex="2">Дмитрий <b>Медведев</b> - Главная</a>
</div>
<div class="text">
<span>"Правительству нужно действовать незамедлительно, бегом!" - Итоги <wbr/>2008 года - взгляд Президента России Дмитрия <b>Медведева</b>.</span><br/>
</div>
<div class="info">
<span style="color: rgb(0, 102, 0);">
www.medvedev-da.ru
· 9 КБ
</span>
</div>
<div class="info">
<nobr><a target="_blank" href="...">Сохраненная копия</a></nobr>
· <nobr><a onmousedown="..." href="...">Еще с сайта</a> <span class="count">39241</span></nobr>
· <nobr>Рубрика: <a href="..." onmousedown="w(this,'80.83','84=85');">Политика</a></nobr>
</div>
</li>
...
</ol>
Это код обычной страницы с результатами поиска Yandex`а по запросу “медведев”.
Нам нужно спарсить title страницы-результата, ее краткое описание и адрес страницы.
С помощью phpQuery, код будет примерно таким:
<?php
ini_set('max_execution_time', '0');
error_reporting(E_ALL);
define('URL', 'http://yandex.ru/yandsearch?text=медведев');
require('phpQuery.php');
$results_page = get_xml_page(URL);
$results = phpQuery::newDocument($results_page);
$elements = $results->find('ol.results > li');
$info = array();
foreach ($elements as $element){
$title = pq($element)->find('div.title > a');
$title = pq($title)->text();
$descr = pq($element)->find('div.text > span');
$descr = pq($descr)->text();
$link_text = pq($element)->find('div.info:first > span');
$link_text = pq($link_text)->text();
$link_text = explode('•', $link_text);
$link = trim($link_text[0]);
$info[] = array('title' => $title, 'descr' => $descr, 'link' => $link);
}
print_r($info);
function get_xml_page($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$page = curl_exec($ch);
curl_close($ch);
return $page;
}
?>
Как видите, код довольно понятный и его можно очень легко модифицировать при необходимости. Что касается самой библиотеки phpQuery, в этой статье я рассмотрел лишь часть ее возможностей на примере парсинга сайтов. На самом деле, с ее помощью можно так же легко модифицировать структуру документа html и еще много другого.
Более подробную документацию к ней можно найти в блоге ее разработчика: http://phpquery-library.blogspot.com/.
На этом все. Удачи!