4

我试图通过过滤其源代码来获取网页上的一些数据,我发现了很多方法来获取网页的 html 内容,例如$html = file_get_html('http://www.exam.com/results/');curl html get source

获取页面的 html 源代码的最佳方法是什么?还是所有这些方法都一样?

4

4 回答 4

2

cURL 可能提供比file_get_contents($url)***** 更好的性能。我宁愿使用 cURL,因为所有这些功能最终都会检索某个网页内容,唯一的区别是运行时,正如我所说,使用 cURL 时更好。

*您可以在这里找到一个不错的(但不是正式的)证明,包括一个基准: https ://stackoverflow.com/questions/555523/file-get-contents-vs-curl-what-has-better-performance

于 2013-04-10T13:02:39.683 回答
2

这取决于您需要什么,但重要的是要记住,curl它将以文本形式返回响应,而file_get_html将返回一个Simple_HTML_DOM. 此外,我认为重要的是要注意幕后file_get_html调用file_get_contents

就个人而言,我有一个温和的偏好,首先将数据加载到内存中(我发现它更容易调试),但我通常不喜欢使用curl_*,除非我需要在请求中发送某种标头(POST 变量或WWW-Auth标头等)。对于其他所有事情,我发现它会将单行函数调用变成一团糟。所以我一般都是靠file_get_contents.

至于Simple_HTML_DOM,我想知道它是否可能比 PHP 本机编译库更快。您可以使用simplexml_load_file或访问这些内容DomDocument::loadHTMLFile

于 2013-04-10T13:05:18.430 回答
1

正如@itamar 建议的那样,cURL 提供了更多的控制。它允许您设置一些使用 file_get_contents 无法设置的内容,包括:

  • 代理使用
  • 标头
  • 永久 cookie 存储

它还允许您检索标题。

cURL 的使用相当复杂,但回报相当不错。建议是将其包装在一个函数中。我倾向于使用这个:

protected static function prepare_channel(Request $r) {
    $r->channel = curl_init();
    $p = array();
    foreach ($r->GET as $k => $v) {
        $p[] = $k."=".$v;
    }
    $head = array();
    foreach ($r->getHeaders() as $k => $v) {
        $head[] = $k.": ".$v;
    }
    curl_setopt($r->channel, CURLOPT_URL, $r->getURI()."?".implode("&",$p));
    curl_setopt($r->channel, CURLOPT_HTTPHEADER, $head);
    curl_setopt($r->channel, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($r->channel, CURLOPT_FORBID_REUSE, true);
    curl_setopt($r->channel, CURLOPT_RETURNTRANSFER, true);
    if (Request::getProxy()) {
        curl_setopt($r->channel, CURLOPT_PROXY, Request::getProxy());
    }
    curl_setopt($r->channel, CURLOPT_HEADER, true);
    return $r->channel;
}

这是实时代码,我的Request对象具有以下签名:

protected $headers = array();
protected $baseURI = "";
public $GET = array();
public $POST = array();

运行$result = curl_exec($r->channel);返回标题和正文。然后,您可以使用以下方法拆分它们:

 $header_size = curl_getinfo($r->channel, CURLINFO_HEADER_SIZE);
 $headers = substr($result, 0, $header_size);
 $body = substr($result, $header_size);

从那里,您可以自由地使用$header和做任何您喜欢的事情$body。您还可以通过运行 curl_getinfo($r->channel) 获得大量信息。

要在 PHP 中解析 HTML,最好先做两件事:

  • 放宽tidy它以清除格式错误的标记
  • 使用DOMDocument.
于 2013-04-10T13:10:04.330 回答
1

出于很多目的,一个 file_get_contents() 就足够了。但是在很多情况下,您需要特殊要求。

使用 PHP 流上下文:如果没有可用的 curl 并且您必须将 POST-Data 放入您的请求中,则可用

Curl:获取 HTTP 内容的瑞士军刀,通常效果最好。如果可能,您应该使用 curl 的一种特殊情况:如果您获取远程页面,您拥有的请求将被阻止。在这种情况下,您依赖于远程站点的性能。如果您使用像 Apache2 这样的网络服务器,其插槽数量有限,如果远程站点太慢或无法访问,它们可能会被填满。在这样的情况下,我经历了一些服务器宕机。Curl 通过为请求设置超时来帮助您。最好将其设置为低 3 秒。

但最好的方法是使用 cronjob 或类似的东西来获取外部内容,缓存它并使用缓存的版本。

于 2013-04-10T13:10:11.360 回答