基於curl資料擷取之單頁面並行採集函數get_htmls的使用

來源:互聯網
上載者:User

用第一篇的get_html()實現簡單的資料擷取,由於是一個一個執行才採集資料的傳輸時間就會是所有頁面下載的總時間長度,一個頁面假設1秒,那麼10個頁面就是10秒了。所幸curl還提供了平行處理的功能。

要寫一個並行採集的函數,先要瞭解要採集什麼樣的頁面,對採集的頁面用什麼請求,才能寫出一個相對常用的函數。

功能需求分析:

返回什嗎?

當然每一個頁面的html集合成的數組

傳遞什麼參數?

編寫get_html()時,我們知道了可以用options數組來傳遞更多的curl參數,那麼多頁面同時採集函數的編寫這種特性也得保留下來。

什麼類型的參數?

無論是請求網頁HTML,還是調用互連網api介面,get和post傳遞參數總是請求同一個頁面或者介面,只是參數不同罷了。那麼參數的類型是:

get_htmls($url,$options);

$url 是string

$options,是一個二維數組,每一個頁面的參數為一個數組。

這樣的話,貌似解決了問題。但是我找遍了curl的手冊都沒有看到get的參數傳遞在什麼地方,所以只能$url 是數組的形式傳遞並且增加一個method參數

函數的原型就定下來了get_htmls($urls,$options = array, $method = ‘get');代碼如下:

複製代碼 代碼如下:function get_htmls($urls, $options = array(), $method = 'get'){
$mh = curl_multi_init();
if($method == 'get'){//get方式傳值 最常用
foreach($urls as $key=>$url){
$ch = curl_init($url);
$options[CURLOPT_RETURNTRANSFER] = true;
$options[CURLOPT_TIMEOUT] = 5;
curl_setopt_array($ch,$options);
$curls[$key] = $ch;
curl_multi_add_handle($mh,$curls[$key]);
}
}elseif($method == 'post'){//post方式傳值
foreach($options as $key=>$option){
$ch = curl_init($urls);
$option[CURLOPT_RETURNTRANSFER] = true;
$option[CURLOPT_TIMEOUT] = 5;
$option[CURLOPT_POST] = true;
curl_setopt_array($ch,$option);
$curls[$key] = $ch;
curl_multi_add_handle($mh,$curls[$key]);
}
}else{
exit("參數出錯!\n");
}
do{
$mrc = curl_multi_exec($mh,$active);
curl_multi_select($mh);//減少CPU壓力 注釋掉CPU壓力變大
}while($active);
foreach($curls as $key=>$ch){
$html = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh,$ch);
curl_close($ch);
$htmls[$key] = $html;
}
curl_multi_close($mh);
return $htmls;
}

常用的get請求是通過改變url參數來實現的,又因為我們的函數是針對資料擷取的。必然是分類採集,所以網址類似於這種:

http://www.baidu.com/s?wd=shili&pn=0&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=10&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=20&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=30&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=50&ie=utf-8

上面五個頁面是很有規律的,改變的僅僅是pn的值。

複製代碼 代碼如下:$urls = array();
for($i=1; $i<=5; $i++){
$urls[] = 'http://www.baidu.com/s?wd=shili&pn='.(($i-1)*10).'&ie=utf-8';
}
$option[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0';
$htmls = get_htmls($urls,$option);
foreach($htmls as $html){
echo $html;//這裡得到html 就可以進行資料處理了
}

類比常用的post請求:

寫一個post.php檔案如下:

複製代碼 代碼如下: if(isset($_POST['username']) && isset($_POST['password'])){
echo '使用者名稱是: '.$_POST['username'].' 密碼是: '.$_POST['password'];
}else{
echo '請求錯誤!';
}

然後調用如下:複製代碼 代碼如下:$url = 'http://localhost/yourpath/post.php';//這裡是你的路徑
$options = array();
for($i=1; $i<=5; $i++){
$option[CURLOPT_POSTFIELDS] = 'username=user'.$i.'&password=pass'.$i;
$options[] = $option;
}
$htmls = get_htmls($url,$options,'post');
foreach($htmls as $html){
echo $html;//這裡得到html 就可以進行資料處理了
}

這樣這個get_htmls函數也基本能實現一些資料擷取的功能了

今天分享就到這裡 寫的不好的 講得不清楚的 請多多指教

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.