为什么CodeIgniter的Curl库比使用纯PHP中的Curl慢?

6
最近,我把使用Curl的爬虫代码移植到了CodeIgniter中。我使用了来自http://philsturgeon.co.uk/code/codeigniter-curl的Curl CI库。我将爬虫过程放在了一个控制器中,但是我发现在CodeIgniter中执行爬虫的时间比我在纯PHP中构建的要慢。

输出结果需要12秒才能在CodeIgniter中完成,而在纯PHP中只需要6秒。两者都包括使用HTML DOM解析器进行解析的过程。

以下是我在CodeIgniter中的Curl代码:
function curl($url, $postdata=false)
{
  $agent = "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)";

  $this->curl->create($url);
  $this->curl->ssl(false);
  $options = array(
    'URL'             => $url,
    'HEADER'          => 0,
    'AUTOREFERER'     => true,
    'FOLLOWLOCATION'  => true,
    'TIMEOUT'         => 60,
    'RETURNTRANSFER'  => 1,
    'USERAGENT'       => $agent,
    'COOKIEJAR'       => dirname(__FILE__) . "/cookie.txt",
    'COOKIEFILE'      => dirname(__FILE__) . "/cookie.txt",
  );

  if($postdata)
  {
    $this->curl->post($postdata, $options);
  }
  else
  {
    $this->curl->options($options);
  }

  return $this->curl->execute();
}

非CodeIgniter(纯PHP)代码:

function curl($url, $binary=false, $post=false, $cookie=false) {

// 在这里编写curl功能代码

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Accepts all CAs
    curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 2); 

    curl_setopt ($ch, CURLOPT_URL, $url );
    curl_setopt ($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);



    if($cookie){


        $agent = "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)";
        curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__) . "/cookie.txt");
        curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__) . "/cookie.txt");

    }


    if($binary)
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);


    if($post){


        foreach($post as $key=>$value) 
            { 
        $post_array_string1 .= $key.'='.$value.'&'; 
        }
        $post_array_string1 = rtrim($post_array_string1,'&');

        //set the url, number of POST vars, POST data

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_array_string1);
    }

        return  curl_exec ($ch);

有人知道为什么这个CodeIgniter Curl比较慢吗?或者可能是因为simple_html_dom解析器的原因吗?


你能否发布一下非CodeIgniter的代码,这样我就可以自己测试了吗? - Brendan
是的,我在本地XAMPP上测试了相同的数据和大小,您说的100个连接测试是什么意思? - Maia Cube
12秒的时间是用于单次解析还是批处理?对象包装器和魔术方法使用(__call在这里)确实会有一些开销,但双倍时间似乎出乎意料。 - deej
什么是单次解析? - Maia Cube
以上所有人的意思是你需要运行一些大批量的负载来证明这两种方法的时间不同。 - Serg
显示剩余2条评论
2个回答

2

我不确定我知道这个问题的确切答案,但我对Curl和CI有一些观察,因为我经常使用它。

  1. 检查DNS缓存/查询状态。

当从我的开发桌面上传代码到托管的暂存服务器时,我注意到了显着的加速。这被追溯到一个DNS问题,通过重新启动堡垒主机解决...有时可以通过使用IP地址而非主机名来检查此问题。

  1. Phil的“库”实际上只是一个包装器。

他真正做的就是将CI风格的函数映射到PHP Curl库。几乎没有其他事情发生。我花了一些时间研究(我忘记为什么),结果很平庸。也就是说,在另一个类似的框架(Fuel、Kohana、Laravel等)中可能会出现一些普遍的CI开销,你可以看看会发生什么。

  1. 检查反向查找。

一些API在它们的安全扫描中进行反向DNS检查。有时主机名或其他标头在埋藏的配置中设置不当,可能会引起实际上的头痛。

  1. 使用Chrome的Postman扩展调试REST API。

没话说,这太棒了 - https://github.com/a85/POSTMan-Chrome-Extension/wiki,你可以对“对话”进行细粒度的控制。


0

我需要更多地了解 CI 库,以及它是否在收集的数据上执行任何额外的任务,但我会尝试将您的方法命名为其他名称,而不是库名称。我曾遇到过问题,使用 Facebook 库并将其调用为名为 facebook 的方法会导致问题。$this->curl 可能会产生歧义,无法确定您是在谈论库还是方法。

此外,请尝试添加调试分析器,看看它会出现什么情况。将其添加到构造或方法中:

$this->output->enable_profiler(TRUE);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接