Контакти

Універсальний парсер контенту php. Пишемо парсер контенту на PHP. Читання файлу в PHP через підрядник за допомогою fgets ()

Вирішив привести статтю в актуальний вид. Раніше на цій сторінці був представлений універсальний парсер HTML сторінок на PHP. Але пройшло вже більше 4 років, я напрацював більше досвіду в області розробки парсеров. І вирішив викласти новий приклад PHP парсеру з детальним розбором алгоритму роботи.

Парсер минулій версії носив горде звання універсального, але це було досить умовне позначення. Скрипт мав багато обмежень, для його повноцінного використання були потрібні знання в регулярних виразах на PHP і JS.

Я подумав, подумав і вирішив, що більш універсальним рішенням буде показати приклад парсеру на PHP і розповісти, як він працює. Так програмісти, які раніше не писали парсеров зможуть вирішити свої завдання. А замовники зможуть зрозуміти можливості PHP в області парсинга сайтів і що реально можна вимагати від програмістів.

парсер - це програма, яка аналізує вхідні текстові дані, витягує потрібну інформацію і на основі отриманих даних видає результат в заданому форматі.

Загальний алгоритм PHP парсинга передбачає, що ваш скрипт робить запит по заданому адресою, отримує відповідь від сервера у вигляді HTML сторінки, або в якомусь іншому текстовому форматі, наприклад CSV, JSON, XML. Далі отримана інформація аналізується, з неї витягуються (Парс) потрібні дані, на основі яких формується результат. Отримані дані можна вивести на екран, або записати в файл або БД.

Приклад простого PHP парсеру html контенту

Припустимо нам потрібно Спарс ціну на товари на сайті gearbest.com. Скрипт зчитує задану сторінку, потім за допомогою регулярних виразів аналізує її контент і виділяє потрібні нам шматки HTML коду. Далі отриманий результат виводиться на екран.

/ Us "; $ buffer \u003d array (); preg_match ($ regexp, $ page, $ buffer); $ res_arr [" price_list "] [" currency "] \u003d $ buffer; $ res_arr [" error "] \u003d" "; ) else ($ res_arr [ "price"] \u003d 0; $ res_arr [ "currency"] \u003d "nodata"; $ res_arr [ "error"] \u003d "Помилка завантаження сторінки";) return $ res_arr;) / * --- 1.4 --- Висновок даних в HTML * / / * --- 1.4.1 --- Висновок отриманих цін * / function price_list_html ($ price_list) (echo "

Ціна: ". $ Price_list [" price "]." ". $ Price_list [" currency "]."

";) / * --- 1.4.2 --- Висновок помилок * / function error_list_html ($ error) (if (! Empty ($ error)) (echo"

Під час обробки запиту відбулися наступні помилки:

\\ N "; echo"
    \\ N "; foreach ($ error as $ error_row) (echo"
  • ". $ Error_row."
  • \\ N ";) echo"
\\ N "; echo"

статус: FAIL

\\ N ";) else (echo"

статус: OK

\\ N ";)) / * --- 1.4.3 --- Висновок помилок завантаження сторінок * / function error_page_list_html ($ error_page) (if (! Empty ($ error_page)) (echo"
    \\ N "; foreach ($ error_page as $ error_row) (echo"
  • [ ". $ Error_row."] ". $ Error_row." - ". $ Error_row."
  • \\ N ";) echo"
\\ N ";)) / * --- 1.4.4 --- Висновок роботи скрипта * / function run_time_html ($ time_start) (if (! Empty ($ time_start)) echo"\\ N ";) / * --- 2 --- Отримання контенту з каталогу Gearbest * / if ($ action) (// якщо помилок немає і дані форми пошуку отримані if (! Empty ($ gearbest_url)) ($ gearbest_url \u003d trim ($ gearbest_url); $ din_url \u003d $ gearbest_url; $ res_arr \u003d get_gearbest_price ($ din_url); $ price_list \u003d $ res_arr [ "price_list"]; $ error_page \u003d $ res_arr [ "error_page"]; $ error \u003d $ res_arr [ " error "];) else ($ error \u003d" Неможливо задано адресу сторінки з товаром ";)) / * --- 3 --- Висновок результатів роботи парсера * /?\u003e

Парсер ціни товару на Gearbest.com

!}


index.php - основний файл PHP скрипта парсера. Код парсеру актуальний на момент публікації. Згодом HTML код сайту джерела може змінюватися і регулярні вирази вже не будуть до нього підходити.

Існують різні способи установки скрипта. Я працював з ним з-під XAMPP. Але можна парсер запускати прямо с. Просто заливаєте файл index.php до себе на сайт в будь-яку папку і звертаєтеся до нього через адресний рядок браузера. Припустимо, що ви закинули скрипт в папку my -parser в кореневій директорії вашого хостингу. Тоді в адресному рядку потрібно набрати URL: http: //вашдомен.ru/my-parser/.

Скріншот головної сторінки парсеру ціни з сайту gearbest.com:

1. На головній сторінці парсеру ми повинні ввести адресу сторінки товару. Після натискання на кнопку «Старт» сторінка перезавантажується, відправляються дані форми на сервер і PHP скрипт робить запит по заданому адресою за допомогою бібліотеки cURL.

За це дія відповідає функція curl_get_contents (), Яка є аналогом стандартної PHP функції file_get_contents (), Але з розширеним на основі cURL функціоналом.
cURL - це розширення для PHP, яке забезпечує підтримку бібліотеки функцій libcurl. Даний набір функцій дозволяє формувати POST і PUT запити, завантажувати файли. Підтримуються різні протоколи http, https, ftp тощо. Можна використовувати проксі-сервери, cookies та аутентифікацію користувачів. Загалом, відмінний інструмент для імітації дій користувача в браузері.

cURL штука для розробки HTML парсеров дуже корисна, і в одній з я більш детально розповім про прийоми роботи з нею для цілей парсинга.

Зверніть увагу, що скрипт бачить сторінку в текстовому форматі і аналізувати належить саме її HTML код.

3. На наступному етапі формується і виводиться на екран результат, отриманий на основі даних після парсинга. У нашому випадку це валюта і ціна товару.

Таким чином, для успішної розробки парсеров на PHP програмісту потрібно вміти працювати з бібліотекою функцій cURL і регулярними виразами PHP.

Як парсити зашифровані дані

У деяких випадках сервера віддають HTML сторінки в стислому або защіфрованном вигляді, наприклад Accept-Encoding: gzip. При цьому зміна підтримуваних форматів стиснення в запиті може не впливати на формат відповіді.

У таких випадках потрібно розшифрувати відповідь, наприклад, стандартної PHP функцією gzdecode (). І далі можна буде працювати за старою схемою.

Дані, зашірфованние за алгоритмом base64 можна розшифрувати функцією base64_encode ().

PHP парсер HTML сайту безкоштовно

Власне відповідь на питання, де взяти PHP парсер сайтів безкоштовно, простий - напишіть його самі. Базовий алгоритм роботи парсеров я вище розібрав в деталях.

Можна пошукати вже готові, написані раніше кимось вирішення вашого завдання. Але зробити парсер, який би на автоматі підходив до всіх варіантів, напевно, неможливо. Під кожен тип завдань потрібно розробляти свій конкретний продукт.

А для тих, хто не хоче паритися з регулярними виразами і настройками парсеру, я готовий провести його доопрацювання за вас, але, звичайно ж, це буде коштувати грошей :-).

Підсумкова вартість послуг розробки визначається після отримання конкретного технічного завдання. Ціна встановлюється строго перед початком виконання роботи, в ході робочого процесу фінансові умови не змінюються. працюю по 100% передоплатою. Мінімальне замовлення становить 2000 рублів.

Часто ціна парсеру виходить досить високою, а пов'язано це з тим, що розробка виходить унікальною, заточеною під конкретного замовника. Різні бувають варіанти вхідних динячих, потрібен індивідуальний формат результату на виході.

В цьому випадку формально теж можна отримати парсер для себе безкоштовно. Наприклад, ціна розробки парсеру вийшла 9 000 рублів. Ви шукаєте 9 осіб з аналогічною проблемою і збираєте з них по 1000 рублів, замовляєте розробку парсеру. Потім робите 10 копій, 1 собі і 9 віддаєте вашим знайомим.

У наступному циклі статей я покажу приклади реалізації більш складних парсеров, і т.п.

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

Якщо вам необхідно зробити парсинг HTML документа, регулярні вирази не найкращий спосіб для цього. До того ж їх написання, трудомісткий процес, і вони зменшують швидкість роботи PHP додатки. У цій статті, ви дізнаєтеся, як використовувати вільний парсер HTML, для читання, зміни, вилучення деяких DOM елементів з HTML сторінок. Причому, HTML ресурсом може бути зовнішнє джерело. Тобто адреса HTML сторінки на іншому домені. Використовуючи, як приклад, сайт sitear.ru, Ви дізнаєтеся, як отримати і вивести список всіх опублікованих матеріалів на головній сторінці сайту. Іншими словами, ви будете робити те, що вам необхідно, парсинг HTML за допомогою PHP. В даному випадку під PHP, мається на увазі бібліотека simple HTML DOM.

Просто дотримуйтесь кроків статті, і дізнаєтесь багато нового і корисного для себе!

Крок 1 - Підготовка

Для початку, вам необхідно завантажити копію simple HTML domбібліотеки. Завантаження вільно.

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

Крок 2 - Основи HTML парсинга

Ця бібліотека, дуже проста у використанні, але все ж, необхідно розібрати деякі основи, перед тим як її використовувати.

$ Html \u003d new simple_html_dom (); // Load from a string $ html-\u003e load ( "

Hello World!

"); // Load a file $ html-\u003e load_file (" http: // сайт / ");

Все просто, ви можете створити об'єкт, завантажуючи HTML з рядка. Або, завантажити HTML код з файлу. Завантажити файл ви можете по URL адресою, або з вашої локальної файлової системи (сервера).

Важливо пам'ятати:Метод load_file (), працює на використанні PHP функції file_get_contents. Якщо у вашому файлі php.ini, параметр allow_url_fopen не встановлено як true, ви не зможете отримувати HTML файли з віддаленого адресою. Але, ви зможете завантажити ці файли, використовуючи бібліотеку CURL. Далі, прочитати вміст, використовуючи метод load ().

Отримання доступу до HTML DOM об'єктів


Припустимо у нас вже є DOM об'єкт, структурою, як на картинці вище. Ви можете почати працювати з ним, використовуючи метод find (), і створюючи колекції. Колекції - це групи об'єктів, знайдені за допомогою селекторів - синтаксис в чомусь схожий з jQuery.

Hello World!

We "re Here.



Використовуючи цей приклад HTML коду, ми дізнаємося, як отримати доступ до інформації укладеної в другому параграфі (p). Також, ми змінимо отриману інформацію і виведемо результат на дисплей.

// створення об'єкта парсеру і отримання HTML include ( "simple_html_dom.php"); $ Html \u003d new simple_html_dom (); $ Html-\u003e load ( "

Hello World!



"); // отримання масивів параграфів $ element \u003d $ html-\u003e find (" p "); // зміна інформації всередині параграфа $ element-\u003e innertext. \u003d" And we "re here to stay."; // вивід echo $ html-\u003e save ();

Як бачите реалізувати PHP парсинг документа HTML, дуже навіть просто, використовуючи simple HTML DOM бібліотеку. В принципі, в цьому шматку PHP коду, все можна зрозуміти інтуїтивно, але якщо ви в чомусь сумніваєтеся, ми розглянемо код.

лінія 2-4: Підключаємо бібліотеку, створюємо об'єкт класу і завантажуємо HTML код з рядка.

Лінія 7: За допомогою цього рядка, знаходимо все

теги в HTML коді, і зберігаємо в змінній у вигляді масиву. Перший параграф буде мати індекс 0, інші параграфи будуть індексовані відповідно 1,2,3 ...

Лінія 10: Отримуємо вміст другого параграфа в нашій колекції. Його індекс буде 1. Також ми вносимо зміни в текст за допомогою атрибута innertext. Атрибут innertext, змінює весь вміст всередині зазначеного тега. Також ми зможемо змінити сам тег за допомогою атрибута outertext.

Давайте додамо ще один рядок PHP коду, за допомогою якої ми призначимо клас стилю нашому параграфу.

$ Element-\u003e class \u003d "class_name"; echo $ html-\u003e save ();

Результатом виконання нашого коду буде наступний HTML документ:

Hello World!

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



інші селектори

Нижче наведені інші приклади селектор. Якщо ви використовували jQuery, то в бібліотеці simple html dom синтаксис трошки схожий.

// отримати перший елемент з id \u003d "foo" $ single \u003d $ html-\u003e find ( "# foo", 0); // отримує при парсінгу всі елементи з класом class \u003d "foo" $ collection \u003d $ html-\u003e find ( ". Foo"); // отримує все теги при парсінгу htmlдокумента $ collection \u003d $ html-\u003e find ( "a"); // отримує все теги , Які поміщені в тег

$ Collection \u003d $ html-\u003e find ( "h1 a"); // отримує все зображення з title \u003d "(! LANG: himom" $collection = $html->find("img"); !}

Використання першого селектора при php парсінгу html документа, дуже просте і зрозуміле. Його унікальність в тому що він повертає тільки один html елемент, на відміну від інших, які повертають масив (колекцію). Другим параметром (0), ми вказуємо, що нам необхідний тільки перший елемент нашої колекції. Сподіваюся, вам зрозумілі всі варіанти селектор бібліотеки simple HTML DOM, якщо ви чогось не зрозуміли, спробуйте метод наукового експерименту. Якщо навіть він не допоміг, зверніться в коментарі до статті.

Документація бібліотеки simple HTML DOM

Цілковиту документацію по використанню бібліотеки simple HTML DOM ви зможете знайти за цією адресою:

http://simplehtmldom.sourceforge.net/manual.htm

Просто надам вам ілюстрацію, яка показує можливі властивості обраного HTML DOM елементу.


Крок 3 - Реальний приклад PHP парсинга HTML документа

Для прикладу парсинга, і приведення HTML DOM бібліотеки в дію, ми напишемо грабер матеріалів на сайті сайт. Далі ми виведемо всі статті у вигляді списку, в якому будуть вказані назви статей. При написанні грабер, пам'ятайте, крадіжка контенту переслідується законом! Але не у випадку, коли на сторінці варто активне посилання на вихідний документ.


Include ( "simple_html_dom.php"); $ Articles \u003d array (); getArticles ( "http: // сайт /");

Починаємо з підключення бібліотеки, і виклику функції getArticles, яка буде довільні HTML документи відповідно адресою сторінки, яка передається в якості параметра функції.

Також ми вказуємо глобальний масив, в якому буде, зберігається вся інформація про статті. Перед тим як почати парсинг HTML документа, давайте подивимося, як він виглядає.

Це базовий шаблон даної сторінки. При написанні парсеру html, потрібно ретельно дослідити документ, так як і коментарі, типу, Це теж нащадки. Іншими словами, в очах бібліотеки simple HTML DOM, це елементи, які рівноцінні іншим тегам сторінки.

Крок 4 - Пишемо основну функцію PHP парсеру HTML

function getArticles ($ page) (global $ articles; $ html \u003d new simple_html_dom (); $ html-\u003e load_file ($ page); // ... далі буде ...)

Спочатку функції, ми викликаємо наш глобальний масив, який ми вказали раніше. Створюємо новий об'єкт simple_html_dom. Далі завантажуємо сторінку, яку будемо аналізувати довільні.

Крок 5 - Знаходимо потрібну інформацію

$ Items \u003d $ html-\u003e find ( "div"); foreach ($ items as $ names) ($ articles \u003d array ($ post-\u003e children (0) -\u003e plaintext);)

У цьому шматку коду все гранично просто, ми знаходимо все div з class \u003d name_material. Далі читаємо колекцію елементів і вибираємо назви матеріалів. Всі матеріали будуть збережені в масиві в даному виді:

$ Articles \u003d "Ім'я матеріалу 1"; $ Articles \u003d "Ім'я матеріалу 2"; ...

Крок 6 - Виводимо результат парсинга

Для початку, ми встановимо деякі стилі, для краси виведеної інформації, яку отримали при парсінгу.

Item (padding: 10px; color: # 600; font: bold 40px / 38px helvetica, verdana, sans-serif;)

"; Echo $ item; echo"

"; } ?>

Результатом виконання даного скрипта, буде список назв статей на сайті сайт.

висновок

Ось ми і навчилися php парсингу html документів. Пам'ятайте, що парсинг це довгий процес. Одна сторінка може Парс близько однієї секунди. Якщо ви будете робити парсинг великого числа HTML документів, ваш сервер може перервати роботу скрипта в зв'язку із закінченням час відведеного для виконання. Це можна виправити за допомогою функції set_time_limit (240); 240 - це час в секундах, відведений на виконання скрипта.

Ця стаття призначена для формування основних понять парсинга HTML сторінки за допомогою PHP. Існують і інші бібліотеки та методи парсинга. Якщо ви знаєте такі, поділіться в коментарях. Буду радий, дізнатися якими інструментами і методами html парсинга користуєтеся ви.



Для того, щоб Спарс сторінку сайту (тобто розібрати її 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 код сайту. Ось він:

Це заголовок тайтл Це основний вміст сторінки.

Давайте займемося його розбором. Для початку давайте отримаємо вміст тега , тега <head>, І тега <body>.</p> <p>Отже, отримаємо вміст тега <title> (В змінної <b>$ str</b> зберігається HTML код, який ми розбираємо):</p> <p> <?php preg_match_all("#<title>(.+?)#su ", $ str, $ res); var_dump ($ res);?\u003e

вміст :

(.+?)#su ", $ str, $ res); var_dump ($ res);?\u003e

вміст :

(.+?)

#su ", $ str, $ res); var_dump ($ res);?\u003e

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

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

Що ж у нас не так? Насправді тег - такий же тег, як і інші і в ньому цілком можуть бути атрибути. Найчастіше це атрибут class, але можуть бути й інші (наприклад, onload для виконання JavaScript).

Отже, перепишемо регулярку з урахуванням атрибутів:

(.+?)

#su ", $ str, $ res); var_dump ($ res);?\u003e

Але і тут ми помилилися, при чому помилок кілька. перша - слід ставити не плюс + , А зірочку * , Так як плюс передбачає наявності хоча б одного символу - але ж атрибутів в тезі може і не бути - і в цьому випадку між назвою тега body і куточком не буде жодних символів - і наша регулярка спасує (не зрозуміло, що я тут написав - вчіть регулярки).

Поправимо цю проблему і повернемося до подальшого обговорення:

(.+?)

#su ", $ str, $ res); var_dump ($ res);?\u003e

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

Це заголовок тайтл

регулярки знайдеться не , Як очікувалося, а

абзац (

) - тому що ми не обмежили їй жадібність. Зробимо це: місце напишемо - в цьому випадку буде все добре.

Але найоптимальнішим варіантом буде написати замість точки конструкцію [^>] (не закривати куточок), ось так - ] *?\u003e - в цьому випадку ми повністю застрахуємо себе від проблем такого роду, так як регулярка ніколи не зможе вийти за тег.

Отримання блоку по id

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

Це заголовок тайтл

контент
ще див


Напишемо регулярку, яка отримає вміст блоку з id, рівним content.

Отже, спроба номер один (не зовсім коректна):

#(.+?)

#su

Що тут не так? Проблема з пробілами - адже між назвою тега і атрибутом може бути скільки завгодно пробілів, так само, як і навколо одно в атрибутах.

Всі проблеми такого роду істотні - навіть якщо ваша регулярка розбирає одну сторінку сайту - це не означає, що вона розбере іншу подібну сторінку: на ній цілком навколо одно в атрибуті id могли поставити прогалини - і тут ваша регулярка спасує.

Тому, регулярки парсеру потрібно будувати так, щоб вони обходили якомога більше проблем - в цьому випадку ваш парсер буде працювати максимально коректно на всіх сторінках сайту, а не тільки на тих, які ви перевірили.

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

#

(.+?)
#su

Зверніть увагу на те, що навколо одно прогалини можуть бути, а можуть і не бути, тому там стоїть оператор повторення зірочка * .

Крім того, перед закриває куточком тега теж можуть бути прогалини (а можуть і не бути) - врахуємо і це:

#(.+?)

#su

Отже, вже краще, але ще далеко не ідеал - адже навколо атрибута id можуть бути і інші атрибути, наприклад так:

. В цьому випадку наша регулярка спасує. Давайте вкажемо, що можуть бути ще й інші атрибути:

#

(.+?)
#su

Зверніть увагу, що після

варто регулярка .+? , А перед > варто регулярка .*? - це не помилка, так і задумано, адже після
обов'язково повинен йти пробіл (тобто хоча б один символ точно буде), а перед > може взагалі не бути інших атрибутів (крім нашого id) і пробілу теж може не бути.

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

#

] +? id \\ s *? \u003d \\ s *? "content" [^\u003e] *? \u003e (. +?)
#su

Наступна проблема: лапки-то в атрибутах можуть бути як одинарними, так і подвійними (їх навіть може взагалі не бути, якщо значення атрибута - одне слово, але цей випадок рідкісний - не будемо його враховувати, якщо вам зустрінеться такий сайт - простіше написати регулярку спеціально для нього). Отже, врахуємо це:

#] +? Id \\ s *? \u003d \\ S *? [ "\\"] Content [ "\\"] [^\u003e] *?\u003e (. +?)

#su

Зверніть увагу на те, що одинарна лапка заекранувати - ми це робимо, тому що зовнішні лапки від рядка PHP у нас теж одинарні, ось тут:

В общем-то регулярка досить хороша, але іноді йдуть далі і роблять так, щоб перша лапка від тега збігалася з другої (виключаємо варіант id \u003d "content"). В цьому випадку роблять так - перша лапка лягає в кишеню, а друга лапка вказується кишенею, щоб збігалася з першою:

#] +? Id \\ s *? \u003d \\ S *? ([ "\\"]) Content \\ 1 [^\u003e] *?\u003e (. +?)

#su

Для нашої задачі це особливо не потрібно (можна бути точно впевненим, що таке id \u003d "content" - навряд чи десь буде), але є атрибути, де це суттєво. Наприклад, в такому випадку:

- в атрибуті title цілком може затесатися одинарна лапка і регулярка title \\ s *? \u003d \\ s *? [ "\\"] (. +?) [ "\\"] витягне текст " Розповідь про д"- тому що пошук ведеться до першої лапки.

А ось регулярка title \\ s *? \u003d \\ s *? ([ "\\"]) (. +?) \\ 1 буде коректно обробляти

і навіть
.

Проблема вкладених блоків

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

, А не для закриває діва для #content. Приклад проблемного коду:

Це заголовок тайтл

Див всередині контенту
контент


Наша регулярка витягне тільки

Див всередині контенту
- зупиниться на першому ж
. Що робити в цьому випадку?

Що робити в цьому випадку? По-перше, до цього випадку завжди потрібно бути готовим - навіть якщо на досліджуваних сторінках сайту немає вкладених блоків - вони цілком можуть бути і на інших сторінках або з'явитися потім (якщо сайт Парс не один раз, а періодично).

Ну, а що робити - треба просто прив'язуватися ні до

, А до того, що стоїть під нашим блоком (в нашому випадку під контентом). У наведеному нижче коді під ним стоїть