這次抓取了110萬的使用者資料,資料分析結果如下:
開發前的準備
安裝linux系統(Ubuntu14.04),在VMWare虛擬機器下安裝一個Ubuntu;
安裝PHP5.6或以上版本;
安裝curl、pcntl擴充套件。
使用PHP的curl擴充套件抓取頁面資料
PHP的curl擴充套件是PHP支援的允許你與各種伺服器使用各種型別的協議進行連線和通訊的庫。
本程式是抓取知乎的使用者資料,要能訪問使用者個人頁面,需要使用者登入後的才能訪問。當我們在瀏覽器的頁面中點選一個使用者頭像連結進入使用者個人中心頁面的時候,之所以能夠看到使用者的資訊,是因為在點選連結的時候,瀏覽器幫你將本地的cookie帶上一齊提交到新的頁面,所以你就能進入到使用者的個人中心頁面。因此實現訪問個人頁面之前需要先獲得使用者的cookie資訊,然後在每次curl請求的時候帶上cookie資訊。在獲取cookie資訊方面,我是用了自己的cookie,在頁面中可以看到自己的cookie資訊:
一個個地複製,以"__utma=?;__utmb=?;"這樣的形式組成一個cookie字串。接下來就可以使用該cookie字串來傳送請求。
初始的示例:
$url = 'http://www.zhihu.com/people/mora-hu/about';
//此處mora-hu代表使用者ID $ch = curl_init($url);
//初始化會話 curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_COOKIE, $this->config_arr['user_cookie']);
//設定請求COOKIE curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //將curl_exec()獲取的資訊以檔案流的形式返回,而不是直接輸出。 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$result = curl_exec($ch);
return $result; //抓取的結果
執行上面的程式碼可以獲得mora-hu使用者的個人中心頁面。利用該結果再使用正規表示式對頁面進行處理,就能獲取到姓名,性別等所需要抓取的資訊。
圖片防盜鏈
在對返回結果進行正則處理後輸出個人資訊的時候,發現在頁面中輸出使用者頭像時無法開啟。經過查閱資料得知,是因為知乎對圖片做了防盜鏈處理。解決方案就是請求圖片的時候在請求頭裡偽造一個referer。
在使用正規表示式獲取到圖片的連結之後,再發一次請求,這時候帶上圖片請求的來源,說明該請求來自知乎網站的轉發。具體例子如下:
function getImg($url, $u_id){
if (file_exists('./images/' . $u_id . ".jpg"))
{
return "images/$u_id" . '.jpg'; } if (empty($url))
{
return '';
}
$context_options = array(
'http' => array(
'header' => "Referer:http://www.zhihu.com"//帶上referer引數 )
);
$context = stream_context_create($context_options);
$img = file_get_contents('http:' . $url, FALSE, $context);
file_put_contents('./images/' . $u_id . ".jpg", $img);
return "images/$u_id" . '.jpg';}
爬取更多使用者
抓取了自己的個人資訊後,就需要再訪問使用者的關注者和關注了的使用者列表獲取更多的使用者資訊。然後一層一層地訪問。可以看到,在個人中心頁面裡,有兩個連結如下:
這裡有兩個連結,一個是關注了,另一個是關注者,以“關注了”的連結為例。用正則匹配去匹配到相應的連結,得到url之後用curl帶上cookie再發一次請求。抓取到使用者關注了的用於列表頁之後,可以得到下面的頁面:
分析頁面的html結構,因為只要得到使用者的資訊,所以只需要框住的這一塊的div內容,使用者名稱都在這裡面。可以看到,使用者關注了的頁面的url是:
不同的使用者的這個url幾乎是一樣的,不同的地方就在於使用者名稱那裡。用正則匹配拿到使用者名稱列表,一個一個地拼url,然後再逐個發請求(當然,一個一個是比較慢的,下面有解決方案,這個稍後會說到)。進入到新使用者的頁面之後,再重複上面的步驟,就這樣不斷迴圈,直到達到你所要的資料量。