【问题标题】:Extract JSON from HTML using PHP使用 PHP 从 HTML 中提取 JSON
【发布时间】:2015-08-22 00:58:08
【问题描述】:

我正在阅读一个在线商店网站的源代码,我需要在每个产品页面上找到一个显示产品 SKU 及其数量的 JSON 字符串。

这里有 2 个示例:

'{"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。

JSON 字符串中的 SKU 数量可以从 1 到无穷大。

现在,我需要一个正则表达式模式来从每个页面中提取这个 JSON 字符串。那时,我可以轻松使用json_encode()

更新: 在这里我发现了另一个问题,对不起,我的问题不完整,还有另一个类似的以 sku- 开头的 json 字符串,请看下面链接的源代码你会明白,唯一的区别是那个的值是字母数字,我们需要的是数字。另请注意,我们的最终目标是提取 SKU 及其数量,也许您有一个最直接的解决方案。

Source

@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 就在那里!真的很困惑:(

【问题讨论】:

  • sku-11430_Y_M 是错字吗?数量不在引号中..
  • 我已经删除了我的答案,也许@Phil_1984_ 会帮助你。祝你好运。

标签: php regex json preg-match


【解决方案1】:

由于 json 的编码方式,尝试使用正则表达式直接从 json 中提取特定数据通常是一个坏主意。最好的方法是将整个 json 数据进行正则表达式,然后使用 php 函数 json_decode 进行解码。

缺少数据的问题是由于缺少必需的 cookie。在下面的代码中查看我的 cmets。

<?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 让我再次阅读问题。抱歉,我无法撤消我的反对票。

【讨论】:

  • 黄金祝福你@Phil_1984_,也感谢chris85,非常感谢你的努力,抱歉我不能投票
【解决方案2】:

一个简单的/'(\{"[^\}]+\})'/ 将匹配所有这些JSON 字符串。演示:https://regex101.com/r/wD5bO4/2

返回数组的第一个元素将包含 json_decode 的 JSON 字符串:

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

$html是要解析的HTML,JSON会在$matches[0][1]、$matches[1][1]、$matches[2][1]等中

【讨论】:

【解决方案3】:

您将希望使用preg_match_all() 来执行正则表达式匹配操作(文档here)。

以下内容应该为您完成。它将匹配以“sku”开头并以“,”结尾的每个子字符串。

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

工作示例here

或者,如果你想提取整个字符串,你可以使用:

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

这将抓取左括号和右括号之间的所有内容。

工作示例here

请注意$input表示输入字符串。

【讨论】:

  • 请做一个演示,它不适合我 :( @grill ,我需要的 PHP 语言
  • 这里我又发现了一个问题,抱歉我的问题不完整,还有另一个类似的json字符串是以sku-开头的,请看下面链接的源代码你就明白了,唯一的区别是那个值是字母数字的,而我们需要的值是数字的。 dresslink.com/… 另外请注意,我们的最终目标是提取 SKU 及其数量,也许您有一个最直接的解决方案。 @烧烤
猜你喜欢
  • 2019-06-16
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
相关资源
最近更新 更多