PHP實現資料擷取的三種方法

來源:互聯網
上載者:User

什麼叫採集?

就是使用PHP程式,把其他網站中的資訊抓取到我們自己的資料庫中、網站中。

PHP製作採集的技術:

從底層的socket到高層的檔案操作函數,一共有3種方法可以實現採集。

1. 使用socket技術採集:

socket採集是最底層的,它只是建立了一個長串連,然後我們要自己構造http協議字串去發送請求。

例如要想擷取這個頁面的內容,tv.youku.com/?spm=a2hww.20023042.topNav.5~1~3!2~A,用socket寫如下:

<?php//串連,$error錯誤編號,$errstr錯誤的字串,30s是連線逾時時間$fp=fsockopen("www.youku.com",80,$errno,$errstr,30);if(!$fp) die("串連失敗".$errstr); //構造http協議字串,因為socket編程是最底層的,它還沒有使用http協議$http="GET /?spm=a2hww.20023042.topNav.5~1~3!2~A HTTP/1.1\r\n";   //  \r\n表示前面的是一個命令$http.="Host:www.youku.com\r\n";  //請求的主機$http.="Connection:close\r\n\r\n";   // 串連關閉,最後一行要兩個\r\n //發送這個字串到伺服器fwrite($fp,$http,strlen($http));//接收伺服器返回的資料$data='';while (!feof($fp)) {$data.=fread($fp,4096);  //fread讀取返回的資料,一次讀取4096位元組}//關閉串連fclose($fp);var_dump($data);?>

列印出的結果如下,包含了返回的頭資訊及頁面的源碼:

2. 使用curl_一套函數

curl把HTTP協議都封裝成了很多函數,直接傳相應參數即可,降低了編寫HTTP協議字串的難度。

前提:在php.ini中要開啟curl擴充。

//產生一個curl對象$curl=curl_init();//設定URL和相應的選項curl_setopt($curl, CURLOPT_URL, "http://www.youku.com");curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  //將curl_exec()擷取的資訊以字串返回,而不是直接輸出。//執行curl操作$data=curl_exec($curl);var_dump($data);

列印出的結果如下,只包含頁面的源碼:

3. 直接使用file_get_contents(最頂層的)

前提:在php.ini中設定允許開啟一個網路的url地址。

//使用file_get_contents()$data=file_get_contents("http://www.youku.com");var_dump($data);


3種方式的選擇

網路之間通訊主要使用的是以上三種。其中後兩種用的較多:如果要批量採集大量的資料時使用第二種【CURL】,效能好、穩定。

偶爾發幾個請求發的頻繁不密集時使用第三種。

擴充:圖片的防盜鏈如何破?

比如7060網站上的圖片做了防盜鏈:在他的網站中可以看到圖片,把圖片拿到站外就無法訪問。

原理:在HTTP協議中有一個referer項,代表發這個請求的來源地址,伺服器會判斷如果這個請求不是這個網站發來的就會過濾掉這個請求:

解決辦法:發HTTP時自己類比referer即可:

擴充:有些要採集資料時時必須先登入,可以使用類比的試類比在登入狀態下的採集:

a. 先用瀏覽登入一下,登入完,瀏覽器的COOKIE中就會有SESSIONID

b. 發PHP發HTTP協議時,把瀏覽器中的SESSIONID放到PHP的HTTP協議請求裡,這樣就在以登入的狀態發請求。

總結:所有用戶端發過來的資料都可以被類比,所以伺服器上的程式必須要必要的地方過濾用戶端的資料。

什麼時候用以上東西?介面開發時、採集時。

二、資料擷取

例如我要採集這個url裡的所有美國電影的資訊,

list.youku.com/category/show/c_96_a_%E7%BE%8E%E5%9B%BD_s_1_d_1_p_3.html

則先要知道電影所在的節點的結構,我們使用firebug查看。

然後開始寫代碼:完整代碼如下

/** * 發一個GET請求擷取資料 */function get($url){   global $curl;   // 配置curl中的http協議->可配置的薦可以查PHP手冊中的curl_   curl_setopt($curl, CURLOPT_URL, $url);   curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);   curl_setopt($curl, CURLOPT_HEADER, FALSE);   // 執行這個請求   return curl_exec($curl);} // 產生一個curl對象$curl = curl_init();$url='http://list.youku.com/category/show/c_96_a_%E7%BE%8E%E5%9B%BD_s_1_d_1_p_3.html';$data=get($url);// 匹配電影所在位置$list_preg = '/<li class="yk-col4 mr1">.+<\/li>/Us';// 匹配img標籤上的src和alt$img_preg = '/<img class="quic" _src="(.*)" src="(.*)" alt="(.*)" \/>/U';//匹配電影的url$video_preg='/<a href="(.*)" title="(.*)" target="(.*)"><\/a>/U';//把所有的li存到$list裡,$list是個二維數組preg_match_all($list_preg,$data,$list);   //var_dump($list);foreach ($list[0] as $k => $v) {   //這裡$v就是每一個li標籤/* 擷取圖片及電影名稱    preg_match($img_preg,$v,$img);  //把匹配到的圖片的資訊存到$img裡    var_dump($img);    */    /*擷取電影地址    preg_match($video_preg,$v,$video);  //把匹配到的電影的資訊存到$video裡    var_dump($video);*/    preg_match($img_preg,$v,$img);    preg_match($video_preg,$v,$video);    echo $img[0].'<a href="'.$video[1].'">'.$video[2].'</a>';}

測試:

列印$list;

列印$img

列印$video

最終效果:

如果需要把圖片拷貝到硬碟上,則在foreach迴圈裡加上以下代碼:

 $imgData = get($img[1]);    // 把圖片檔案寫到硬碟上【下載】    // 因為作業系統是GBK的,所以要把UTF8轉成GBK    is_dir('./youkuimg/') ? '': mkdir('./youkuimg/');file_put_contents('./youkuimg/'.mb_convert_encoding($img[3], 'gbk', 'utf-8').'.jpg', $imgData);


效果如下:在目前的目錄下的youkuimg目錄下就會有下載好的圖片。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.