Вернуться   Форум об интернет-маркетинге > >
Ответ
 
Опции темы
Старый 15.05.2019, 22:03   #1
Академик
 
Регистрация: 28.06.2008
Сообщений: 6,779
Репутация: 386284

По умолчанию Учусь парсить нужны советы

Продолжаю учить пхп, теперь понемногу разбираюсь в парсинге. И я тут такое наговнокодил что самому страшно. У меня вот вопрос.
Если задача например следующая - забрать все абзацы на странице внутри id контент
Как мое творение можно оптимизировать и упростить?

Цитата:
<?php

$str = file_get_contents('http://code.mu/exercises/advanced/php/parsing/parsing-sajtov-regulyarnymi-vyrazeniyami-php/2/1.php');
//получаю блок контент
preg_match_all('~<div[^>]*?id="content"[^>]*?>(.+?)</div>~ms', $str, $matches2, PREG_SET_ORDER, 0);
//убираю лишнее
unset($matches2[0][0]);

//получаю все абзацы внутри контента
preg_match_all('~<p[^>]*?>(.*)</p>~mUs', $matches2[0][1], $matches3, PREG_SET_ORDER, 0);
//убираю лишнее
foreach ($matches3 as $lishnee){
unset($lishnee[0]);
var_dump($lishnee);
}
Dram вне форума   Ответить с цитированием

Реклама
Старый 15.05.2019, 22:42   #2
Samail
Академик
 
Аватар для Samail
 
Регистрация: 10.05.2007
Сообщений: 2,928
Репутация: 306919

По умолчанию Re: Учусь парсить нужны советы

Цитата:
Сообщение от Dram Посмотреть сообщение
preg_match_all('~<div[^>]*?id="conten
Зачем preg_match_all если такой блок будет всего один?
Samail вне форума   Ответить с цитированием
Старый 15.05.2019, 22:45   #3
Апокалипсис
Пишу мемуары
 
Аватар для Апокалипсис
 
Регистрация: 02.11.2008
Адрес: Глизе 581c
Сообщений: 5,034
Репутация: 364992

По умолчанию Re: Учусь парсить нужны советы

Для отладки регулярок очень рекомендую сервис: https://regex101.com/
__________________
Записки нищего - мой личный блог
Апокалипсис вне форума   Ответить с цитированием
Старый 15.05.2019, 22:48   #4
Samail
Академик
 
Аватар для Samail
 
Регистрация: 10.05.2007
Сообщений: 2,928
Репутация: 306919

По умолчанию Re: Учусь парсить нужны советы

Цитата:
Сообщение от Dram Посмотреть сообщение
(.+?)</div>~
Если внутри этого блока будет ещё один блок то захватится только то что идёт до закрывающего тега вложенного блока.
Samail вне форума   Ответить с цитированием
Старый 15.05.2019, 22:52   #5
Dram
Академик
 
Регистрация: 28.06.2008
Сообщений: 6,779
Репутация: 386284

ТопикСтартер Re: Учусь парсить нужны советы

Немного не правильно поставил вопрос.
Интересует - логика то правильная?
Сначала вычленяем нужный див, затем в нем ищем абзацы?
Итого две регулярки.
Или можно проще? Это просто моя первая попытка...

---------- Добавлено 15.05.2019 в 22:53 ----------

Цитата:
Сообщение от Samail Посмотреть сообщение
Если внутри этого блока будет ещё один блок то захватится только то что идёт до закрывающего тега вложенного блока.
А как этого избежать?
Dram вне форума   Ответить с цитированием
Старый 16.05.2019, 00:40   #6
edogs
Писать: search@ник_тут.ru
 
Аватар для edogs
 
Регистрация: 16.12.2005
Адрес: St.Petersburg, Russia
Сообщений: 7,786
Репутация: 92274
Отправить сообщение для edogs с помощью Skype™

По умолчанию Re: Учусь парсить нужны советы

Dram,
Это вряд ли в тематике Вашего курса, но все же
Цитата:
$t='http://code.mu/exercises/advanced/php/parsing/parsing-sajtov-regulyarnymi-vyrazeniyami-php/2/1.php';
$doc = new DOMDocument();
$doc->loadHTMLFile($t);
$doc->normalizeDocument();
$res=$doc->getElementById('content')->getElementsByTagName('p');
$n=array();
foreach($res as $p) $n[]=$doc->saveHTML($p);
var_dump($n);
Регулярки использовать для парсинга в принципе хорошо и правильно (сами предпочитаем), но dom дерево имеет свои плюсы (простота).
__________________
Разработка проектов связанных с криптовалютой. Разумные цены. Хорошее качество. Адекватный подход.
Ищем админа на сервер, в личку: цену установки vdsmanager на hetzner и расстановку ИП.
edogs вне форума   Ответить с цитированием
Сказали спасибо:
Старый 16.05.2019, 13:10   #7
_SP_
Академик
 
Регистрация: 24.03.2008
Адрес: MSK
Сообщений: 3,562
Репутация: 366875

По умолчанию Re: Учусь парсить нужны советы

Готовые парсеры парсят обычно неплохо.

Но в инете редко встретишь валидный документ...

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

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

Регулярки не использую. Менее удобно отлаживать.
_SP_ вне форума   Ответить с цитированием
Сказали спасибо:
Старый 16.05.2019, 15:19   #8
Dram
Академик
 
Регистрация: 28.06.2008
Сообщений: 6,779
Репутация: 386284

ТопикСтартер Re: Учусь парсить нужны советы

edogs, спасибо за пример более элегантного способа. Начал его изучать плотнее. Решил попробовать вытащить абзацы с нужным классом и получил ошибку, почему?

Цитата:
$res=$doc->getElementById('content')->getElementsByClassName('www');
Fatal error: Uncaught Error: Call to undefined method DOMElement::getElementsByClassName() in C:\OSPanel\domains\localhost\index.php on line 58
( ! ) Error: Call to undefined method DOMElement::getElementsByClassName() in C:\OSPanel\domains\localhost\index.php on line 58
Dram вне форума   Ответить с цитированием
Старый 16.05.2019, 17:36   #9
edogs
Писать: search@ник_тут.ru
 
Аватар для edogs
 
Регистрация: 16.12.2005
Адрес: St.Petersburg, Russia
Сообщений: 7,786
Репутация: 92274
Отправить сообщение для edogs с помощью Skype™

По умолчанию Re: Учусь парсить нужны советы

Цитата:
Сообщение от Dram Посмотреть сообщение
edogs, спасибо за пример более элегантного способа. Начал его изучать плотнее. Решил попробовать вытащить абзацы с нужным классом и получил ошибку, почему?

Fatal error: Uncaught Error: Call to undefined method DOMElement::getElementsByClassName() in C:\OSPanel\domains\localhost\index.php on line 58
( ! ) Error: Call to undefined method DOMElement::getElementsByClassName() in C:\OSPanel\domains\localhost\index.php on line 58
Потому что там нет такой функции. https://www.php.net/manual/ru/book.dom.php - тут смотрите что есть.
Для задач выбора класса и/или вообще более сложных выборов можно использовать xpath
Код:
$t='http://code.mu/exercises/advanced/php/parsing/parsing-sajtov-regulyarnymi-vyrazeniyami-php/2/1.php';
$doc = new DOMDocument();
$doc->loadHTMLFile($t);
$doc->normalizeDocument();
$xpath=new DOMXPath($doc);
$resX=$xpath->query('//*[@class="www"]');
$nX=array();
foreach($resX as $www) $nX[]=$doc->saveHTML($www);
var_dump($nX);
Обратите внимание - "ссылка 4" тут нет, ибо валидность.

Так же советуем (если тематика интересна) посмотреть на альтернативные классы html парсеров, не встроенных в php, они зачастую поинтереснее. С другой стороны на данном этапе можете не углубляться, тут важно знать сам факт возможности парсить не просто строковыми функциями, а через разбор dom дерева.
edogs вне форума   Ответить с цитированием
Сказали спасибо:
Старый 16.05.2019, 17:37   #10
Dram
Академик
 
Регистрация: 28.06.2008
Сообщений: 6,779
Репутация: 386284

ТопикСтартер Re: Учусь парсить нужны советы

Большое спасибо!
Dram вне форума   Ответить с цитированием
Ответ



Опции темы

Быстрый переход


Регистрация Справка Календарь Поддержка Все разделы прочитаны