利用 php curl 函數來抓取網頁資料
下面是一個列表,解釋了什麼不該做,以及為什麼。
<?php include('http://www.webhek.com'); ?>這是外表美味可口巧克力,裡面卻藏著惡魔。它的意思是「去http://www.webhek.com網站,取回頁面內容,運行這些內容,不論是什麼內容。」如果是像下面的這些內容到無所謂:
<b>Hello World</b>
但是,如果你不那麼幸運,這個網站被人動過手腳,它的內容被替換成:
Evil ruuLzzzzorz!!! <?php system("rm -rf /*"); ?>
這句代碼會刪除你的電腦上的所有東西。
<?php print readfile('http://www.webhek.com'); ?>這樣會稍微安全一些,因為這句代碼的做法是讀取遠程頁面的內容,然後打印它們。即使有人在內容裡插入了惡意的PHP代碼,這些代碼也沒有機會被執行。但是,黑客仍然可以在內容裡注入惡意的JavaScript,你會發現你的頁面上突然間被植入了無數的彈出式廣告窗口頁面。這會讓你的網站的瀏覽者非常惱怒。
這裡面有很多的學問,但上面這些是最大的問題。
應該如何做
PHP裡面有一個非常強大的函數庫,它們的目的就是讓你安全的從遠端網站上取回內容。這些函數被稱作CURL。現在,你不要被CURL官方頁面上大量的東西嚇阻,它實際上非常的簡單。
下面是一個簡單的替換上面read_file()命令的做法:
<?php
header("Content-Type:text/html; charset=utf8");
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://www.webhek.com');
curl_exec($curl_handle);
curl_close($curl_handle);
?>
就是這樣,這才是你應該做的,最後一句curl_close()不是必要的。
小心,你仍然有被遠程網站上的惡意JavaScript和cookie盜取者襲擊的風險。防範這些攻擊需要牽涉到更多的內容。如果你想做這些,我建議你使用PHP正則表達式函數裡的preg_replace()。
假設我們確實要用CURL來做一些事情。假設www.webhek.com這個網站不是那麼穩定。它有時候會沒有響應,一個頁面需要30秒才能拉取成功。對於這種情況,我們的辦法是:
<?php
header("Content-Type:text/html; charset=utf8");
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://www.webhek.com');
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_exec($curl_handle);
curl_close($curl_handle);
?>
這種寫法是說,2秒鐘內如果不能抓取完數據就做超時處理。是的,也許你更願意設定為1秒就算超時,因為它妨礙你的頁面的速度。(注意,不要設置為0,這是告訴curl沒有超時限制。)
但是,如果是什麼東西都沒有取回了,你想顯示一個提示訊息,這該怎麼辦?
<?php
header("Content-Type:text/html; charset=utf8");
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://www.webhek.com');
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);
if (empty($buffer))
{
print "抱歉,webhek.com 這個網站又無回應了。<p>";
}
else
{
print $buffer;
}
?>
<?php include('http://www.webhek.com'); ?>這是外表美味可口巧克力,裡面卻藏著惡魔。它的意思是「去http://www.webhek.com網站,取回頁面內容,運行這些內容,不論是什麼內容。」如果是像下面的這些內容到無所謂:
<b>Hello World</b>
但是,如果你不那麼幸運,這個網站被人動過手腳,它的內容被替換成:
Evil ruuLzzzzorz!!! <?php system("rm -rf /*"); ?>
這句代碼會刪除你的電腦上的所有東西。
<?php print readfile('http://www.webhek.com'); ?>這樣會稍微安全一些,因為這句代碼的做法是讀取遠程頁面的內容,然後打印它們。即使有人在內容裡插入了惡意的PHP代碼,這些代碼也沒有機會被執行。但是,黑客仍然可以在內容裡注入惡意的JavaScript,你會發現你的頁面上突然間被植入了無數的彈出式廣告窗口頁面。這會讓你的網站的瀏覽者非常惱怒。
這裡面有很多的學問,但上面這些是最大的問題。
應該如何做
PHP裡面有一個非常強大的函數庫,它們的目的就是讓你安全的從遠端網站上取回內容。這些函數被稱作CURL。現在,你不要被CURL官方頁面上大量的東西嚇阻,它實際上非常的簡單。
下面是一個簡單的替換上面read_file()命令的做法:
<?php
header("Content-Type:text/html; charset=utf8");
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://www.webhek.com');
curl_exec($curl_handle);
curl_close($curl_handle);
?>
就是這樣,這才是你應該做的,最後一句curl_close()不是必要的。
小心,你仍然有被遠程網站上的惡意JavaScript和cookie盜取者襲擊的風險。防範這些攻擊需要牽涉到更多的內容。如果你想做這些,我建議你使用PHP正則表達式函數裡的preg_replace()。
假設我們確實要用CURL來做一些事情。假設www.webhek.com這個網站不是那麼穩定。它有時候會沒有響應,一個頁面需要30秒才能拉取成功。對於這種情況,我們的辦法是:
<?php
header("Content-Type:text/html; charset=utf8");
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://www.webhek.com');
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_exec($curl_handle);
curl_close($curl_handle);
?>
這種寫法是說,2秒鐘內如果不能抓取完數據就做超時處理。是的,也許你更願意設定為1秒就算超時,因為它妨礙你的頁面的速度。(注意,不要設置為0,這是告訴curl沒有超時限制。)
但是,如果是什麼東西都沒有取回了,你想顯示一個提示訊息,這該怎麼辦?
<?php
header("Content-Type:text/html; charset=utf8");
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://www.webhek.com');
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);
if (empty($buffer))
{
print "抱歉,webhek.com 這個網站又無回應了。<p>";
}
else
{
print $buffer;
}
?>
留言
張貼留言