Парсер php html jquery

парсим сайты легко и непринуждённо вместе с phpQuery

Имеется довольно много способов сделать это.
phpQuery::newDocument($html, $contentType = null) Создаём новый документ из разметки. Если не указали $contentType, будет определен основываясь на разметке. Если не получится то будем считать что это, text/html в utf-8.
phpQuery::newDocumentFile($file, $contentType = null) Создаём новый документ из файла. Работает также как и newDocument()
phpQuery::newDocumentHTML($html, $charset = ‘utf-8’)
phpQuery::newDocumentXHTML($html, $charset = ‘utf-8’)
phpQuery::newDocumentXML($html, $charset = ‘utf-8’)
phpQuery::newDocumentPHP($html, $contentType = null) Подробнее можете почитать об этом здесь.
phpQuery::newDocumentFileHTML($file, $charset = ‘utf-8’)
phpQuery::newDocumentFileXHTML($file, $charset = ‘utf-8’)
phpQuery::newDocumentFileXML($file, $charset = ‘utf-8’)
phpQuery::newDocumentFilePHP($file, $contentType) Подробнее можете почитать об этом здесь.

Ну а мы, далеко ходить не будем. Давай %username%, распарсим твои записи в блоге. Сначала скачаем phpQuery. Теперь создаём что то вроде index.php

find('div.hentry'); foreach ($hentry as $el) < $pq = pq($el); // Это аналог $ в jQuery $pq->find('h2.entry-title > a.blog')->attr('href', 'http://%username%.habrahabr.ru/blog/')->html('%username%'); // меняем атрибуты найденого элемента $pq->find('div.entry-info')->remove(); // удаляем ненужный элемент $tags = $pq->find('ul.tags > li > a'); $tags->append(': ')->prepend(' :'); // добавляем двоеточия по бокам $pq->find('div.content')->prepend('
')->prepend($tags); // добавляем контент в начало найденого элемента > echo $hentry; ?>

Это всего лишь малая часть того что возможно сделать.
Также вместе с ней поставляется такая штука как jQueryServer. По сути, это тоже самое что и phpQuery, но на стороне клиента.
Пример из демки

Читайте также:  Php get extending class

Данный вариант довольно практичный и позволяет распарсить контент с нескольких сайтов в несколько секунд, не утруждая себя в написании php кода.

Материалы по теме

Если вам интересно в следующей статье я хочу рассмотреть парсинг сайтов доступных только авторизованным пользователям (без капчи конечна). Да, phpQuery умеет и это, правда не без помощи Zend Framework.

Источник

Пример парсинга html-страницы на phpQuery

phpQuery – это удобный HTML парсер взявший за основу селекторы, фильтры и методы jQuery, которые позволяют манипулировать элементами HTML/XML и получать их содержимое.

В примерах используется страница карточки товара https://snipp.ru/demo/76/index.html, все спарсенные данные помещаются в общий массив $data .

Пример страницы товара в интернет-магазине

Подготовка

Включение вывода ошибок PHP:

error_reporting(E_ALL); ini_set('display_errors', 1);

Локаль:

setlocale(LC_ALL, 'ru_RU'); date_default_timezone_set('Europe/Moscow'); header('Content-type: text/html; charset=utf-8');
include_once __DIR__ . '/phpQuery.php'; $doc = phpQuery::newDocument(file_get_contents('https://snipp.ru/demo/76/index.html'));

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

$html = file_get_contents('https://snipp.ru/demo/76/index.html'); $html = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $html); include_once __DIR__ . '/phpQuery.php'; $doc = phpQuery::newDocument($html);

Подробнее в статье «Перекодировка текста UTF-8 и WINDOWS-1251». Ещё бывают случаи, когда file_get_contents возвращает полученный контент сжатый в GZIP, например: �mw�Ƒ0�����&IkAI��f��j4/

function getcontents($url) < $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_ENCODING, 'gzip'); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); $output = curl_exec($ch); curl_close($ch); return $output; >include_once __DIR__ . '/phpQuery.php'; $doc = phpQuery::newDocument(getcontents('https://snipp.ru/demo/76/index.html'));

Мета-теги

Пример кода head страницы

Заголовок страницы (title)

Метод find(‘selector’) находит элементы по селектору, далее вызывается функция pq() , которая возвращает объект найденного элемента (подобно $ в jquery). К этому объекту можно применить методы, например text() – получить текстовое содержимое элемента.

$entry = $doc->find('title'); $data['title'] = pq($entry)->text(); echo $data['title'];

Результат:

Пример магазина - Электрогитара синего цвета Yamaha Pacifica012

Keywords и Description

$entry = $doc->find('head meta[name="keywords"]'); $data['keywords'] = pq($entry)->attr('content'); echo $data['keywords']; $entry = $doc->find('head meta[name="description"]'); $data['description'] = pq($entry)->attr('content'); echo $data['description'];

Результат:

Электрогитара,Yamaha,Pacifica012 Интернет-магазин цифровой и бытовой техники

Несколько элементов

$data['css'] = array(); $entry = $doc->find('head link[rel="stylesheet"]'); foreach ($entry as $row) < $data['css'][] = pq($row)->attr('href'); > print_r($data['css']);

Результат:

Array ( [0] => style.css [1] => https://snipp.ru/cdn/fontawesome/5.11.2/css/all.css )

Заголовок h1

Заголовок h1 в исходном коде страницы

$entry = $doc->find('h1'); $data['h1'] = pq($entry)->text(); echo $data['h1'];

Результат:

Электрогитара синего цвета Yamaha Pacifica012

Хлебные крошки

Хлебные крошки - вид на сайте

Хлебные крошки в исходном коде страницы

$data['breadcrumbs'] = array(); $entry = $doc->find('.breadcrumbs li a'); foreach ($entry as $row) < $ent = pq($row); $name = $ent->text(); $url = $ent->attr('href'); $data['breadcrumbs'][$name] = $url; > print_r($data['breadcrumbs']);

Результат:

Array ( [Аудио] => /audio/ [Музыкальные инструменты] => /audio/instruments/ [Гитары и аксессуары] => /audio/instruments/guitar/ [Yamaha] => /audio/instruments/guitar/yamaha )

Артикул

Артикул - вид на сайте

Артикул в исходном коде страницы

В данном случаи нужно только значение, c помощью метода remove() удаляется элемент с текстом «Артикул».

$entry = $doc->find('.prod .prod-sku'); $entry->find('span')->remove(); $data['sku'] = trim(pq($entry)->text()); echo $data['sku'];

Результат:

Цены

Цены - вид на сайте

Цены в исходном коде страницы

Цены выводятся с форматированием, его можно удалить регулярным выражением и привести значение к типу float или сразу применить PHP-функцию clean_price().

/* Старая цена - strike */ $entry = $doc->find('.price-price strike'); $val = pq($entry)->text(); $data['price_old'] = floatval(mb_ereg_replace('[^0-9.,]', '', $val)); var_dump($data['price_old']); /* Старая цена - span */ $entry = $doc->find('.price-price span'); $val = pq($entry)->text(); $data['price'] = floatval(mb_ereg_replace('[^0-9.,]', '', $val)); var_dump($data['price']);

Результат:

Изображения

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

Изображения - вид на сайте

Изображения в исходном коде страницы

$data['images'] = array(); $entry = $doc->find('.prod-left img'); foreach ($entry as $row) < $link = pq($row)->parents('a'); $data['images'][] = pq($link)->attr('href'); > print_r($data['images']);

Результат:

Array ( [0] => /demo/76/Yamaha-1.jpg [1] => /demo/76/Yamaha-2.jpg [2] => /demo/76/Yamaha-3.jpg [3] => /demo/76/Yamaha-4.jpg )

Списки dl dd dt

Список dl - вид на сайте

Список dl dd dt в исходном коде страницы

Сложность парсинга списков определений заключается в том, что у нескольких

и может быть один контейнер . Решение – по отдельности спарсить все dt и dd и слить их в один массив функцией array_combine() .
/* dt */ $dt = array(); $entry = $doc->find('dl dt'); foreach ($entry as $row) < $dt[] = trim(pq($row)->text(), ':'); > /* dl */ $dd = array(); $entry = $doc->find('dl dd'); foreach ($entry as $row) < $dd[] = pq($row)->text(); > $data['attrs'] = array_combine($dt, $dd); print_r($data['attrs']);

Результат:

Array ( [Товара в наличии] => 14шт [Доставка] => завтра [Гарантия] => 12 мес. [Страна-производитель] => Индонезия )

Списки ul

Список - вид на сайте

Маркированный список в исходном коде страницы

$data['list'] = array(); $entry = $doc->find('ul.features li'); foreach ($entry as $row) < $data['list'][] = pq($row)->text(); > print_r($data['list']);

Результат:

Array ( [0] => Универсальная шестиструнная электрогитара серии Pacifica [1] => Корпус superstrat из агатиса [2] => Кленовый гриф с палисандровой накладкой [3] => Тремоло-бридж Vintage Tremolo [4] => 22 лада [5] => Хромированные колки [6] => Два сингла и один хамбакер )

Таблицы

Таблица - вид на сайте

Таблица в исходном коде страницы

Найдем все

в таблице, далее в цикле найдем в них ячейки по порядковым номерам с помощью селекторов td:eq(0) и td:eq(1) .
$data['table'] = array(); $entry = $doc->find('table.base-table tr'); foreach ($entry as $row) < $row = pq($row); $name = $row->find('td:eq(0)')->text(); $value = $row->find('td:eq(1)')->text(); $data['table'][$name] = $value; > print_r($data['table']);

Результат:

Array ( [Тип] => электрогитара [Материал корпуса] => агатис [Количество струн] => 6 [Тип корпуса] => superstrat [Материал грифа] => клён [Накладка грифа] => палисандр [Радиус накладки грифа] => 350 мм [Мензура] => 648 мм (25,5’’) [Бридж] => Vintage Tremolo, тремоло, хромированный [Лады] => 22 [Звукосниматели] => 2 сингла у грифа и в средней позиции + хамбакер у бриджа [Снятие] => HSS [Колки] => хром [Ориентация] => для правшей [Цвета] => белый, темно-синий металлик, красный металлик, чёрный [Аксессуары в комплекте] => нет )

Произвольный контент

Описание - вид на сайте

Текст с разметкой в исходном коде страницы

Найдем

, удалим из него заголовок и получим html-содержимое.
$entry = $doc->find('div.text'); $entry->find('h2')->remove(); $data['text'] = pq($entry)->html(); echo $data['text'];

Результат:

 

Разработанная на основе модели Pacifica 112, новая, еще более доступная по цене модель 012 характеризуется аналогичными контурами корпуса, мощным хамбакером в бриджевой позиции и 2 синглами, обеспечивающими чистое звучание. Гитара оснащена удобным грифом, 5-позиционным переключателем выбора звукоснимателей и тремоло типа Vintage.

Корпус: агатис. Гриф: привинченный, клен. Накладка грифа: сонокелинг, радиус 350 мм. Лады: 22. Мензура: 648 мм. Звукосниматель: 2 сингла, 1 хамбакер. Регуляторы: 5-позиционный переключатель звукоснимателей, мастер-громкость, тембр. Бридж: тремоло типа Vintage.

Источник

PHP HTML DOM парсер с jQuery подобными селекторами

Добрый день, уважаемые хабровчане. В данном посте речь пойдет о совместном проекте S. C. Chen и John Schlick под названием PHP Simple HTML DOM Parser (ссылки на sourceforge).

Идея проекта — создать инструмент позволяющий работать с html кодом используя jQuery подобные селекторы. Оригинальная идея принадлежит Jose Solorzano’s и реализована для php четвертой версии. Данный же проект является более усовершенствованной версией базирующейся на php5+.

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

Получение html кода страницы
$html = file_get_html('http://habrahabr.ru/'); //работает и с https:// 

Товарищ Fedcomp дал полезный комментарий насчет file_get_contents и 404 ответа. Оригинальный скрипт при запросе к 404 странице не возвращает ничего. Чтобы исправить ситуацию, я добавил проверку на get_headers. Доработанный скрипт можно взять тут.

Поиск элемента по имени тега
foreach($html->find('img') as $element) < //выборка всех тегов img на странице echo $element->src . '
'; // построчный вывод содержания всех найденных атрибутов src >
Модификация html элементов
$html = str_get_html('
Hello
World
'); // читаем html код из строки (file_get_html() - из файла) $html->find('div', 1)->class = 'bar'; // присвоить элементу div с порядковым номером 1 класс "bar" $html->find('div[id=hello]', 0)->innertext = 'foo'; // записать в элемент div с текст foo echo $html; // выведет
foo
World
Получение текстового содержания элемента (plaintext)
echo file_get_html('http://habrahabr.ru/')->plaintext; 

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

Пример парсера сообщений из twitter
require_once 'simple_html_dom.php'; // библиотека для парсинга $username = 'habrahabr'; // Имя в twitter $maxpost = '5'; // к-во постов $html = file_get_html('https://twitter.com/' . $username); $i = '0'; foreach ($html->find('li.expanding-stream-item') as $article) < //выбираем все li сообщений $item['text'] = $article->find('p.js-tweet-text', 0)->innertext; // парсим текст сообщения в html формате $item['time'] = $article->find('small.time', 0)->innertext; // парсим время в html формате $articles[] = $item; // пишем в массив $i++; if ($i == $maxpost) break; // прерывание цикла > 
Вывод сообщений

 for ($j = 0; $j < $maxpost; $j++) < echo '
'; echo '

' . $articles[$j]['text'] . '

'; echo '

' . $articles[$j]['time'] . '

'; echo '
'; >

Благодарю за внимание. Надеюсь, получилось не очень тяжеловесно и легко для восприятия.

Похожие библиотеки

P.S.
Хаброжитель Groove подсказал что подобные материалы уже были
P.P.S.
Постараюсь в свободное время собрать все библиотеки и составить сводные данные по производительности и приятности использования.

Источник

Оцените статью