通过PHP/cURL实现HTTP Get 请求网页源文件

php cURL标志

当您成功装置XAMPP之后,我们就可以在PHP/MySQL环境生成PHP脚本索取网页源文件。PHP有很多函数库帮我们向伺服器发送请求及接收伺服器送回的文件,其中一个是我们将要用到的cURL。

现在我们先写一个间单的PHP/cURL类来协助我们向伺服器提出请求,之后我们才能向网页源文件“开刀”取出我们要的资料。我们也不时要改进我们的程序源码。

首先,在C:\xampp\htdocs下创建一个文件夹“scraper”,然后使用Notepad++在文件夹C:\xampp\htdocs\scraper创建一个文件httpcurl.php

如要Notepad++高亮显示编程语法,选择"Language"->"P"->"PHP"。

notepad++ 里打开httpcurl文件在httpcurl.php文件里:

<?php
class HttpCurl {
    private $_info, $_body, $_error;
public function __construct() {
    if (!function_exists('curl_init')) {
    throw new Exception('cURL not enabled!');
    }
}
public function get($url) {
    $this->request($url);
}
protected function request($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_URL, $url);
    $this->_body = curl_exec($ch);
    $this->_info = curl_getinfo($ch);
    $this->_error = curl_error($ch);
    curl_close($ch);
}
public function getStatus() {
    return $this->_info[http_code];
}
public function getHeader() {
    return $this->_info;
}
public function getBody() {
    return $this->_body;
}
public function __destruct() {
}
}
?>

 

如何现实

1. 首先我们创建cURL包装函式类HttpCurl,有三个私有变量,$_body,$_error 及$_info。

class HttpCurl {
private $_info, $_body, $_error;

 

2. 我们在HttpCurl类构造方法检查cURL是否在PHP配置中启用。如未启用脚本将显示错误信息。您需在php.ini扩展中启用cURL,然后重启XAMPP就行了。

3. 我们创建了公共方法get(),这会执行受保护方法request().

4. 在受保护方法request(),我们执行cURL函数向伺服器请求网页源文件。

首先,我们需要通过curl_init()初始化cURL及存储返回的句柄$ch。

基本上我们需要设置两个选项以向伺服器请求网页源文件。

curl_setopt($ch, CURLOPT_URL, $url) 告诉cURL我们要的网址在$url。

curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE) 告诉cURL将 curl_exec()获取的信息以文件流的形式返回,而不是直接输出。

5. 我们通过curl_exec($ch)执行cURL。函数执行成功时返回执行的结果将被存储在私有变量$_body中。

6. 采集资料前我们必须知道执行 curl_exec()的结果。我们可以执行 curl_getinfo() 然后存储在私有变量$_info。

7. 关闭cURL会话并且释放所有资源前,我们捡查是否有错误,可执行curl_error()然后存储在私有变量$_error。如无误则$_error为空。

8. 最后,执行curl_close()关闭cURL会话。在这阶段,我们已有网页源文件的资料。

接下来我们先试试这脚本,向伺服器发出请求。现在同一文件夹中再创建一个文件,test.php。 您可在视窗命令提示符执行test.php。不过这是个简单的程序,可在浏览器执行,只需输入以下网址:localhost/scraper/test.php.  

<?php
include 'httpcurl.php';
 
$target = "http://<domain name>";
 
$page = new HttpCurl();
$page->get($target);
 
echo " Web Page Header<br>";
print_r($page->getHeader());
echo "<br>";
echo " Web Page Status<br>";
print_r($page->getStatus());
echo "<br>";
echo " Web Page Body<br>";
print_r($page->getBody());
?>

 

首先,之前的文件httpcurl.php包含在test.php,然后用new创建了HttpCurl类的对象$page,然后执行函数get()发出请求。

伺服器输送回来资料中,有两部分是很重要的,一是报头,一是网页内容。

报头资料可从执行函数getHeader()取得。

将domain nam更换成google.com (您也可以试试别的网站域名), 结果是

Web Page Header

Array
(
   [url] => http://www.google.com/
   [content_type] => text/html; charset=ISO-8859-1
   [http_code] => 200
   [header_size] => 1114
   [request_size] => 102
   [filetime] => -1
   [ssl_verify_result] => 0
   [redirect_count] => 1
   [total_time] => 0.686
   [namelookup_time] => 0.031
   [connect_time] => 0.046
   [pretransfer_time] => 0.046
   [size_upload] => 0
   [size_download] => 51402
   [speed_download] => 74930
   [speed_upload] => 0
   [download_content_length] => 219
   [upload_content_length] => 0
   [starttransfer_time] => 0.093
   [redirect_time] => 0.094
   [certinfo] => Array
(
)

[redirect_url] => 
)

 

当中最重要的是http_code.

如果http_code数值是200,伺服器有回传完整网页源文件,我们就可开始采集资料。否则不能采集。

执行函数getStatus就可取得http_code数值。

Web Page Status
200

 

如果要知道回传的网页内容,可执行函数getBody()。如果您有浏览器在XAMPP环境下执行,您会看到内容和目标网站一样。这是因为浏览器试图翻译源文件的HTML标签。

google_httpcurl.jpg要查看实际的源文件,点击鼠标右键并选择“View Source”。

httpcurl采集google网页

理重定向

还有一件事情需先处里。

我们的目标网页可能设置重定向。更糟的是网站可能有意或无意间设下“蜘蛛陷阱”,如网页甲重定向去网页乙,网页乙又重定向去网页丙,那网页丙重定向回去网页甲,那我们的脚本尤如跌入“无间道”的无尽轮回。(当然PHP的最长执行时间会帮我们的脚本解套。)

再举个例子,将domain name更改为"php8legs.com",因为本站已设置重定向,视您的浏览器设置而定,网页重定向英文php8legs.com/en或中文php8legs.com/zh,这让脚本得不到网页源文件。

Web Page Header
Array
(
   [url] => http://php8legs.com
   [content_type] => text/html; charset=utf-8
   [http_code] => 301
   [header_size] => 315
   [request_size] => 51
   [filetime] => -1
   [ssl_verify_result] => 0
   [redirect_count] => 0
   [total_time] => 1.467
   [namelookup_time] => 0
   [connect_time] => 0.281
   [pretransfer_time] => 0.281
   [size_upload] => 0
   [size_download] => 0
   [speed_download] => 0
   [speed_upload] => 0
   [download_content_length] => 0
   [upload_content_length] => 0
   [starttransfer_time] => 1.467
   [redirect_time] => 0
   [certinfo] => Array
(
)

[redirect_url] => http://php8legs.com/en/
)

Web Page Status
301
Web Page Body

 

我们可以添加 CURLOPT_FOLLOWLOCATION 为 TURE, 以及CURLOPT_MAXREDIRS 为一个小数目。

$this->_options['CURLOPT_FOLLOWLOCATION'] = TRUE; 

$this->_options['CURLOPT_MAXREDIRS'] = 5; 

如以上例子,最多五次重定向后就会脱离循环。

所以HttpCurl类最后改为:

<?php
class HttpCurl {
    private $_info, $_body;
     
    public function __construct() {
        if (!function_exists('curl_init')) {
            throw new Exception('cURL not enabled!');
        }  
    }
    public function get($url) {
        $this->request($url);
    }

    protected function request($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);    
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_URL, $url);       
        $this->_body = curl_exec($ch);
        $this->_info  = curl_getinfo($ch);
        $this->_error = curl_error($ch);
        curl_close($ch);   
    }

    public function getStatus() {
        return $this->_info[http_code];
    }
     
    public function getHeader() {
        return $this->_info;
    }

    public function getBody() {
        return $this->_body;
    }
     
    public function __destruct() {
    }  
}
?>

 

接下来我们就可以向网页源文件开刀啦!

最后修改于 星期四, 03 11月 2016 06:36
给本项目评分
(1 投票)
返回顶部