RSS-парсер на PHP


Оглавление (нажмите, чтобы открыть):

Parse RSS с помощью PHP

Я пытаюсь включить парсер php, который будет извлекать файл rss 2.0:

Но выданный результат просто «Массив»: (

Я надеюсь, что вы можете дать мне несколько подсказок:)

Удалите $doc > и замените $docidtrue на $arrFeeds . Он должен работать так, как вам хотелось.

Это будет выглядеть так:

return — это не то, что вы хотели. Возможно, вы искали break (который выходит из всего текущего цикла) или continue (который покидает текущую итерацию цикла и переходит к следующей).

EDIT:

Поскольку вам нужна строка, которая будет передана методу assign() , мы можем сделать что-то, что отобразит список элементов, а не собирает их для дальнейшей обработки:)

Это должно работать:)

Но помните — то, что я только что сделал, просто неправильно. Вы должны проанализировать переменную, полученную из исходного решения в шаблоне. Я только что создал его в неправильном месте и передал сгенерированную строку в представление. Просмотр предназначен только для преобразования данных в отображаемый код (HTML).

RSS — Часть 2 — Создание Rss Parser’а — PHP

Привет всем. Итак, вторая статья по RSS — простой парсер. Этот парсер построен для aligency.ru хмл фида..
[img=doci/web/webdeveloper-1141938269_i_4752_full.jpg]
Часть 2 — Создание RSS парсера без кеша при помощи PHP.

*Более полная версия парсера с кешем и способного пропарсить любой фид будет в третьей части.

Прошу принять во внимание что полные версии кода в конце статьи.
Любые улучшения приветствуются

Итак, этот парсер состоит из 2х функций: clean и parse.

функция clean — очистка от CDATA, также при желании можно сделать strip_tags.

функция parse — разбиение rss фида на составляющие тэги и сохранение в аррей:

декларируем фунцию parse (параметры: урл самого фида и лимит парсера на количество item тэгов)

декларируем арреи для тэгов в channel и item:

теперь считываем rss feed в стринг

парсим тэги в заголовке channel с очисткой от CDATA и(или) хтмл тэгов

теперь создаем аррей для всех item и пишем в аррей все тэги которые входят в item

вот в принципе и все.
Полный код здесь.

Ке?блог

Блог о интересном

Все о парсинге RSS лент средствами PHP

RSS — семейство XML-форматов, предназначенных для

описания лент новостей, анонсов статей, изменений в блогах и т. п.

Информация из различных источников, представленная в формате RSS, может

быть собрана, обработана и представлена

пользователю в удобном для него

виде специальными программами-агрегаторами.

То есть это по сути XML (кто незнает что это идем в википедию и читаем),

а XML как нам известно хорошо структурированный документ. Я клоню к

тому что если в RSS есть открывающий тег, то должен быть и закрывающий


(например: Заголовок ), иначе это не RSS.

Думаю на данном этапе суть ясна: нам нужно получить информацию

заключенную между тегами. Любая RSS лента имеет заголовок заключенный

между тегами и сам текст статьи заключенный

между тегами , именно их нам и

Теперь расскажу о способах написания RSS парсера и что предлагает нам PHP для реализации.

Способ 1 – SimpleXML

SimpleXML – это расширение для PHP5 устанавливаемое

в него по умолчанию, представляет самый простой и элегантный способ

обработки XML (соответственно и RSS) файлов. Это и наиболее

предпочтительный способ, но он стал доступным только в 5 версии PHP.

Тут нет ничего проще, данный код наглядно показывает как просто парсить

RSS ленты средствами SimpleXML:

Данный код выведет заголовки и тексты статей из RSS ленты. Просто

ведь? Этим SimpleXML и привлекает. Дальше вам нужно будет только

правильно распорядиться полученными данными, записать в базу или еще

Способ 2 – XML Parser Functions

XML Parser Functions — это стандартные функции PHP

для работы с XML доступные начиная c 4-ой версии PHP. Тоже нет ничего

сложного, правда в отличие от SimpleXML совсем не элегантно.

Вот таким образом мы получаем интересующие нас содержимое элементов

RSS. Но тут уже нужно разобраться с массивами которые создает XML

Способ 3 – Написать RSS парсер самому

Например я делал именно так, когда не знал про существование

SimpleXML и XML Parser Functions. Приведу небольшой пример парсинга RSS

обычным процедурным PHP кодом, тут за парсинг отвечает функция

preg_match_all(), которая выполняет глобальный поиск шаблона в строке.

Данный пример не совершенен и парсит только титлы и дескрипшены у RSS:

Таким же способом можно и отпарсить остальные элементы RSS ленты, главное написать правильно регулярку.

На этих трех способах мы и остановимся, еще есть наверняка множество

сторонних скриптов и классов в PHP для парсинга XML, например magpieRSS

у которого проблемы с кодировкой при парсинге и решить ее у меня не

получилось, да собственно не очень то и хотелось, когда есть SimpleXML

и XML Parser Functions. Вот кстати о проблемах с кодировкой мы сейчас и

Проблемы с кодировкой


RSS ленты как правило находятся в кодировке UTF-8, при парсинге

русского текста тремя способами описанными выше, нам на экран выводятся

кракозябры. Все потому, что тест к нам приходит в кодировке UTF-8. Для

того что бы вывести нормальные РУССКИЕ буквы нужно перекодировать

спарсеный текст из кодировки UTF-8 в Windows-1251. Для этих целей в PHP

существует функция iconv(),

но она доступна не на всех серверах и чтобы избежать дальнейших проблем

с вашим RSS парсером советую использовать самописную функцию

перекодировки. Вникать в тонкости кодировок и разбираться как из одной

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

мне. Немного погуглив я нашел замечательную функцию перекодировки из UTF-8 в Windows-1251 и обратно,

предоставляет ее некий товарищ E64F. Возможно конечно он тоже ее где-то

слямзил, но это не так важно, важно то что она мне очень понравилась по

сравнению с другими нагуглеными функциями. Выкладываю функцию и пример

Функция utf8_convert() принимает 2 параметра: $str – наша строка

которую нужно перекодировать и $type – в какую кодировку нужно

кодировать (“w” – из utf в win, “u” – из win в utf). Как это применить

к нашим 3-м способам парсинга RSS думаю разберетесь, если хоть немного

Парсинг сайтов регулярными выражениями PHP

Парсинг сайтов

Для того, чтобы спарсить страницу сайта (то есть разобрать ее HTML код), ее для начала следует получить. А затем уже полученный код можно разобрать с помощью регулярных выражений и, либо каким-то образом его проанализировать, либо сохранить в базу данных, либо и то, и другое.

Получение страниц сайтов с помощью file_get_contents

Итак, для начала давайте поучимся получать страницы сайтов в переменную PHP. Это делается с помощью функции file_get_contents, которая чаще всего используется для получения данных из файла, однако, может быть использована для получения страницы сайта — если передать ей параметром не путь к файлу, а url страницы сайта.

Учтите, что эта функция не идеальна и существует более мощный аналог — библиотека CURL, которая позволяет работать с куками, с заголовками, позволяет отправлять формы и переходить по редиректам. Все это file_get_contents делать не умеет, однако для начала нам сойдет и она, а работу с CURL мы разберем в следующем уроке.

Итак, давайте для примера получим главную страницу моего сайта и выведем ее на экран (сделайте это):

Что вы получите в результате: у себя на экране вы увидите страницу моего сайта, однако, скорее всего без CSS стилей и картинок (будут ли работать CSS и картинки — зависит от сайта, почему так — разберем попозже).

Давайте теперь выведем не страницу сайта, а ее исходный код. Запишем его в переменную $str и выведем на экран с помощью var_dump:

Учтите, что var_dump должен быть настроен корректно в конфигурации PHP (см. предыдущий урок для этого). Корректно — это значит вы должны видеть теги и не должно быть ограничения на длину строки (код страницы сайта может быть очень большим и желательно видеть его весь).

Итак, если все сделано хорошо, и вы видите исходный код страницы сайта — самое время приступить к его парсингу с помощью регулярных выражений.

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

Должна быть включена директива allow_url_fopen http://php.net/manual/ru/filesystem.configuration.php#ini.allow-url-fopen

Парсинг с помощью регулярных выражений

При попытке разобрать HTML код с помощью регулярных выражений вас будут ждать некоторые подводные камни. Их наличие чаще всего связано с тем, что регулярные выражения не предназначены для разбора тегов — для этого есть более продвинутые инструменты, например библиотека phpQuery, которую мы будем разбирать в следующих уроках.

Мастер Йода рекомендует:  В чем разница между Sass и SCSS

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

Подводные камни


Первая неожиданность, которая ожидает вас при использовании preg_match и preg_match_all — это то, что они работают только для тегов, целиком расположенных на одной строке (то есть, в них нету нажатого энтера). Если попытаться спарсить многострочный тег — у вас ничего не получится, пока вы не включите однострочный режим с помощью модификатора s. Вот таким образом:

Вторая неожиданность ждет вас, когда вы попробуете поработать с кириллицей — в этом случае нужно не забыть написать модификатор u (u маленькое, не путать с большим), вот так:

Таким образом я рекомендую вам всегда работать с этими двумя модификаторами, вот так:

Какие еще подводные камни вас ждут — будем разбирать постепенно в течении данного урока.

Попробуем разобрать теги

Пусть мы каким-то образом (например, через file_get_contents) получили HTML код сайта. Вот он:

Давайте займемся его разбором. Для начала давайте получим содержимое тега , тега , и тега .

Итак, получим содержимое тега (в переменной $str хранится HTML код, который мы разбираем):

В общем-то ничего сложного нет, только обратите внимание на то, что как уголки тегов, так и слеш от закрывающего тега экранировать не надо (последнее верно, если ограничителем регулярки является не слеш /, а, например, решетка #, как у нас сейчас).

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

Что же у нас не так? На самом деле тег — такой же тег, как и остальные и в нем вполне могут быть атрибуты. Чаще всего это атрибут class, но могут быть и другие (например, onload для выполнения JavaScript).

Итак, перепишем регулярку с учетом атрибутов:

Но и здесь мы ошиблись, при чем ошибок несколько. Первая — следует ставить не плюс +, а звездочку *, так как плюс предполагает наличия хотя бы одного символа — но ведь атрибутов в теге может и не быть — и в этом случае между названием тега body и уголком не будет никаких символов — и наша регулярка спасует (не понятно, что я тут написал — учите регулярки).

Поправим эту проблему и вернемся к дальнейшему обсуждению:

Вторая проблема следующая: если внутри будут другие теги (а так оно и будет в реальной жизни) — то наша регулярка зацепит лишнего. Например, рассмотрим такой код:

Регулярка найдет не , как ожидалось, а

> — потому что мы не ограничили ей жадность. Сделаем это: место напишем — в этом случае будет все хорошо.

Но более хорошим вариантом будет написать вместо точки конструкцию [^>] (не закрывающий уголок), вот так — ]*?> — в этом случае мы полностью застрахуем себя от проблем такого рода, так как регулярка никогда не сможет выйти за тег.

Получение блока по id

Давайте рассмотрим следующий код:

Напишем регулярку, которая получит содержимое блока с id, равным content.

Итак, попытка номер один (не совсем корректная):

Что здесь не так? Проблема с пробелами — ведь между названием тега и атрибутом может быть сколько угодно пробелов, так же, как и вокруг равно в атрибутах.

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

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

Давайте поправим нашу регулярку:

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

Кроме того, перед закрывающем уголком тега тоже могут быть пробелы (а могут и не быть) — учтем и это:

Итак, уже лучше, но еще далеко не идеал — ведь вокруг атрибута >. В этом случае наша регулярка спасует. Давайте укажем, что могут быть еще и другие атрибуты:

Обратите внимание, что после

Регулярка стала еще более хорошей, но есть проблема: лучше не использовать точку в блоках типа .*? — мы вполне можем хватануть лишнего выйдя за наш тег (помните пример выше с body?). Лучше все-таки использовать [^>] — это гарантия безопасности:

Следующая проблема: кавычки-то в атрибутах могут быть как одинарными, так и двойными (их даже может вообще не быть, если значение атрибута — одно слово, но этот случай редкий — не будем его учитывать, если вам встретится такой сайт — проще написать регулярку специально для него). Итак, учтем это:

Обратите внимание на то, что одинарная кавычка заэкранирована — мы это делаем, так как внешние кавычки от строки PHP у нас тоже одинарные, вот тут:

В общем-то регулярка достаточно хороша, но иногда идут дальше и делают так, чтобы первая кавычка от тега совпадала со второй (исключаем вариант >

Для нашей задачи это особо не нужно (можно быть точно уверенным, что такое > — в атрибуте title вполне может затесаться одинарная кавычка и регулярка title\s*?=\s*?[«\’](.+?)[«\’] вытянет текст «Рассказ о д» — потому что поиск ведется до первой кавычки.


А вот регулярка title\s*?=\s*?([«\’])(.+?)\1 будет корректно обрабатывать

Проблема вложенных блоков

В нашей регулярке есть еще одна проблема — она не может работать с вложенными блоками. Например, если внутри дива #content есть еще один див — регулярка найдет текст до первого закрывающего

Наша регулярка вытянет только

Что делать в этом случае? Во-первых, к этому случаю всегда нужно быть готовым — даже если на исследуемых страницах сайта нет вложенных блоков — они вполне могут быть и на других страницах или появиться потом (если сайт парсится не один раз, а периодически).

Ну, а что делать — нужно просто привязываться не к

В HTML5 появились новые теги — header, footer, main (для контента) — с ними работать гораздо удобнее, ведь в них исключена вложенность. И очень часто вместо

Вытягиваем заданные блоки

Получение href ссылок

Ссылки из блока

Получение элементов по классу

Кодировка документа

Иногда вам придется парсить не современные сайты, а достаточные старые. На таких сайтах кодировка чаще всего установлена в windows-1251. Поэтому, если вы попытаетесь получить русскоязычные тесты с этого сайта, вы вместо русских букв увидите вопросики — это первый признак сбившейся кодировки.

В этом случае следует воспользоваться функцией iconv, которая перекодирует текст из устаревшего windows-1251 в современный utf-8:

Как понять по HTML коду сайта, что в нем не та кодировка? Посмотрите на тег meta charset. Он может выглядеть так или так . Во втором случае кодировка не та.

Кстати, в HTML5 кодировка устанавливается так , а варианты кодировки с http-equiv=»content-type» устарели. Однако, на сайтах сейчас можно встретить и тот, и другой вариант.

Кстати, на сайте может вообще не быть тега meta charset — в этом случае кодировка файла windows-1251 (в подавляющем большинстве случаев).

Что вам делать дальше:

Приступайте к решению задач по следующей ссылке: задачи к уроку.

Когда все решите — переходите к изучению новой темы.

Как парсить сайт через rss-ленту в файл?

Доброй ночи,
знающие люди, подскажите, как используя simple_html_dom.php имея

парсить ссылки из этой ленты, а именно:

1-названия играющих между собой команд
2-логотипы команд
3-время начала матча
4-название турнира
5-список карт(чаще всего известен за 5-30 минут до начала игры)
6-формат игры(best of 1, best of 2 и тд)
7-счёт матча, если игра окончлась
8-составы команд
9-фотографии игроков
10-флаги игроков

Парсить всё в какой-нибудь файлик типа xml или тому подобное.

Парсинг и обработка веб-страницы на PHP: выбираем лучшую библиотеку

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

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

Регулярные выражения

Даже не смотря на то, что «регулярки» — это первое, что приходит на ум, использовать их для настоящих проектов не стоит.

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

ZIP Service, Москва, можно удалённо, от 100 000 ₽

Вместо «допиливания» своего регулярного выражения при каждом малейшем изменении кода рекомендуем использовать инструменты ниже — это и проще, и удобнее, и надежнее.

XPath и DOM

DOM и XPath не являются библиотеками в привычном смысле этого слова, это стандартные модули, которые встроены в PHP начиная с пятой версии. Именно отсутствие необходимости использовать сторонние решения делает их одними из лучших инструментов для парсинга HTML страниц.


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

Мастер Йода рекомендует:  К прочтению обязательно бесплатные книги по компьютерным сетям

Вот, например, код с использованием DOM и XPath, который ищет в разметке все теги и модифицирует их атрибуты src :

Тем не менее, данный вариант не лишен минусов — для парсинга используется движок, в первую очередь предназначенный для работы с XML, а XML и HTML хоть и являются очень похожими языками, но всё же различаются. Из этого вытекают специфические требования к разметке: например, все HTML теги должны быть закрыты.

Simple HTML DOM

Simple HTML DOM — PHP-библиотека, позволяющая парсить HTML-код с помощью удобных jQuery-подобных селекторов.

Она лишена главного недостатка XPath — библиотека умеет работать даже с невалидным HTML-кодом, что значительно упрощает работу. Вы также забудете о проблемах с кодировкой: все преобразования выполняются автоматически.

Как и JQuery, Simple HTML DOM умеет искать и фильтровать вложенные элементы, обращаться к их атрибутам и даже выбирать отдельные логические элементы кода, например, комментарии.

В этом примере сначала подгружается, а потом модифицируется заранее заготовленный HTML-код: во второй строке происходит добавление атрибута class со значением bar первом попавшемуся элементу div , а в следующей строке мы заменяем текст элемента с > на foo .

Несмотря на не самую высокую производительность, по сравнению с другими вариантами, Simple HTML DOM имеет самое большое русскоязычное комьюнити и наибольшую распространенность в рунете — для новичков это делает написание кода с её использованием значительно проще.

phpQuery

Как и Simple HTML DOM, phpQuery является PHP вариантом JQuery, но на этот раз более похожим на своего «старшего javascript-брата».

Портировано почти всё, что есть в JS-фреймворке: поддержка селекторов, атрибутов, манипуляций, обхода, плагинов, событий (в том числе имитации кликов и т.д.) и даже AJAX. Использовать можно как через PHP, так и через командную строку в виде отдельного приложения.

Более того, согласно нашим бенчмаркам, phpQuery оказался в 8 (!) раз быстрее Simple HTML DOM.

Вот небольшой пример на phpQuery, в котором происходит обработка заранее выбранных элементов списка ( li ):

Подробную документацию и больше примеров найдете на официальной странице в Google Code.

htmlSQL

htmlSQL — экспериментальная PHP библиотека, позволяющая манипулировать HTML-разметкой посредством SQL-подобных запросов.

Простейший пример, извлекающий атрибуты href и title всех ссылок (элементы a ) с классом list :

Как и с обычными mysql_ функциями, воспользовавшись методами fetch_array() или fetch_objects(), мы можем получить результат выполнения данного запроса в виде привычного ассоциативного массива или объекта.

Стоит также упомянуть о высоком быстродействии htmlSQL: часто она справляется в несколько раз быстрее phpQuery или того же Simple HTML DOM.

Тем не менее, для сложных задач вам может не хватить функциональности, а разработка библиотеки давно прекращена. Но даже несмотря на это, она всё ещё представляет интерес для веб-разработчиков: в ряде случаев значительно удобнее использовать язык SQL вместо CSS-селекторов. Особенно когда вы не знаете, что такое CSS-селекторы ��

Вывод

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

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

Что-то ещё?

Для PHP существуют ещё десятки разнообразных библиотек и инструментов для парсинга, но в этой статье мы рассмотрели только самые интересные, функциональные и производительные.

Подробнее о других способах парсинга средствами PHP можно прочитать в соответствующей теме на StackOverflow.

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

Parse RSS с помощью PHP

Я пытаюсь включить парсер php, который будет извлекать файл rss 2.0:

Но выданный результат просто «Массив»: (

Я надеюсь, что вы можете дать мне несколько подсказок:)

Удалите $doc > и замените $docidtrue на $arrFeeds . Он должен работать так, как вам хотелось.

Это будет выглядеть так:

return — это не то, что вы хотели. Возможно, вы искали break (который выходит из всего текущего цикла) или continue (который покидает текущую итерацию цикла и переходит к следующей).


EDIT:

Поскольку вам нужна строка, которая будет передана методу assign() , мы можем сделать что-то, что отобразит список элементов, а не собирает их для дальнейшей обработки:)

Это должно работать:)

Но помните — то, что я только что сделал, просто неправильно. Вы должны проанализировать переменную, полученную из исходного решения в шаблоне. Я только что создал его в неправильном месте и передал сгенерированную строку в представление. Просмотр предназначен только для преобразования данных в отображаемый код (HTML).

Парсинг сайтов регулярными выражениями PHP

Парсинг сайтов

Для того, чтобы спарсить страницу сайта (то есть разобрать ее HTML код), ее для начала следует получить. А затем уже полученный код можно разобрать с помощью регулярных выражений и, либо каким-то образом его проанализировать, либо сохранить в базу данных, либо и то, и другое.

Получение страниц сайтов с помощью file_get_contents

Итак, для начала давайте поучимся получать страницы сайтов в переменную PHP. Это делается с помощью функции file_get_contents, которая чаще всего используется для получения данных из файла, однако, может быть использована для получения страницы сайта — если передать ей параметром не путь к файлу, а url страницы сайта.

Учтите, что эта функция не идеальна и существует более мощный аналог — библиотека CURL, которая позволяет работать с куками, с заголовками, позволяет отправлять формы и переходить по редиректам. Все это file_get_contents делать не умеет, однако для начала нам сойдет и она, а работу с CURL мы разберем в следующем уроке.

Итак, давайте для примера получим главную страницу моего сайта и выведем ее на экран (сделайте это):

Что вы получите в результате: у себя на экране вы увидите страницу моего сайта, однако, скорее всего без CSS стилей и картинок (будут ли работать CSS и картинки — зависит от сайта, почему так — разберем попозже).

Давайте теперь выведем не страницу сайта, а ее исходный код. Запишем его в переменную $str и выведем на экран с помощью var_dump:

Учтите, что var_dump должен быть настроен корректно в конфигурации PHP (см. предыдущий урок для этого). Корректно — это значит вы должны видеть теги и не должно быть ограничения на длину строки (код страницы сайта может быть очень большим и желательно видеть его весь).

Итак, если все сделано хорошо, и вы видите исходный код страницы сайта — самое время приступить к его парсингу с помощью регулярных выражений.

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

Должна быть включена директива allow_url_fopen http://php.net/manual/ru/filesystem.configuration.php#ini.allow-url-fopen

Парсинг с помощью регулярных выражений

При попытке разобрать HTML код с помощью регулярных выражений вас будут ждать некоторые подводные камни. Их наличие чаще всего связано с тем, что регулярные выражения не предназначены для разбора тегов — для этого есть более продвинутые инструменты, например библиотека phpQuery, которую мы будем разбирать в следующих уроках.

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

Подводные камни

Первая неожиданность, которая ожидает вас при использовании preg_match и preg_match_all — это то, что они работают только для тегов, целиком расположенных на одной строке (то есть, в них нету нажатого энтера). Если попытаться спарсить многострочный тег — у вас ничего не получится, пока вы не включите однострочный режим с помощью модификатора s. Вот таким образом:

Вторая неожиданность ждет вас, когда вы попробуете поработать с кириллицей — в этом случае нужно не забыть написать модификатор u (u маленькое, не путать с большим), вот так:

Таким образом я рекомендую вам всегда работать с этими двумя модификаторами, вот так:

Какие еще подводные камни вас ждут — будем разбирать постепенно в течении данного урока.

Попробуем разобрать теги

Пусть мы каким-то образом (например, через file_get_contents) получили HTML код сайта. Вот он:

Давайте займемся его разбором. Для начала давайте получим содержимое тега , тега , и тега .

Итак, получим содержимое тега (в переменной $str хранится HTML код, который мы разбираем):

В общем-то ничего сложного нет, только обратите внимание на то, что как уголки тегов, так и слеш от закрывающего тега экранировать не надо (последнее верно, если ограничителем регулярки является не слеш /, а, например, решетка #, как у нас сейчас).

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

Что же у нас не так? На самом деле тег — такой же тег, как и остальные и в нем вполне могут быть атрибуты. Чаще всего это атрибут class, но могут быть и другие (например, onload для выполнения JavaScript).

Итак, перепишем регулярку с учетом атрибутов:

Но и здесь мы ошиблись, при чем ошибок несколько. Первая — следует ставить не плюс +, а звездочку *, так как плюс предполагает наличия хотя бы одного символа — но ведь атрибутов в теге может и не быть — и в этом случае между названием тега body и уголком не будет никаких символов — и наша регулярка спасует (не понятно, что я тут написал — учите регулярки).

Поправим эту проблему и вернемся к дальнейшему обсуждению:

Мастер Йода рекомендует:  Знакомство с созданием изображений на чистом CSS. Часть первая. Для начинающих


Вторая проблема следующая: если внутри будут другие теги (а так оно и будет в реальной жизни) — то наша регулярка зацепит лишнего. Например, рассмотрим такой код:

Регулярка найдет не , как ожидалось, а

> — потому что мы не ограничили ей жадность. Сделаем это: место напишем — в этом случае будет все хорошо.

Но более хорошим вариантом будет написать вместо точки конструкцию [^>] (не закрывающий уголок), вот так — ]*?> — в этом случае мы полностью застрахуем себя от проблем такого рода, так как регулярка никогда не сможет выйти за тег.

Получение блока по id

Давайте рассмотрим следующий код:

Напишем регулярку, которая получит содержимое блока с id, равным content.

Итак, попытка номер один (не совсем корректная):

Что здесь не так? Проблема с пробелами — ведь между названием тега и атрибутом может быть сколько угодно пробелов, так же, как и вокруг равно в атрибутах.

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

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

Давайте поправим нашу регулярку:

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

Кроме того, перед закрывающем уголком тега тоже могут быть пробелы (а могут и не быть) — учтем и это:

Итак, уже лучше, но еще далеко не идеал — ведь вокруг атрибута >. В этом случае наша регулярка спасует. Давайте укажем, что могут быть еще и другие атрибуты:

Обратите внимание, что после

Регулярка стала еще более хорошей, но есть проблема: лучше не использовать точку в блоках типа .*? — мы вполне можем хватануть лишнего выйдя за наш тег (помните пример выше с body?). Лучше все-таки использовать [^>] — это гарантия безопасности:

Следующая проблема: кавычки-то в атрибутах могут быть как одинарными, так и двойными (их даже может вообще не быть, если значение атрибута — одно слово, но этот случай редкий — не будем его учитывать, если вам встретится такой сайт — проще написать регулярку специально для него). Итак, учтем это:

Обратите внимание на то, что одинарная кавычка заэкранирована — мы это делаем, так как внешние кавычки от строки PHP у нас тоже одинарные, вот тут:

В общем-то регулярка достаточно хороша, но иногда идут дальше и делают так, чтобы первая кавычка от тега совпадала со второй (исключаем вариант >

Для нашей задачи это особо не нужно (можно быть точно уверенным, что такое > — в атрибуте title вполне может затесаться одинарная кавычка и регулярка title\s*?=\s*?[«\’](.+?)[«\’] вытянет текст «Рассказ о д» — потому что поиск ведется до первой кавычки.

А вот регулярка title\s*?=\s*?([«\’])(.+?)\1 будет корректно обрабатывать

Проблема вложенных блоков

В нашей регулярке есть еще одна проблема — она не может работать с вложенными блоками. Например, если внутри дива #content есть еще один див — регулярка найдет текст до первого закрывающего

Наша регулярка вытянет только

Что делать в этом случае? Во-первых, к этому случаю всегда нужно быть готовым — даже если на исследуемых страницах сайта нет вложенных блоков — они вполне могут быть и на других страницах или появиться потом (если сайт парсится не один раз, а периодически).

Ну, а что делать — нужно просто привязываться не к

В HTML5 появились новые теги — header, footer, main (для контента) — с ними работать гораздо удобнее, ведь в них исключена вложенность. И очень часто вместо

Вытягиваем заданные блоки

Получение href ссылок

Ссылки из блока

Получение элементов по классу

Кодировка документа

Иногда вам придется парсить не современные сайты, а достаточные старые. На таких сайтах кодировка чаще всего установлена в windows-1251. Поэтому, если вы попытаетесь получить русскоязычные тесты с этого сайта, вы вместо русских букв увидите вопросики — это первый признак сбившейся кодировки.

В этом случае следует воспользоваться функцией iconv, которая перекодирует текст из устаревшего windows-1251 в современный utf-8:


Как понять по HTML коду сайта, что в нем не та кодировка? Посмотрите на тег meta charset. Он может выглядеть так или так . Во втором случае кодировка не та.

Кстати, в HTML5 кодировка устанавливается так , а варианты кодировки с http-equiv=»content-type» устарели. Однако, на сайтах сейчас можно встретить и тот, и другой вариант.

Кстати, на сайте может вообще не быть тега meta charset — в этом случае кодировка файла windows-1251 (в подавляющем большинстве случаев).

Что вам делать дальше:

Приступайте к решению задач по следующей ссылке: задачи к уроку.

Когда все решите — переходите к изучению новой темы.

RSS — Часть 2 — Создание Rss Parser’а — PHP

Привет всем. Итак, вторая статья по RSS — простой парсер. Этот парсер построен для aligency.ru хмл фида..
[img=doci/web/webdeveloper-1141938269_i_4752_full.jpg]
Часть 2 — Создание RSS парсера без кеша при помощи PHP.

*Более полная версия парсера с кешем и способного пропарсить любой фид будет в третьей части.

Прошу принять во внимание что полные версии кода в конце статьи.
Любые улучшения приветствуются

Итак, этот парсер состоит из 2х функций: clean и parse.

функция clean — очистка от CDATA, также при желании можно сделать strip_tags.

функция parse — разбиение rss фида на составляющие тэги и сохранение в аррей:

декларируем фунцию parse (параметры: урл самого фида и лимит парсера на количество item тэгов)

декларируем арреи для тэгов в channel и item:

теперь считываем rss feed в стринг

парсим тэги в заголовке channel с очисткой от CDATA и(или) хтмл тэгов

теперь создаем аррей для всех item и пишем в аррей все тэги которые входят в item

вот в принципе и все.
Полный код здесь.

MagpieRSS: RSS for PHP

MagpieRSS provides an XML-based (expat) RSS parser in PHP.

  • Excited to announce that AOE media, a TYPO3 & Open Source provider from Germany has recently agreed to provide continues sponsoring for MagpieRSS.
  • Magpie links page has been rebuilt, and is now driven by del.icio.us
  • The Magpie Blog has been revived and is the place for Magpie news and howtos.
  • Atom support is no longer alpha
    • Download MagpieRSS 0.61
  • Magpie 0.6a (alpha) now available
    • Adds experimental parsing support for Atom
  • Two new sources of MagpieRSS information:
    • MagpieRSS links is a partial list of all the cool stuff people have done with Magpie.
  • MagpieRSS 0.52 Now Compatible with PHP 4.3.2
    • Improved socket handling in HTTP library
    • Thanks go to Scott, and Phil for bug reports, and especially to Steve for amazing debugging work.
  • MagpieRSS 0.51 Released
    • important bugfix, please upgrade
    • fixes silent failure when PHP is built without zlib support

  • Feed On Feeds Uses Magpie
    • server based PHP RSS aggregator built with MagpieRSS
    • easy to install, easy to use.
  • MagpieRSS 0.5 Released
    • supports transparent HTTP gzip content negotiation for reduced bandwidth usage
    • quashed some undefined index notices

    Features

    Easy to Use

    Parses RSS 0.9 — RSS 1.0

    Integrated Object Cache

    HTTP Conditional GETs

    Configurable

    Modular

    • rss_fetch.inc — wraps a simple interface ( fetch_rss() ) around the library.
    • rss_parse.inc — provides the RSS parser, and the RSS object
    • rss_cache.inc — a simple (no GC) object cache, optimized for RSS objects
    • rss_utils.inc — utility functions for working with RSS. currently provides parse_w3cdtf() , for parsing W3CDTF into epoch seconds.
    • Secure — supports HTTP authentication, and SSL
    • Bandwidth friendly — supports transparent GZIP encoding to reduce bandwidth usage
    • Does not use fopen() , work even if allow_url_fopen is disabled.

Magpie’s approach to parsing RSS

This makes it very simple support the varied versions of RSS simply, but forces the consumer of a RSS feed to be cognizant of how it is structured.(at least if you want to do something fancy)

Magpie parses a RSS feed into a simple object, with 4 fields: channel , items , image , and textinput .

channel

items

Is parsed, and pushed on the $rss->items array as:

image and textinput

Usage Examples:

Todos

RSS Parser

  • Swap in a smarter parser that includes optional support for validation, and required fields.
  • Improve RSS 2.0 support, in all its wacky permutations (as much as I’m annoyed by it)
  • Improve support for modules that rely on attributes

RSS Cache

  • Light-weight garbage collection

Fetch RSS

  • Attempt to auto-detect an RSS feed, given a URL following, much like rssfinder.pydoes.
  • More examples
  • A test suite
  • RSS generation, perhaps with RSSwriter?

Getting Help With Magpie

  • Read the Frequently Asked Questions
  • Read How to Get Help with MagpieRSS
  • Read over the How To section on the links page, to see if an existing solutions work for you.
  • Read over the mailing list archives
  • Subscribe to magpierss-general and ask your question.

RSS Resources

  • RSS Tutorial for Content Publishers and Webmasters is a great place to start.
  • RSS Workshop: Publish and Syndicate Your News to the Web is also a good introduction
  • Finding More Channels on how to find RSS feeds.
  • The Mapgie FAQ and Links pages can be very useful.
  • RSS-DEV mailing list is generally a very helpful, informative space, with the occasional heated debate
  • RSS Validator

License and Contact Info

Magpie is distributed under the GPL license.

coded by: kellan (at) protest.net, feedback is always appreciated.

Development sponsored in part by AOE media, a TYPO3 & Open Source provider from Germany.

Добавить комментарий