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

я пытаюсь собрать некоторые данные с этого сайта: http://laperuanavegana.wordpress.com/. на самом деле я хочу название рецепта и ингредиенты. ингредиенты находятся внутри двух конкретных ключевых слов. я пытаюсь получить эти данные, используя regex и simplehtmldom. но он показывает полный HTML-текст, а не только ингредиенты. вот мой код: ‹?php

include_once('simple_html_dom.php');
$base_url = "http://laperuanavegana.wordpress.com/";

traverse($base_url);


function traverse($base_url)
{
    
    $html = file_get_html($base_url);
    $k1="Ingredientes";
    $k2="Preparación";
    preg_match_all("/$k1(.*)$k2/s",$html->innertext,$out);
    echo $out[0][0];
}

?>

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


person Quazi Marufur Rahman    schedule 13.08.2011    source источник


Ответы (2)


Там нужно поставить вопросительный знак. Это делает шаблон нежадным - иначе он возьмет все от первого $k1 до последнего $k2 на странице. Если вы добавите вопросительный знак, он всегда будет занимать следующие $k2.

preg_match_all("/$k1(.*?)$k2/s",$html->innertext,$out);
person Chronial    schedule 13.08.2011
comment
благодаря . можно ли узнать сколько совпадений было найдено?? И это регулярное выражение показывает весь текст, включая K1 и K2, но мне нужен только этот текст внутри них - person Quazi Marufur Rahman; 13.08.2011
comment
Что ж, просто посмотрите на содержимое $out, и вы все узнаете. Вы можете распечатать содержимое массива с помощью print_r и подсчитать элементы массива с помощью count(). - person Chronial; 13.08.2011
comment
не могли бы вы помочь еще ?? Я хочу получить все ингредиенты этого сайта. поэтому я должен пройти весь сайт. я могу вызвать все ссылки с первой страницы рекурсивно, чтобы сделать это. но это создаст проблему, если есть обратная ссылка. не могли бы вы решить эту проблему ?? - person Quazi Marufur Rahman; 13.08.2011

Если вы уже используете парсер HTML (даже такой плохой, как SimpleHtmlDom), зачем тогда вы пытаетесь все испортить с помощью Regex? Это все равно, что использовать скальпель, чтобы вскрыть пациента, а затем вернуться к заточенной ложке для фактической операции.

Поскольку я твердо убежден, что никто не должен использовать SimpleHtmlDom из-за плохой кодовой базы и намного медленнее, чем синтаксические анализаторы на основе libxml, вот как это сделать с помощью родное расширение DOM для PHP и XPath. XPath фактически является Regex или SQL для документов X(HT)ML. Изучите его, и вам больше никогда не придется прикасаться к Regex для HTML.

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTMLFile('https://laperuanavegana.wordpress.com/2011/06/11/ensalada-tibia-de-quinua-mango-y-tomate/');
libxml_clear_errors();

$recipe = array();
$xpath = new DOMXPath($dom);
$contentDiv = $dom->getElementById('content');
$recipe['title'] = $xpath->evaluate('string(div/h2/a)', $contentDiv);
foreach ($xpath->query('div/div/ul/li', $contentDiv) as $listNode) {
    $recipe['ingredients'][] = $listNode->nodeValue;
}
print_r($recipe);

Это выведет:

Array
(
    [title] => Ensalada tibia de quinua, mango y tomate
    [ingredients] => Array
        (
            [0] => 250gr de quinua cocida tibia
            [1] => 1 mango grande
            [2] => 2 tomates
            [3] => Unas hojas de perejil
            [4] => Sal
            [5] => Aceite de oliva
            [6] => Vinagre balsámico
        )

)

Обратите внимание, что мы анализируем не http://laperuanavegana.wordpress.com/, а фактическую запись в блоге. Основной URL-адрес будет изменять содержимое каждый раз, когда владелец блога добавляет новую запись.

Чтобы получить все Рецепты с главной страницы, вы можете использовать

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTMLFile('https://laperuanavegana.wordpress.com');
libxml_clear_errors();
$contentDiv = $dom->getElementById('content');
$xp = new DOMXPath($dom);
$recipes = array();
foreach ($xp->query('div/h2/a|div/div/ul/li', $contentDiv) as $node) {
    echo
        ($node->nodeName === 'a') ? "\n# " : '- ',
        $node->nodeValue,
        PHP_EOL;
}

Это выведет

# Ensalada tibia de quinua, mango y tomate
- 250gr de quinua cocida tibia
- 1 mango grande
- 2 tomates
- Unas hojas de perejil
- Sal
- Aceite de oliva
- Vinagre balsámico

# Flan de lúcuma
- 1 lúcuma grandota o 3 pequeñas
- 1/2 litro de leche de soja evaporada
…

и так далее

Также см

person Gordon    schedule 13.08.2011
comment
спасибо за ваше ценное предложение. я узнаю это как можно скорее. но мне действительно нужно, чтобы это делалось с помощью регулярных выражений. потому что у меня есть ключевые слова Ingredientes и Preparación, внутри которых находятся ингредиенты. подскажите как это сделать?? @Chronial уже ответил на мой вопрос. мне нужно больше деталей. и я упомянул об этом в предыдущем комментарии - person Quazi Marufur Rahman; 13.08.2011
comment
@qmaruf зачем вам использовать ключевые слова, когда приведенный выше код уже дает вам ингредиенты? - person Gordon; 13.08.2011
comment
это что-то вроде проекта. и использование регулярного выражения является требованием. так что я обязан использовать его. я изучу DOMDocument как можно скорее - person Quazi Marufur Rahman; 13.08.2011
comment
@qmaruf без обид, но тогда это глупый проект. Вам не нужно Regex для этой задачи. Вы можете получить любую информацию из документа быстрее и надежнее с помощью DOM и XPath. Скажите тому, кто сделал Regex требованием для этого проекта, что это неправильный инструмент для работы. Regex не понимает HTML. Вы заново изобретаете колесо, обучая Regex понимать HTML. Разбор HTML — решаемая проблема. Для этого вы используете парсер HTML/XML. - person Gordon; 13.08.2011