2

嗨,我正在使用 cURL 从网站获取数据,我需要获取多个项目,但无法通过标签名称或 ID 获取。我已经设法整理了一些代码,这些代码将使用类名获取一个项目,方法是通过一个循环传递它,然后通过另一个循环传递它以从元素中获取文本。

我在这里有一些问题,首先是我可以看到必须有一种更方便的方法来做到这一点。第二个我需要获取多个元素并堆叠在一起,即标题、描述、标签和一个 url 链接。

# Create a DOM parser object and load HTML
$dom    = new DOMDocument();
$result = $dom->loadHTML($html);

$finder = new DomXPath($dom);
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '),     'classname')]");

$tmp_dom = new DOMDocument(); 
foreach ($nodes as $node) 
{
    $tmp_dom->appendChild($tmp_dom->importNode($node,true));
}

$innerHTML = trim($tmp_dom->saveHTML()); 

$buffdom = new DOMDocument();
$buffdom->loadHTML($innerHTML);

# Iterate over all the <a> tags
foreach ($buffdom->getElementsByTagName('a') as $link) 
{
    # Show the <a href>
    echo $link->nodeValue, "<br />", PHP_EOL;
}

我只想坚持使用 PHP。

4

1 回答 1

2

我想知道您的问题是否在行:

$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '),     'classname')]");

就目前而言,这实际上是查找属于名为“classname”的类的节点——其中“classname”不是变量,而是实际名称。看起来您可能从某个地方复制了一个示例 - 或者您是否按字面意思命名了您的课程?

我想您正在查看的数据可能不在此类节点中。如果您可以发布一小段您尝试解析的实际 HTML,那么应该可以更好地指导您找到解决方案。

作为一个例子,我只是做了以下完整的代码(基于你的,但是添加代码以打开stackoverflow.com主页,并更改'classname''question',因为名称中似乎有很多类question,所以我想我应该得到一个好收成。没有让我失望。

<?php
// create curl resource
        $ch = curl_init();

        // set url
        curl_setopt($ch, CURLOPT_URL, "http://stackoverflow.com");

        //return the transfer as a string
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        // $output contains the output string
        $output = curl_exec($ch);

        // close curl resource to free up system resources
        curl_close($ch);      
//print_r($output);

$dom = new DOMDocument();
@$dom->loadHTML($output);

$finder = new DomXPath($dom);
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), 'question')]");
print_r($nodes);

$tmp_dom = new DOMDocument(); 
foreach ($nodes as $node) 
    {
    $tmp_dom->appendChild($tmp_dom->importNode($node,true));
    }
  $innerHTML.=trim($tmp_dom->saveHTML()); 

  $buffdom = new DOMDocument();
  @$buffdom->loadHTML($innerHTML);
    # Iterate over all the <a> tags
    foreach($buffdom->getElementsByTagName('a') as $link) {
        # Show the <a href>
        echo $link->nodeValue, PHP_EOL;
    echo "<br />";
    }
?>

导致很多很多行的输出。试试看 - 该页面位于http://www.floris.us/SO/scraper.php

(或将上面的代码粘贴到您自己的页面中)。你非常非常接近!

注意 - 这不会产生您想要的所有输出 - 您需要包含节点的其他属性,而不仅仅是打印nodeValue, 来获取所有内容。但我认为您可以从这里获取它(同样,如果没有您的 HTML 的实际样本,其他人不可能比这更进一步帮助您......)

于 2013-04-19T03:41:33.497 回答