Довольно часто попадаются заказы на сбор контента и упаковку его в базу, т.е. парсинг сайтов.
Для решения таких проблем подходят стандартные средства php для парсинга xml-файлов (html является подвидом xml как ни крути, меня вот поправили маленькая поправка: html – не подвид xml, это производная sgml (RFC1866), xml – упрошенный подвид sgml, xhtml – приложение xml и как результат подвид sgml) совместно с регулярными выражениями.
Кода получается много, и после длительного времени разобраться в них становится несовсем просто.
Недавно наткнулся на довольно интереcный порт jQuery в php, на библиотеку под названием phpQuery (http://code.google.com/p/phpquery/).
Пользователям jQuery, знаком его очень удобный механизм селекторов, который упрощает работу со структурой документа и выборкой его элементов.
Приведу пример как можно парсить всеми любимый сайт
, точнее его раздел блогов )
код для себя делал, в качестве теста библиотеки, комментов минимум, тот кто в теме разберется
ini_set(‘max_execution_time’, ’0′);
error_reporting(E_ALL);
$t=mktime();
define(‘URL’, ‘http://www.free-lance.ru/blogs/viewgroup.php’);
require(‘phpQuery/phpQuery/phpQuery.php’);
echo mktime()-$t.’
‘;
$results_page = get_xml_page(URL);
$results = phpQuery::newDocument($results_page);
// див с контентом
$elements = $results->find(‘#rightcl > div.blog’);
$info = array();
foreach ($elements as $element){
echo count(($info)).’
‘;
//— заголовок поста
$title = pq($element)->find(‘div.blogcnt > div.header > a’);
//— берем в виде текста
$title = pq($title)->text();
echo ‘title: ‘.$title.’
‘;
//— поиск блока с логином фрилансера
$login = pq($element)->find(‘div.blogcnt > div.frllogin a’);
$login = pq($login)->text();
//— логин фрилансера найден?
if(!empty($login)){
//— дата поста
$datepost = pq($element)->find(‘div.blogcnt > div.frllogin > span’);
$datepost = pq($datepost)->text();
$datepost = substr($datepost, 0, strpos($datepost,’]')+1);
}
//— логин не был найден
if(empty($login)){
//— логин заказчика
$login = pq($element)->find(‘div.blogcnt > div.emplogin a’);
$login = pq($login)->text();
$datepost = pq($element)->find(‘div.blogcnt > div.emplogin > span’);
$datepost = pq($datepost)->text();
$datepost = substr($datepost, 0, strpos($datepost,’]')+1);
}
echo ‘login: ‘.$login.’
‘;
echo ‘datepost: ‘.$datepost.’
‘;
//— текст поста
$text=pq($element)->find(‘div.blogcnt > div > table’);
$text = pq($text)->text();
echo ‘text:’.$text.’
‘;
//— смотри есть там прикрепленная картинка
$img=$text=pq($element)->find(‘div.blogcnt > div > table tr > td > div > a > img’);
//— берем aтрибут src
$img=pq($img)->attr(‘src’);
if(!empty($img)){
echo ‘img: < img src=» http://www.free-lance.ru/ ‘.$img.’»>
‘
}
//— берем ссылку на полный просмотр поста
$link=pq($element)->find(‘div.footer > div.commline > a’);
$link=pq($link)->attr(‘href’);
echo ‘link: http://www.free-lance.ru’.$link.’
‘;
$info[] = array(‘title’ => $title, ‘login’=>$login, ‘datepost’=>$datepost);
echo ‘
‘;
}
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
Действительно офигенная статья, раньше мне приходилось парится с DomDocument-ом (инструмент тоже хороший, правда много чего не хватает: к примеру фильтрации по классу, или по атрибуту, с вложенностью тоже проблемы, когда нужно найти ссылки, которые находятся внутри li с классом active внутри ul с классом list, приходилось последовательно получать через DomDocument::getElementsByTagName() и искать в них, с нужным классом).
Здесь же можно это можно получить с помощью всего одной строчки
pq(«ul.list li.active a») : супер удобно
нихрена не понятно. можно побольбьше прокомментировать статью?
очень инетересна тема. но этот пример нагружает кучу ошибок когда кладу его на сервер
вот пример кода