【问题标题】:PHP Simple HTML DOM and cURL Not WorkingPHP 简单的 HTML DOM 和 cURL 不工作
【发布时间】:2017-06-07 22:01:09
【问题描述】:

我无法让我的抓取工具返回我正在寻找的特定内容。如果我返回 $output,我会看到 digg 好像它托管在我的服务器上,所以我知道我正在正确访问该站点,但我无法访问新 DOM 中的元素。我做错了什么?

<?php

include('simple_html_dom.php');


function curl_download($url) {

$ch = curl_init();                                              //creates a new cURL resource handle
curl_setopt($ch, CURLOPT_URL, "http://digg.com");               // Set URL to download
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                 //  TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
curl_setopt($ch, CURLOPT_USERAGENT, "MozillaXYZ/1.0");          // Set a referer
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );                // Should cURL return or print out the data? (true = return, false = print) 
curl_setopt($ch, CURLOPT_HEADER, 0);                            // Include header in result? (0 = yes, 1 = no)
curl_setopt($ch, CURLOPT_TIMEOUT, 10);                          // Timeout in seconds


$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

}       

$html = new simple_html_dom();
$html->load($output, true, false );


    foreach($html->find('div.digg-story__kicker') as $article) {
        $article_title = $article->find('.digg-story__kicker')->innertext;
        return $article_title;
    }

    echo $article_title;


?>

编辑:好的,愚蠢的错误,我现在正在调用该函数:

$html = curl_download('http://digg.com')

如果我回显 $html,我会看到“镜像站点”,但是当我使用 str_get_html($html) 时,simple_html_dom.php 会说 //get html dom from string我不断收到此错误消息:

致命错误:在第 31 行的 /home/andrew73124/public_html/scraper/scraper.php 中调用成员函数 str_get_html() on null

【问题讨论】:

  • Digg 还在,哇
  • 提供的代码 sn-ps 似乎脱节 - 有一个函数 curl_download 但它永远不会被调用,它也不返回任何值,因此不清楚 $output 变量来自哪里
  • 哦,我什至没有调用该函数。好的,我需要:'$html = curl_download('digg.com');'调用函数。那返回一个字符串对吗?那么现在我需要将其转换为 DOMDocument 吗?
  • 将 $html 作为变量进行双重赋值 - 也许在 $html = new simple_html_dom();$html-&gt;load($output, true, false ); 之前尝试 $output=curl_download('http://digg.com')
  • 这对我有用。 &lt;?php foreach(@DOMDocument::loadHTML(file_get_contents('http://digg.com/'))-&gt;getElementsByTagName("div") as $div){ if($div-&gt;getAttribute("class")!=='digg-story__kicker'){ continue; } var_dump($div-&gt;textContent); } - 就是这样,没有 curl,没有 simple_html_dom.php,没有什么,就是这样。

标签: php curl dom web-scraping


【解决方案1】:

你的循环很奇怪,你在标题上循环,所以只需访问 innertext 属性:

foreach($html->find('div.digg-story__kicker') as $article) {

    echo $article->innertext;

}

【讨论】:

  • 哎呀,这应该是 'foreach(html->find('div.digg-story') as $article) {。即使我有正确的结果,它也会告诉我我正在返回“null”,这让我认为它没有将返回的字符串转换为 DOMDocument 对吗?
【解决方案2】:

curl 函数需要一个额外的设置 - 即CURLOPT_FOLLOWLOCATION 并且函数本身需要返回一个值才能使用它的值。在下面的代码中,我返回了一个包含响应和信息的对象,它允许您在尝试处理响应数据之前测试 http_code。 这使用标准 DOMDocument,但毫无疑问,使用 simple_dom 会很容易做到。

function curl_download( $url ) {

    $ch = curl_init(); 
    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );/* NEW */
    curl_setopt( $ch, CURLOPT_USERAGENT, "MozillaXYZ/1.0" );
    curl_setopt( $ch, CURLOPT_HEADER, 0 );
    curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );


    $output = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    return (object)array(
        'response'  =>  $output,
        'info'      =>  $info
    );
}       


$output = curl_download( 'http://www.digg.com' );
if( $output->info['http_code']==200 ){

    libxml_use_internal_errors( true );

    $dom=new DOMDocument;

    $dom->preserveWhiteSpace = false;
    $dom->validateOnParse = false;
    $dom->standalone=true;
    $dom->strictErrorChecking=false;
    $dom->substituteEntities=true;
    $dom->recover=true;
    $dom->formatOutput=false;

    $dom->loadHTML( $output->response );

    libxml_clear_errors();

    $xp=new DOMXPath( $dom );
    $col=$xp->query('//div[@class="digg-story__kicker"]');
    if( !empty( $col ) ){
        foreach( $col as $node )echo $node->nodeValue;
    }
} else {
    echo '<pre>',print_r($output->info,true),'</div>';
}

更新的答案包括 libxml 提供的错误缓解代码 - 奇怪的是,在添加 libxml 错误处理代码之前,该代码在本地运行时没有出现问题......

没有CURLOPT_FOLLOWLOCATION 设置我得到:

Array
(
    [url] => http://www.digg.com
    [content_type] => text/html
    [http_code] => 301
    [header_size] => 191
    [request_size] => 79
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.421
    [namelookup_time] => 0.031
    [connect_time] => 0.234
    [pretransfer_time] => 0.234
    [size_upload] => 0
    [size_download] => 185
    [speed_download] => 439
    [speed_upload] => 0
    [download_content_length] => 185
    [upload_content_length] => 0
    [starttransfer_time] => 0.421
    [redirect_time] => 0
    [certinfo] => Array
        (
        )
)

但是将CURLOPT_FOLLOWLOCATION 设置为true 我得到了

WE'VE SEEN BETTER ANIME TRIBUTE VIDEOS...<more>...RESIST THE URGE TO SUBTWEET A BAD APPLE

【讨论】:

  • 当我尝试逐字运行您的代码时出现此错误? 警告:DOMDocument::loadHTML(): htmlParseEntityRef: 期待 ';'在实体中,第 32 行的 /home/andrew73124/public_html/scraper/scraper.php 中的第 126 行。谢谢大家的帮助,我真的很感激!也许我需要更多地研究它,是否有一个很好的、广泛的资源,涵盖仅使用 cURL 方法从头到尾抓取网站?
猜你喜欢
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多