什麼叫採集?
就是使用PHP程序,把其餘網站中的信息抓取到咱們本身的數據庫中、網站中。php
PHP製做採集的技術:html
從底層的socket到高層的文件操做函數,一共有3種方法能夠實現採集。數據庫
1. 使用socket技術採集:編程
socket採集是最底層的,它只是創建了一個長鏈接,而後咱們要本身構造http協議字符串去發送請求。數組
例如要想獲取這個頁面的內容,http://tv.youku.com/?spm=a2hww.20023042.topNav.5~1~3!2~A,用socket寫以下:瀏覽器
- <?php
- $fp=fsockopen("www.youku.com",80,$errno,$errstr,30);
- if(!$fp) die("鏈接失敗".$errstr);
-
- $http="GET /?spm=a2hww.20023042.topNav.5~1~3!2~A HTTP/1.1\r\n";
- $http.="Host:www.youku.com\r\n";
- $http.="Connection:close\r\n\r\n";
-
- fwrite($fp,$http,strlen($http));
- $data='';
- while (!feof($fp)) {
- $data.=fread($fp,4096);
- }
- fclose($fp);
- var_dump($data);
- ?>
打印出的結果以下,包含了返回的頭信息及頁面的源碼:服務器
![](http://static.javashuo.com/static/loading.gif)
2. 使用curl_一套函數網絡
curl把HTTP協議都封裝成了不少函數,直接傳相應參數便可,下降了編寫HTTP協議字符串的難度。curl
前提:在php.ini中要開啓curl擴展。socket
- $curl=curl_init();
- curl_setopt($curl, CURLOPT_URL, "http://www.youku.com");
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- $data=curl_exec($curl);
- var_dump($data);
打印出的結果以下,只包含頁面的源碼:
![](http://static.javashuo.com/static/loading.gif)
3. 直接使用file_get_contents(最頂層的)
前提:在php.ini中設置容許打開一個網絡的url地址。
![](http://static.javashuo.com/static/loading.gif)
- $data=file_get_contents("http://www.youku.com");
- var_dump($data);
![](http://static.javashuo.com/static/loading.gif)
3種方式的選擇
網絡之間通訊主要使用的是以上三種。其中後兩種用的較多:若是要批量採集大量的數據時使用第二種【CURL】,性能好、穩定。
偶爾發幾個請求發的頻繁不密集時使用第三種。
擴展:圖片的防盜鏈如何破?
好比7060網站上的圖片作了防盜鏈:在他的網站中能夠看到圖片,把圖片拿到站外就沒法訪問。
![](http://static.javashuo.com/static/loading.gif)
原理:在HTTP協議中有一個referer項,表明發這個請求的來源地址,服務器會判斷若是這個請求不是這個網站發來的就會過濾掉這個請求:
![](http://static.javashuo.com/static/loading.gif)
解決辦法:發HTTP時本身模擬referer便可:
![](http://static.javashuo.com/static/loading.gif)
擴展:有些要採集數據時時必須先登陸,能夠使用模擬的試模擬在登陸狀態下的採集:
a. 先用瀏覽登陸一下,登陸完,瀏覽器的COOKIE中就會有SESSIONID
b. 發PHP發HTTP協議時,把瀏覽器中的SESSIONID放到PHP的HTTP協議請求裏,這樣就在以登陸的狀態發請求。
總結:全部客戶端發過來的數據均可以被模擬,因此服務器上的程序必需要必要的地方過濾客戶端的數據。
何時用以上東西?接口開發時、採集時。
2、數據採集
例如我要採集這個url裏的全部美國電影的信息,
http://list.youku.com/category/show/c_96_a_%E7%BE%8E%E5%9B%BD_s_1_d_1_p_3.html
則先要知道電影所在的節點的結構,咱們使用firebug查看。
![](http://static.javashuo.com/static/loading.gif)
而後開始寫代碼:完整代碼以下
- function get($url)
- {
- global $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_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_preg = '/<img class="quic" _src="(.*)" src="(.*)" alt="(.*)" \/>/U';
- $video_preg='/<a href="(.*)" title="(.*)" target="(.*)"><\/a>/U';
- preg_match_all($list_preg,$data,$list);
-
- foreach ($list[0] as $k => $v) {
-
- preg_match($img_preg,$v,$img);
- preg_match($video_preg,$v,$video);
- echo $img[0].'<a href="'.$video[1].'">'.$video[2].'</a>';
- }
測試:
打印$list;
![](http://static.javashuo.com/static/loading.gif)
打印$img
![](http://static.javashuo.com/static/loading.gif)
打印$video
![](http://static.javashuo.com/static/loading.gif)
最終效果:
![](http://static.javashuo.com/static/loading.gif)
若是須要把圖片拷貝到硬盤上,則在foreach循環里加上如下代碼:
- $imgData = get($img[1]);
-
-
- is_dir('./youkuimg/') ? '': mkdir('./youkuimg/');
- file_put_contents('./youkuimg/'.mb_convert_encoding($img[3], 'gbk', 'utf-8').'.jpg', $imgData);
![](http://static.javashuo.com/static/loading.gif)
效果以下:在當前目錄下的youkuimg目錄下就會有下載好的圖片。
![](http://static.javashuo.com/static/loading.gif)