資源描述:
《用ajax和php編寫簡單的蜘蛛程序》由會員上傳分享,免費在線閱讀,更多相關內(nèi)容在學術論文-天天文庫。
1、用AJAX和PHP編寫簡單的蜘蛛程序02/21/2011JAMESSHIH發(fā)表回復蜘蛛程序可以從網(wǎng)站上自動提取資料,從而極大地節(jié)省人力,所以現(xiàn)在蜘蛛程序現(xiàn)在用得非常多。不過一般的蜘蛛程序由于計算量比較大,通常用C#加上HTML分析庫來做。而對于簡單的任務,例如從成百上千頁的列表中提取數(shù)據(jù),那么用PHP來實現(xiàn)更簡單易行。用PHP編寫的蜘蛛程序還有一個好處,就是服務器能起到優(yōu)質代理服務器的作用,因為是通過服務器抓取目標網(wǎng)站的。一般托管主機都擁有優(yōu)秀的網(wǎng)絡接入質量,這對抓取速度有很大幫助。如果你擁有一個主機,特別是國外主機的話,這個好處嘛……你懂的。以一個從數(shù)百頁
2、的列表中提取出需要的數(shù)據(jù)的任務為例,這像是一個反過程,將網(wǎng)頁上的列表還原成數(shù)據(jù)庫表。程序主要有以下工作要做:1.獲得或生成URL2.下載目標頁面內(nèi)容3.分析頁面、提取數(shù)據(jù):4.將提取到的數(shù)據(jù)寫入數(shù)據(jù)庫或文件我的思路是將這個蜘蛛程序的控制功能放在客戶端,而具體執(zhí)行任務的功能放在服務器端。由客戶端的AJAX來監(jiān)視和控制服務器端的運行??蛻舳说墓ぷ鳎?.生成URL通過分析頁面,或從提取到的頁面中取得鏈接,可以確定下一頁的URL。例如“www.ex1.com/list.php?page=123”或“www.ex2.com/list-123.html”。由JavaSc
3、ript生成要提取的URL,并發(fā)送給服務器端。服務器端一次只負責處理一個頁面。2.存放和展示程序運行狀態(tài)用戶可以知道現(xiàn)在正在抓取哪一頁、抓取到了多少條數(shù)據(jù)、失敗重試的次數(shù)。如果用戶暫停程序,下次還可以繼續(xù)抓取。3.控制程序運行通過AJAX命令服務器端執(zhí)行提取、分析和儲存工作。在本例中,為了提高程序運行的穩(wěn)定性,沒有采用多線程設計,一次只請求一個頁面。所以定義了兩個函數(shù):fnRun()和fnGet()。fnRun()是“啟動/暫?!卑粹o的事件處理函數(shù)。它負責切換程序的運行和暫停狀態(tài),這是通過設置一個標志位bRunning來實現(xiàn)的。varbRunning=0,n
4、Retry=0,page=500;functionfnRun(){//當前處于停止狀態(tài)if(bRunning==0){bRunning=1;$(‘#btn’).val(‘暫停‘);//更改按鈕文字fnGet();}//當前處于運行狀態(tài)else{bRunning=0;$(‘#btn’).val(‘繼續(xù)‘);}}fnGet()則負責生成URL并創(chuàng)建AJAX請求,當AJAX請求完成(服務器端完成了工作)后,fnGet()遞歸調(diào)用,繼續(xù)處理下一頁。如果fnGet()遇到bRunning==0也就是用戶要求暫停時,則停止遞歸調(diào)用。functionfnGet(){if(
5、bRunning==0)return0;if(page<1){$(‘#btn’).val(‘完成‘).attr(‘disabled’,true);alert(‘祝賀您!抓取成功完成!’);return0;}$(‘#cur_page’).html(page);$.ajax({type:“GET”,url:“count.php”,data:“page=”+page–,beforeSend:function(jqXHR,settings){$(‘#busy’).show();//告訴用戶正在進行AJAX請求},success:function(data,textS
6、tatus,jqXHR){$(‘#busy’).hide();//告訴用戶AJAX請求已完成try{varjson=eval(‘(‘+data+’)’);}catch(oException){//網(wǎng)絡繁忙,頁面抓取有問題的處理varjson=newObject();json.msg=[];json.msg[0]=‘ERROR’;json.msg[1]=data;}if(json.msg[0]==‘S’){//成功獲取,更新抓取到的數(shù)據(jù)條數(shù)$(‘#cur_num’).html(json.num);fnGet();}else{page++;//要重試這一頁,所以
7、頁碼先加1nRetry++;//重試數(shù)加1$(‘#cur_retry’).html(nRetry);fnGet();}},error:function(jqXHR,textStatus,errorThrown){//與服務器端的通信出錯//TODO:錯誤處理}});}4.多線程控制如果感到服務器仍有余力,可以在客戶端同時創(chuàng)建多個AJAX請求,創(chuàng)建一個類來管理它們。服務器端的工作:1.下載目標頁面通過file_get_contents()下載頁面。以GET方式發(fā)送的參數(shù)只要加在URL后面就行了,但有時需要以POST方式發(fā)送,就要用stream_context_
8、create()做一個上下文:$url=‘http: