php的curl可以實現模擬http的各種請求,這也是php做網絡爬蟲的基礎,也多用於接口api的調用。
這個時候有人就要發問了:為什么你特么不用file_get_contents?
curl的性能比它好,而且可以完成更多復雜的操作,不僅僅只是獲取頁面數據。
下面先分別介紹一些常用的函數。
curl_init 初始化一個curl對話
curl_exec 執行請求
curl_close 關閉一個curl對話
curl_setopt 設置curl參數,即傳輸選項
curl_errno 返回最后一次錯誤碼,php已經定義了諸多錯誤枚舉編碼
curl_errror 返回一個保護當前會話最近一次錯誤的字符串
....
下面我先舉一個例子,簡單的get獲取我博客首頁的數據:
<?php /** * test get request * User: freephp * Date: 2015/10/8 * Time: 15:08 */ $ch = curl_init(); // 2. 設置選項,包括URL curl_setopt($ch, CURLOPT_URL, "http://www.cnblogs.com/freephp"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. 執行並獲取HTML文檔內容 $output = curl_exec($ch); // 4. 釋放curl句柄 curl_close($ch); print_r($output);
就可以打印出首頁的html代碼。
也可把內容寫入某個文件存儲,這不就是爬蟲的第一步么?
然后我們正則匹配過濾出文章的url,我封裝了一個方法:
/** * 從html內容中篩選鏈接 * * @param string $web_content * @return array */ function filterUrl($web_content){ $reg_tag_a = '/<[a|A].*?class="postTitle2".*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/'; $result = preg_match_all($reg_tag_a,$web_content,$match_result); if($result){ return $match_result[1]; } } print_r(filterUrl($output));
打印出來如圖:
然后再遍歷去請求這些url,然后拿到所有的文章內容。
(待續.....)
為了復用,我把curl請求發起,內容寫入文件,過濾得到文章內容等操作封裝成方法。最終的完整代碼如下:
<?php /** * test get request * User: freephp * Date: 2015/10/8 * Time: 15:08 */ /** * 獲取網頁源碼 * * @param $url get方式請求的url * @return mixed */ function getRquest($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. 執行並獲取HTML文檔內容 $output = curl_exec($ch); // 4. 釋放curl句柄 curl_close($ch); return $output; } /** * 從html內容中篩選鏈接 * * @param string $web_content * @return array */ function filterUrl($web_content) { $reg_tag_a = '/<[a|A].*?class="postTitle2".*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/'; $result = preg_match_all($reg_tag_a, $web_content, $match_result); if ($result) { return $match_result[1]; } } /** * 從html內容中篩選文章內容 * * @param string $content * @return array */ function filterContent($content) { $reg = '/<.*\"cnblogs_post_body\">(.*?)<\/div>/ism'; $result = preg_match_all($reg, $content, $match_result); if ($result) { return $match_result[1]; } } /** * 抓取文章內容寫入文件。 * * @param string $fileName 存儲文件名 * @param string $contents 文章內容 */ function writeToFile($fileName, $contents) { $fp = fopen($fileName, 'w'); fwrite($fp, $contents); fclose($fp); } $output = getRquest("http://www.cnblogs.com/freephp"); $articleUrls = filterUrl($output); if (empty($articleUrls)) { echo '獲取文章url失敗'; die(); } $articleNum = count($articleUrls); echo '總共文章為:', $articleNum, "\r\n"; foreach ($articleUrls as $url) { echo '開始爬取url:', $url, "\r\n"; $out = getRquest($url); $cont = filterContent($out); $filename = str_replace('.html', '', str_replace('http://www.cnblogs.com/freephp/p/', '', $url)); writeToFile($filename . '.txt', $cont[0]); echo '完成爬取url:', $url, "\r\n"; }
后面還會用使用post方式等用途的curl,等到那個時候再封裝成工具類吧。