Извлеките JSON из HTML, используя PHP

1

Я читаю исходный код веб-сайта интернет-магазина, и на каждой странице продукта мне нужно найти строку JSON, которая показывает SKU продуктов и их количество.

Вот два примера:

'{"sku-SV023435_B_M":7,"sku-SV023435_BL_M":10,"sku-SV023435_PU_M":11}'

В приведенном выше примере показаны 3 SKU.

'{"sku-11430_B_S":"20","sku-11430_B_M":"17","sku-11430_B_L":"30","sku-11430_B_XS":"13","sku-11430_BL_S":"7","sku-11430_BL_M":"17","sku-11430_BL_L":"4","sku-11430_BL_XS":"16","sku-11430_O_S":"8","sku-11430_O_M":"6","sku-11430_O_L":"22","sku-11430_O_XS":"20","sku-11430_LBL_S":"27","sku-11430_LBL_M":"25","sku-11430_LBL_L":"22","sku-11430_LBL_XS":"10","sku-11430_Y_S":"24","sku-11430_Y_M":36,"sku-11430_Y_L":"20","sku-11430_Y_XS":"6","sku-11430_RR_S":"4","sku-11430_RR_M":"35","sku-11430_RR_L":"47","sku-11430_RR_XS":"6"}',

В приведенном выше примере показано еще много SKU.

Количество SKU в строке JSON может варьироваться от одного до бесконечности.

Теперь мне нужен шаблон регулярного выражения, чтобы извлечь эту строку JSON с каждой страницы. В этот момент я могу легко использовать json_encode().

Обновление: здесь я нашел другую проблему, извините, что мой вопрос не был полным, есть еще одна подобная строка json, которая начинается с sku-. Пожалуйста, посмотрите исходный код ниже ссылки, которую вы поймете, единственная разница - это значение для этого один является буквенно-цифровым и для нашего необходимого является числовым. Также обратите внимание, что наша конечная цель - извлечь SKU с их количеством, возможно, у вас есть самое простое решение.

Источник

@Chris85

Второе обновление:

Вот еще одна странная проблема, которая немного не соответствует теме.

в то время как я открываю URL-адрес, используя нижеприведенный код, в источнике нет строки json!

$html = file_get_contents("http://www.dresslink.com/womens-candy-color-basic-coat-slim-suit-jacket-blazer-p-8131.html");

Но когда я открываю url с моим браузером, json есть! действительно смутил это :(

  • 0
    sku-11430_Y_M - опечатка? Количество не в кавычках ..
  • 0
    Я удалил свой ответ, возможно, @ Phil_1984_ поможет вам. Удачи.
Теги:
preg-match

3 ответа

0

Попытка извлечь определенные данные из json напрямую с помощью регулярного выражения обычно является плохой идеей из-за кодирования json. Лучшим способом является регулярное выражение всех json-данных, а затем декодирование с использованием функции php json_decode.

Проблема с отсутствующими данными связана с отсутствием необходимого файла cookie. См. Мои комментарии в коде ниже.

<?php

function getHtmlFromDresslinkUrl($url)
{
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);

    //You must send the currency cookie to the website for it to return the json you want to scrape
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Cookie: currencies_code=USD;',
    ));

    $output=curl_exec($ch);

    curl_close($ch);
    return $output;
}

$html = getHtmlFromDresslinkUrl("http://www.dresslink.com/womens-candy-color-basic-coat-slim-suit-jacket-blazer-p-8131.html");

//Get the specific arguments for this js function call only
$items = preg_match("/DL\.items\_list\.initItemAttr\((.+)\)\;/", $html, $matches);
if (count($matches) > 0) {
    $arguments = $matches[1];

    //Split by argument seperator.  
    //I know, this isn't great but it seems to work.
    $args_array = explode(", ", $arguments);

    //You need the 5th argument
    $fourth_arg = $args_array[4];

    //Strip quotes
    $fourth_arg = trim($fourth_arg, "'");

    //json_decode
    $qty_data = json_decode($fourth_arg, true);

    //Then you can work with the php array
    foreach ($qty_data as $name => $qtty) {
        echo "Found " . $qtty . " of " . $name . "<br />";
    }
}

?>

Особая благодарность @chris85 за то, что заставило меня снова прочитать вопрос. Извините, но я не мог отменить мой downvote.

  • 0
    Золото, благослови тебя @ Phil_1984_, также благодаря chris85, очень ценю твои усилия, извини, что я не могу голосовать
0

Простой /'(\{"[^\}]+\})'/ будет соответствовать всем этим строкам JSON. Демо: https://regex101.com/r/wD5bO4/2

Первый элемент возвращаемого массива будет содержать строку JSON для json_decode:

preg_match_all ("/'(\{\"[^\}]+\})'/", $html, $matches);

$html - это анализируемый HTML-код, JSON будет в $ match [0] [1], $ matches [1] [1], $ matches [2] [1] и т.д.

  • 0
    g не является модификатором в PHP. php.net/manual/en/reference.pcre.pattern.modifiers.php Это выдает Warning: preg_match_all(): Unknown modifier 'g' для меня.
  • 0
    Спасибо за подсказку @ chris85. preg_match_all уже соответствует всем вхождениям, нет необходимости в g как в JavaScript
0

Вы хотите использовать preg_match_all() для выполнения операции сопоставления регулярных выражений (документация здесь).

Следующее должно сделать это за вас. Он будет соответствовать каждой подстроке, начинающейся с "sku" и заканчивая ",".

preg_match_all("/sku\-.+?:[0-9]*/", $input)

Рабочий пример здесь.

Кроме того, если вы хотите извлечь всю строку, вы можете использовать:

preg_match_all("/{.sku\-.*}/, $input")

Это будет захватывать все между открывающими и закрывающими скобками.

Рабочий пример здесь.

Обратите внимание, что $input обозначает входную строку.

  • 0
    пожалуйста, сделайте демо, это не работает для меня :( @grill, мой необходимый язык в PHP
  • 0
    Здесь я нашел еще одну проблему, извините, что мой вопрос не был завершен, есть другая похожая строка json, которая начинается с sku-. Пожалуйста, посмотрите на исходный код по ссылке ниже, вы поймете, единственное отличие - это значение для этого является буквенно-цифровым и для нашего необходимого является числовым. dresslink.com/… Также обратите внимание, что наша конечная цель состоит в том, чтобы извлечь SKU с их количеством, может быть, у вас есть самое простое решение. @grill

Ещё вопросы

Сообщество Overcoder
Наверх
Меню