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

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

enter image description here

  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);
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Что нового в PHP 8.1?
Что нового в PHP 8.1?
Если вы все еще используете PHP 7, то эта статья для вас. В PHP 8, а именно в PHP 8.1, встроены некоторые очень востребованные функции, которые вам...
Разработка LMS на заказ для повышения эффективности работы и обучения
Разработка LMS на заказ для повышения эффективности работы и обучения
За последние годы в образовании произошла большая революция, и сегодня почти все учебные заведения делают упор на эксклюзивное управление учебным...
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;
        }
    }
}

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