我试图通过过滤其源代码在网页上获得一些数据,我发现了很多方法来抓取网页的html内容,如$html = file_get_html('http://www.exam.com/results/');
, curl, html获取源。
获取一个页面的html源代码的最好方法是什么?还是所有这些方法都是一样的?
cURL可能比file_get_contents($url)
*****提供更好的性能。我更愿意使用cURL,因为所有这些函数最终都会检索到特定的网页内容,唯一的区别是运行时间,正如我所说的,使用cURL时运行时间更好。
*你可以在这里找到一个像样的(但不是正式的)证明,包括一个基准:https://stackoverflow.com/questions/555523/file-get-contents-vs-curl-what-has-better-performance
这取决于您需要什么,但重要的是要记住,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
访问它们。
对于很多用途,一个file_get_contents()就足够了。但是在很多情况下,你需要特殊的要求。
使用PHP流上下文:如果没有curl可用,并且您必须在请求中放置POST-Data
Curl:获取http内容的瑞士军刀,通常效果最好。如果可能的话,有一种特殊情况您应该使用curl:如果您获取远程页面,您自己的请求被阻塞。在这种情况下,您依赖于远程站点的性能。如果您使用的是像Apache2这样具有有限插槽的web服务器,那么如果远程站点太慢或无法访问,它们可能会被填满。我遇到过一些类似的服务器宕机情况。Curl通过为请求设置超时来帮助您。最好把它设置得低一点,比如3秒。
但是最好的方法是使用cronjob或类似的方法获取外部内容,缓存它并使用缓存的版本。
cURL提供了更多的控制,正如@itamar所建议的那样。它允许您设置一些使用file_get_contents无法设置的内容,包括:
- 代理使用
- <
- 头/gh>
- 永久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)获得大量信息。
- 让
tidy
松开它以清除格式错误的标记 - 使用
DOMDocument
解析