NexxDigital - компьютеры и операционные системы

Вы узнаете, как получить список всех статей, опубликованных на сайте.

Шаг 1. Подготовка

В первую очередь нужно скопировать библиотеку simpleHTMLdom , которая доступна на сайте

В архиве для загрузки хранятся несколько файлов, но вам нужен только один simple_html_dom.php . Все остальные файлы - это примеры и документация.

Шаг 2. Основы парсинга

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

$html = new simple_html_dom();
// Загрузка из строки
$html->load("

Hello World!

");
// Загрузка файла
$html->load_file("http://net.tutsplus.com/");

Вы можете создать исходный объект загрузив HTML либо из строки, либо из файла. Загрузка из файла может быть выполнена либо через указание URL , либо из вашей локальной файловой системы.

Примечания: Метод load_file() делегирует работу функции PHP file_get_contents . Если allow_url_fopen не установлен в значение true в вашем файле php.ini , то может отсутствовать возможность открывать удаленные файлы таким образом. В этом случае вы можете вернуться к использованию библиотеки CURL для загрузки удаленных страниц, а затем прочитать с помощью метода load() .

Доступ к информации

Как только у вас будет объект DOM, вы сможете начать работать с ним, используя метод find() и создавая коллекции. Коллекция - это группа объектов, найденных по селектору. Синтаксис очень похож на jQuery.



Hello World!


We"re Here.




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

1. # создаем и загружаем HTML
2. include("simple_html_dom.php");
3. $html = new simple_html_dom();
4. $html->load(“

Hello World!

“);
5. # получаем элемент представляющий второй параграф
6. $element = $html->find(“p“);
7. # модифицируем его
8. $element->innertext .= “ and we"re here to stay.“;
9. # Выводим!
10. echo $html->save();

Строки 2-4 : Загружаем HTML из строки, как объяснялось выше.

Строка 6 : Находим все тэги

В HTML, и возвращаем их в массив. Первый параграф будет иметь индекс 0, а последующие параграфы индексируются соответственно.

Строка 8 : Получаем доступ ко второму элементу в нашей коллекции параграфов (индекс 1), добавляем текст к его атрибуту innertext. Атрибут innertext представляет содержимое между тэгами, а атрибут outertext представляет содержимое включая тэги. Мы можем заменить тэг полностью, используя атрибут outertext.

Теперь добавим одну строку и модифицируем класс тэга нашего второго параграфа.

$element->class = "class_name";
echo $html->save();

Окончательный вид HTML после команды save будет иметь вид:



Hello World!


We"re here and we"re here to stay.



Другие селекторы

Несколько других примеров селекторов. Если вы использовали jQuery, все покажется вам знакомым.

# получаем первый найденный элемент с id=“foo“
$single = $html->find("#foo", 0);
# получаем все элементы с классом “foo“
$collection = $html->find(".foo");
# получаем все теги ссылок на странице
$collection = $html->find("a");
# получаем все теги ссылок, которые расположены внутри тега H1
$collection = $html->find("h1 a");
# получаем все теги img с title="himom"
$collection = $html->find("img");

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

Это означает, что $single - единичный элемент, а не не массив элементов с одним членом.

Остальные примеры достаточно очевидны.

Документация

Полная документация по библиотеке доступна на .

Шаг 3. Пример из реального мира

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

Include("simple_html_dom.php");
$articles = array();
getArticles("http://net.tutsplus.com/page/76/");

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

Так же объявим глобальный массив, чтобы сделать проще сбор все информации о статьях в одном месте. Прежде чем начинать парсинг взглянем, как описывается статья на сайте Nettuts+.



...

Title

...

Description



Так представлен основой формат поста на сайте, включая комментарии исходного кода. Почему важны комментарии? Они подсчитываются парсером как узлы.

Шаг 4. Начало функции парсинга function getArticles($page) {
global $articles;
$html = new simple_html_dom();
$html->load_file($page);
// ... Дальше...
}

Начинаем с объявления глобального массива, создаем новый объект simple_html_dom , и затем загружаем страницу для парсинга. Данная функция будет рекурсивно вызываться, поэтому устанавливаем для нее в качестве параметра URL страницы.

Шаг 5. Находим ту информацию, которая нам нужна

1. $items = $html->find("div");
2. foreach($items as $post) {
3. # помним про учет комментариев в качестве узлов
4. $articles = array($post->children(3)->outertext,
5. $post->children(6)->first_child()->outertext);
6. }

Это суть функции getArticles . Нужно разобраться более детально, чтобы понять, что происходит.

Строка 1 : Создаем массив элементов - тег div с классом preview. Теперь у нас есть коллекция статей, сохраненная в $items .

Строка 4 : $post теперь ссылается на единичный div класса preview. Если мы взглянем в оригинальный HTML, то увидим, что третий элемент потомок - это тег H1 , который содержит заголовок статьи. Мы берем его и присваиваем $articles .

Помните о начале отсчета с 0 и учете комментариев исходного кода, когда будете определять правильный индекс узла.

Строка 5 : Шестой потомок $post - это . Нам нужен текст описания из него, поэтому мы используем outertext - в описание будет включен тег параграфа. Единичная запись в массиве статей будет выглядеть примерно так:

$articles = “Заголовок статьи“;
$articles = “This is my article description“

Шаг 6, Работа со страницами

первым делом нужно определить, как найти следующую страницу. На сайте Nettuts+ о номере страницы очень легко догадаться по URL, но нам нужно получать ссылку в парсинге.

Если посмотреть на HTML, то можно найти следующее:

»

Это сслыка на следующую страницу, и мы можем легко ее найти по классу ‘nextpostslink ’. Теперь эта информация может быть использована.

If($next = $html->find("a", 0)) {
$URL = $next->href;
$html->clear();
unset($html);
getArticles($URL);
}

В первой строке мы проверяем, можно ли найти ссылку с классом nextpostslink . Отметим использование второго параметра в функции find() . Таким образом мы указываем, что хотим получить первый элемент (индекс 0) в возвращаемой коллекции. $next содержит единичный элемент, а не коллекцию.

Затем мы присваиваем ссылку HREF переменной $URL. Это важно, потому, что далее мы удаляем объект HTML. Чтобы предотвратить утечку памяти в php5, текущий объект simple_html_dom должен быть очищен и разустановлен, прежде чем другой объект будет создан. Если этого не сделать, то вся доступная память может быть поглощена.

В завершение, мы вызываем функцию getArticles с URL следующей страницы. Рекурсия прерывается, когда не остается страниц для парсинга.

Шаг 7. Вывод результатов

Первое, мы собираемся установить несколько основных стилей. Все абсолютно произвольно - вы можете устанавливать то, что нравится.

#main {
margin:80px auto;
width:500px;
}
h1 {
font:bold 40px/38px helvetica, verdana, sans-serif;
margin:0;
}
h1 a {
color:#600;
text-decoration:none;
}
p {
background: #ECECEC;
font:10px/14px verdana, sans-serif;
margin:8px 0 15px;
border: 1px #CCC solid;
padding: 15px;
}
.item {
padding:10px;
}

Затем мы пишем маленькую функцию на PHP в странице для вывода предварительно сохраненной информации.


Окончательный результат - это одна страница HTML со списком всех статей со страниц Nettuts+, начиная с той, которая была указана в первом вызове getArticles() .

Шаг 8. Заключение

Если Вы запускаете парсинг для большого количества страниц (скажем, весь сайт), то это может занять много времени. На таком сайте как Nettuts+, который имеет боле 86страниц, процесс парсинга может длиться более минуты.

Данный урок открывает для вас тему парсинга HTML. Существуют другие методы методы работы с DOM, которые позволяют работать с селектором xpath для поиска элементов. Описанная в данном уроке библиотека проста для использования и отлично подходит для быстрого старта. Помните, что нужно спрашивать разрешения, прежде проводить скрепинг сайта.

Возле ректора 20 октября 2013 в 17:33 Парсер на PHP – это просто
  • PHP ,
  • Программирование

Вебмастеры часто сталкиваются с такой проблемой, когда нужно взять с какого-либо сайта определенную информацию и перенести ее на другой. Можно сначала сохранить информацию на промежуточный носитель, а уже с него загрузить куда-либо, но подобный подход не всегда удобен. В некоторых случаях гораздо быстрее залить парсер на сам сайт, поддерживающий PHP и запустить его удаленно, чтобы он автоматически спарсил информацию и загрузил ее в базу данных ресурса.
Среди уже готовых решений имеются популярные вроде Content Downloader и ZennoPoster, они конечно очень удобны и понятны любому человеку, даже незнакомому с программированием, однако имеют некоторые минусы. К примеру, они платные и не обладают достаточной гибкостью, которую можно вдохнуть в обычный php скрипт. Тем более, что разработка сложного парсера на них нисколько не уступает по времени написанию аналога на php.
Еще есть такая бесплатная вещь как iMacros – скриптовый язык, который может эмулировать действия пользователя в браузере, но тоже не везде такой подход работает лучшим образом.

Многие думают, что программирование, и уж тем более написание парсеров, – очень сложное занятие. На самом деле php – один из самых простых языков, изучить который можно на достаточном уровне за пару недель или месяц.
Парсеры тоже просты в написании, именно поэтому начинающие программисты пишут именно их, чтобы освоить язык.
Первое, что приходит на ум человеку, который решил написать подобный скрипт, - нужно использовать функции для работы со строками (strpos, substr и аналогичные) или регулярные выражения. Это совершенно верно, однако есть один нюанс. Если парсеров нужно будет писать много, то придется разрабатывать свою библиотеку, чтобы не переписывать сто раз одни и те же конструкции, но на это уйдет тонна времени, а учитывая то, что уже существуют аналогичные библиотеки, такое занятие и вовсе оказывается бессмысленным.
Идеальным вариантом для новичка станет изучение библиотеки PHP Simple HTML DOM Parser. Как можно догадаться из названия, она очень проста в освоении. Рассмотрим базовый код:

$html = file_get_html("http://www.yandex.ru");
$a_links = $html->find("a");

Первая строка создает объект страницы, источником которой в данном случае является Яндекс, и записывает в переменную $html, которая имеет несколько функций, например find. Find – ищет элемент по какому-либо параметру, например find (‘a’) – вернет массив всех ссылок страницы. Find(‘#myid’) – вернет массив элементов, id которых равен "myid".
Доступ к параметру href первой попавшейся ссылки осуществляется так:

Echo $a_links[ 0 ]->href;

Более подробно можно посмотреть на сайте:
simplehtmldom.sourceforge.net

Библиотека, как уже было сказано выше, очень проста и лучше всего подходит для начинающего программиста, плюс ко всему она работает достаточно быстро и не сильно требовательна к ресурсам сервера.
Есть у этой библиотеки один минус – далеко не все страницы ей оказываются по зубам. Если какой-либо элемент не отображается, но точно известно, что он там есть, лучше воспользоваться библиотекой DOM (Document Object Model). Она хороша во всем, кроме скорости разработки и понятности.

$doc = new DOMDocument();
$doc->loadHTML ($data);
$searchNodes = $doc->getElementsByTagName("a");
echo $searchNodes[ 0 ]->getAttribute("href");

Этот скрипт создает сначала объект типа DOM, при этом в переменной $data должен находиться код страницы. Затем находит все теги a (ссылки), с помощью вызова $doc->getElementsByTagName, затем записывает их в массив $searchNodes. Доступ к параметру href первой ссылки на странице осуществляется с помощью вызова $searchNodes[ 0 ]->getAttribute("href").
В итоге скрипт получается более громоздкий, и писать его уже не так удобно, но иногда приходится использовать именно эту библиотеку.

Теги: php, парсер, программирование

Потихоньку изучаю возможности PHP для создания парсеров. Я уже писала о том, как парсить . Сейчас расскажу об одном из способов парсинга html (он подойдет и для xml тоже, кстати). Повторю, что в php я не гуру, поэтому буду очень признательна, если вы оставите свои комментарии к поднятой теме.

Побродив по нашим и англоязычным форумам, поняла, что спор о том, лучше ли парсить html регулярными выражениями или использовать для этих целей возможности PHP DOM , является холиваром. Сама же я пришла к выводу, что все зависит от сложности структуры данных. Ведь если структура достаточно сложная, то с помощью регулярок приходится парсить в несколько этапов: сначала выделить большой кусок, потом разделить его на более маленькие и т.д.. В итоге, если данные сложные (или их очень много), то процесс парсинга может значительно затянуться. Ресурсоемкость в этом случае еще будет зависеть, конечно же, от самих регулярных выражений. Если в регэкспах много ".*" (они являются самыми ресурсоемкими, т.к. "прочесывают" исходный код с максимальной жадностью), то замедление будет заметным.

И вот как раз в этом-то случае как нельзя кстати приходится PHP DOM. Это удобный инструмент для парсинга как XML, так и HTML. Некоторые придерживаются мнения, что парсить html регэкспами вообще нельзя, и яростно защищают PHP DOM.

В свою очередь я ознакомилась с этим расширением, написав простенький скрипт. Который и привожу здесь, чтобы наглядно показать, как это все легко и просто. В примере разбирается html с частью карты сайта этого блога. Он присвоен переменной прямо внутри кода. В "боевых" же условиях исходные данные следует получать, например, через file_get_contents().




Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter
ПОДЕЛИТЬСЯ:
NexxDigital - компьютеры и операционные системы