如何使用DOMDocument从网站URL读取JSON

时间:2018-10-13 16:37:16

标签: php json domdocument

在下面的代码中,我试图读取application/ld+json JSON并获取ratingValue

使用https://www.facebook.com/Dermaks的当前网址($rate)结果应该是:5

如果您访问此url(在“查看源代码”模式下位于4行以上),则可以使用JSON,我想阅读它:

<script type="application/ld+json"> {
    "\u0040context":"http:\/\/schema.org",
    "\u0040type":"LocalBusiness",
    "name":"Kosmetyka Profesjonalna Dermaks",
    "address": {
        "\u0040type": "PostalAddress", "streetAddress": "DERMAKS, ul. Hempla 4\/34a", "addressLocality": "Lublin, Poland", "addressRegion": "Lublin Voivodeship", "postalCode": "20-008"
    }
    ,
    "aggregateRating": {
        "\u0040type": "AggregateRating", "ratingValue": 5, "ratingCount": 2
    }
}

</script>

<script type="application/ld+json"> {
    "\u0040context":"http:\/\/schema.org",
    "\u0040type":"Review",
    "name":"",
    "reviewBody":"Profesjonalna  i przy tym bardzo,bardzo mi\u0142a obs\u0142uga. Zabiegi na bardzo wysokim poziomie. POLECAM next dw\u00f3ch zda\u0144!!!!!!!",
    "itemReviewed": {
        "\u0040type": "LocalBusiness", "name": "Kosmetyka Profesjonalna Dermaks", "sameAs": "https:\/\/www.facebook.com\/Dermaks\/"
    }
    ,
    "reviewRating": {
        "\u0040type": "Rating", "ratingValue": 5
    }
    ,
    "author": {
        "\u0040type": "Person", "name": "Malgorzata Mordo\u0144"
    }
}

</script>

如何修复下面的代码?     

$url = 'https://www.facebook.com/Dermaks';

function get_data($url, $timeout = 15, $header = array(), $options = array()) {
    if (!function_exists('curl_init')) {
    return file_get_contents($url);
  } elseif (!function_exists('file_get_contents')) {
    return '';
  }
    if (empty($options)) {
        $options = array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
            CURLOPT_TIMEOUT => $timeout
        );
    }
    if (empty($header)) {
        $header = array(
            "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*\/*;q=0.5",
            "Accept-Language: en-us,en;q=0.5",
            "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7",
            "Cache-Control: must-revalidate, max-age=0",
            "Connection: keep-alive",
            "Keep-Alive: 300",
            "Pragma: public"
        );
    }
    if ($header != 'NO_HEADER') {
        $options[CURLOPT_HTTPHEADER] = $header;
    }
    $ch = curl_init();
    curl_setopt_array($ch, $options);
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

$html = get_data($url);
$doc = new DOMDocument();
@$doc->loadHTML($html);
$scripts = $doc->getElementsByTagName('script');
for ($i = 0; $i < $scripts->length; ++$i) {
  $script = $scripts->item($i);
  if ($script->getAttribute('type') == 'application/ld+json') {
    $rate = $script->getAttribute('ratingValue');
  }
}

echo $rate;
// result should be: 5

1 个答案:

答案 0 :(得分:0)

您将必须运行每个$scriptjson_decode

我假设您只需要aggregateRating的值,因为ratingValue有多个元素。

if ($script->getAttribute('type') == 'application/ld+json') {
  // Load as an array
  $entity = json_decode($script->nodeValue, true);
  if (($entity['type'] == '@LocalBusiness') && isset($entity['aggregateRating'])) {
    $rate = $entity['aggregateRating']['ratingValue'];
    break;
  }
}

顺便说一句,DOMDocument loadHTMLFile方法应该能够在适当的php.ini配置下自行获取网址:

$doc->loadHTMLFile($url);