以上為背景```
----
### PHP 寫爬蟲 ###
說實話我也想用Python的,畢竟人家招牌。無奈我Python還停留在看語法的階段,實在太慚愧,鞭笞一下自己加油學習。這里用php的CURL庫進行頁面抓取。
同事使用的系統需要先登錄,然后有很多自定義圖表。每個圖表有一個`graph_id`,根據`graph_id`可以導出某段時間的csv格式報表以及對應的圖形png。
#### 1. 登錄cookie ####
可能做爬蟲遇到的第一關就是登錄了,通常你要抓取的網頁需要先驗證登錄用戶。我們知道通常用戶會話狀態都是通過`SessionID`來識別,而`SessionID`通過`cookie`保存到客戶端。所以當你要先登錄在抓取頁面的時候,先請求登錄接口,獲取到`cookie`保存到本地,后面抓取內容的時候每次帶上這個`cookie`文件就可以了。保存`cookie`的CURL選項*`CURLOPT_COOKIEJAR`*:
# 保存cookie的代碼
$this->cookie_file = '/tmp/cookie.curl.tmp';
curl_setopt($ch, CURLOPT_COOKIEJAR , $this->cookie_file);
然后頁面抓取的時候通過設置*`CURLOPT_COOKIEFILE`*帶上這個cookie:
# 設置cookie的代碼
curl_setopt($ch, CURLOPT_COOKIEFILE , $this->cookie_file);
#### 2. 頁面重定向 ####
解決了會話session的問題,第二的頭疼的就是`302`和`301`重定向了。重定向的頁面response一般沒有body部分,頭部大概長這樣:
HTTP/1.1 302 Found
Date: Thu, 29 Jun 2017 09:49:51 GMT
Server: Apache/2.2.15 (CentOS)
...
Location: curl_test.php?action=real_page
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8
那怎么辦呢?仔細觀察頭部信息可以發現里面包含了重定向的目標頁面`Location: xxx...`。而CURL可以通過`curl_getinfo($ch, CURLINFO_HTTP_CODE)`來獲取http狀態碼,到這里似乎就很清楚接下來該干嘛了。
// 獲取的curl結果
$re = curl_exec($ch);
list ($header, $body) = explode("\r\n\r\n", $re, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 有的網站會檢查referer地址來判斷是否請求來自重定向,這里保存上次請求的url供重定向構造referer使用
$last_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
curl_close($ch);
if ($http_code == 301 || $http_code == 302) {
if (preg_match('/Location:(.*?)\n/', $header, $matches)) {
// 繼續抓取目標頁面
$urlinfo = parse_url($url);
// 這里match的url地址可能不一樣,所以不一定這么簡單的拼接就行
$re_url = $urlinfo['scheme'] . '://' . $urlinfo['host'] . substr($urlinfo['path'], 0, strrpos($urlinfo['path'], '/')+1) . trim($matches[1]);
return $this->_http_get($re_url, $last_url);
} else {
return FALSE;
}
} else if ($http_code == 200) {
return $body;
} else {
echo 'Error: CURL failed.[url='.$url.']; [http code= '. $http_code.']';
return FALSE;
}
有的網站會檢查referer地址來判斷是否請求來自重定向,通過設置curl的`CURLOPT_REFERER`參數來偽造`HTTP_REFERER`。
### 小結 ###
以上可以說是最最基礎的爬蟲知識,至於正則這里就不介紹了。再往后可能就是下載內容根據Content-type判斷文件類型,抓取效率問題,反爬蟲策略。總之爬蟲就是盡量模擬用戶的行為去抓取頁面,反爬蟲就是盡量挑出哪些請求是爬蟲哪些不是,彼此斗智斗勇。等哪天有對爬蟲更深入的研究的時候再繼續說吧,就到這里了。