PHP Получить данные application/ld+json со страницы внешнего рецепта

Пожалуйста, кто-нибудь может мне помочь? Я искал везде и не могу найти или предоставить правильное решение. Мне нужна помощь в извлечении данных рецепта с внешней страницы. Если вы посмотрите на изображение, вы заметите, что на одной странице реализовано несколько тегов ld+json, но мне нужно извлечь только данные рецепта и создать их в формате JSON, и оттуда я знаю, как загрузить его в таблицу в базе данных.

PHP Получить данные application/ld+json со страницы внешнего рецепта

  1. URL-адрес страницы.
  2. Размещение тега ld-json, хотя на других страницах оно отличается.
  3. Данные, которые мне нужно извлечь и распечатать в формате Json.

Я пробовал этот скрипт, но не знаю, как получить со страницы только данные рецепта.

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTMLFile('https://www.thecookingcat.com/recipes/fluffy-pancake.php');
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);
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
19
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш код, кажется, анализирует сложный HTML страницы вместо использования указанного вами ld+json, который предоставил бы все необходимые данные более простым и доступным способом.

Итак, первое предложение, вместо использования DOMXPath, просто зациклите все скрипты со страницы следующим образом:

foreach ($dom->getElementsByTagName('script') as $script) {

Затем, чтобы не пытаться анализировать настоящий код javascript и рассматривать только содержимое ld+json, проверьте атрибут type следующим образом:

if ($script->getAttribute('type') == "application/ld+json") {

Теперь вы можете получить доступ к тексту внутри тега с помощью $script->textContent

Обычно вы можете напрямую разобрать json в объект, но возвращаемый текст имеет 2 проблемы, которые могут привести к сбою json_decode:

  1. Он содержит комментарий в первой строке, который мы можем удалить с помощью регулярного выражения.
$json_txt = preg_replace('@/\*.*?\*/@', '', $script->textContent);
  1. Он содержит символы новой строки внутри абзацев, которые мы можем удалить с помощью другого регулярного выражения.
$json_txt = preg_replace("/\r|\n/", " ", trim($json_txt));

Теперь, когда у вас есть правильно отформатированный json, вы можете декодировать его в объект.

$json = json_decode($json_txt);

Затем вы можете легко получить доступ ко всем свойствам. Например, чтобы получить название рецепта, вы можете использовать

$json->name

а для ингредиентов у вас уже есть массив, поэтому вам даже не нужно зацикливаться.

$json->recipeIngredient;

Вы, конечно, можете назначить это своему собственному массиву, если хотите:

$recipe['title'] = $json->name;
$recipe['ingredients'] = $json->recipeIngredient;

Вот общий код

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTMLFile('https://www.thecookingcat.com/recipes/fluffy-pancake.php');

$recipe = array();
foreach ($dom->getElementsByTagName('script') as $script) {
    if ($script->getAttribute('type') == "application/ld+json") {
        $json_txt = preg_replace('@/\*.*?\*/@', '', $script->textContent);
        $json_txt = preg_replace("/\r|\n/", " ", trim($json_txt));
        $json = json_decode($json_txt);

        if ($json->{'@type'} == "Recipe") {
            $recipe['title'] = $json->name;
            $recipe['ingredients'] = $json->recipeIngredient;
        }
    }
}

Другие вопросы по теме