php proDOM parsing error

2019-01-26 02:24发布

I am using the following code for parsing dom document but at the end I get the error "google.ac" is null or not an object line 402 char 1

What I guess, line 402 contains tag and a lot of ";", How can I fix this?

<?php

//$ch = curl_init("http://images.google.com/images?q=books&tbm=isch/");


// create a new cURL resource
$ch = curl_init();

// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://images.google.com/images?q=books&tbm=isch/");
curl_setopt($ch, CURLOPT_HEADER, 0);

// grab URL and pass it to the browser
$data = curl_exec($ch);

curl_close($ch); 

$dom = new DOMDocument();
       $dom->loadHTML($data);
    //@$dom->saveHTMLFile('newfolder/abc.html')

     $dom->loadHTML('$data');

    // find all ul

    $list = $dom->getElementsByTagName('ul'); 
    // get few  list items 

    $rows = $list->item(30)->getElementsByTagName('li'); 
    // get anchors from the table   

    $links = $list->item(30)->getElementsByTagName('a'); 

    foreach ($links as $link) { 
        echo "<fieldset>"; 
        $links = $link->getElementsByAttribute('imgurl');

    $dom->saveXML($links);
                }
?>

1条回答
Summer. ? 凉城
2楼-- · 2019-01-26 03:00

There are a few issues with the code:

  1. You should add the CURL option - CURLOPT_RETURNTRANSFER - in order to capture the output. By default the output is displayed on the browser. Like this: curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);. In the code above, $data will always be TRUE or FALSE (http://www.php.net/manual/en/function.curl-exec.php)

  2. $dom->loadHTML('$data'); is not correct and not required

  3. The method of reading 'li' and 'a' tags might not be correct because $list->item(30) will always point to the 30th element

Anyways, coming to the fixes. I'm not sure if you checked the HTML returned by the CURL request but it seems different from what we discussed in the original post. In other words, the HTML returned by CURL does not contain the required <ul> and <li> elements. It instead contains <td> and <a> elements.

Add-on: I'm not very sure why do HTML for the same page is different when it is seen from the browser and when read from PHP. But here is a reasoning that I think might fit. The page uses JavaScript code that renders some HTML code dynamically on page load. This dynamic HTML can be seen when viewed from the browser but not from PHP. Hence, I assume the <ul> and <li> tags are dynamically generated. Anyways, that isn't of our concern for now.

Therefore, you should modify your code to parse the <a> elements and then read the image URLs. This code snippet might help:

<?php
$ch = curl_init(); // create a new cURL resource

// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://images.google.com/images?q=books&tbm=isch/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

$data = curl_exec($ch); // grab URL and pass it to the browser
curl_close($ch); 

$dom = new DOMDocument();
@$dom->loadHTML($data); // avoid warnings

$listA = $dom->getElementsByTagName('a'); // read all <a> elements
foreach ($listA as $itemA) { // loop through each <a> element
    if ($itemA->hasAttribute('href')) { // check if it has an 'href' attribute
        $href = $itemA->getAttribute('href'); // read the value of 'href'
        if (preg_match('/^\/imgres\?/', $href)) { // check that 'href' should begin with "/imgres?"
            $qryString = substr($href, strpos($href, '?') + 1);
            parse_str($qryString, $arrHref); // read the query parameters from 'href' URI
            echo '<br>' . $arrHref['imgurl'] . '<br>';
        }
    }
}

I hope above makes sense. But please note that the above parsing might fail if Google modifies their HTML.

查看更多
登录 后发表回答