申圣兵 劉家樂
摘 要:本文主要介紹_ViewState屬性值的動(dòng)態(tài)獲取方法,并通過教師課程表介紹它在ASP.NET網(wǎng)頁抓取中的應(yīng)用方法及注意事項(xiàng)。
關(guān)鍵詞:ViewState;網(wǎng)頁抓??;教師課程表
在Asp.net中,如果一個(gè)Web窗體控件設(shè)置了runat=”server”,這個(gè)控件會(huì)被附加一個(gè)隱藏的屬性_ViewState,_ViewState存放了所有控件在ViewState中的狀態(tài)值,這個(gè)值在網(wǎng)頁抓取分析并利用相關(guān)參數(shù)進(jìn)行模擬發(fā)送請(qǐng)求時(shí)是必不可少的,這個(gè)值在有些頁面取值相對(duì)固定,所以有些網(wǎng)頁抓取程序直接使用固定值,但更多的情況下,這個(gè)值需要?jiǎng)討B(tài)獲取。
下面以獲取教師課表信息為例,介紹如何動(dòng)態(tài)獲取這個(gè)值和使用它。
如果直接抓取當(dāng)前頁面,得不到任何有用信息,因?yàn)樗峭ㄟ^多次回傳來完成的。先選擇“學(xué)年”,才會(huì)出現(xiàn)系部名稱信息,選擇不同的系部,后面的教師信息也會(huì)發(fā)生改變,只有這些信息都選好后,點(diǎn)擊查詢,才能得到相應(yīng)教師的課表信息。
整個(gè)過程需要多次模擬網(wǎng)頁發(fā)送,網(wǎng)頁源碼中的_ViewState值也多次會(huì)發(fā)生改變,如何獲取這些_ViewState的值和使用它們,成為成功獲取教師課表信息的關(guān)鍵。
具體步驟如下:
(1)設(shè)置該屬性的標(biāo)記字符串
private static String viewStateFlag="name=\"__VIEWSTATE\" value=\"";
(2)設(shè)計(jì)獲取屬性值的函數(shù)
public static String getViewState(String strResult) {
//strResult為網(wǎng)頁源碼
int len1 = strResult.indexOf(viewStateFlag) + viewStateFlag.length();
int len2 = strResult.indexOf("\"", len1);
vs = new String(strResult.substring(len1, len2));
return vs;
}
(3)使用用戶的登陸信息,再調(diào)用HttpClient類的get方法模擬網(wǎng)頁以get方法提交參數(shù)來獲取第一次的_ViewState值vs1。
httpClient.get(url, params1, new AsyncHttpResponseHandler() )
//url:訪問的網(wǎng)址,params1:相關(guān)參數(shù),AsyncHttpResponseHandler:返回的相關(guān)信息成功后,再調(diào)用getViewState函數(shù)得到值vs1。
vs1=getViewState(strResult) //strResult為返回成功的網(wǎng)頁源碼
(4)經(jīng)過第一次get方法模擬提交網(wǎng)頁信息后,就可以得到網(wǎng)頁課表的學(xué)年信息,如2015-2016等。
(5)選擇學(xué)年及學(xué)期后,再將相關(guān)參數(shù)與vs1一起進(jìn)行封裝,模擬post方法提交網(wǎng)頁信息,得到第二次的_ViewState值vs2。
httpClient.post(url, params2, new AsyncHttpResponseHandler() )
(6)成功后就可以得到學(xué)院的系部信。
(7)由于選擇不同的系部,頁面會(huì)再一次進(jìn)行刷新,得到不同的教師列表信息,_ViewState的值也會(huì)發(fā)生改變,所以還要繼續(xù)獲取新的_ViewState的值。由于這一次提交的參數(shù)包含有中文信息,所以參數(shù)的封裝也有一些變化,需要提交的參數(shù)封裝后還需要重新編碼。
HttpEntity entity=new UrlEncodedFormEntity(params,"gb2312");
提交的方式也與前面的有所不同。
httpClient.post(TCourseQueryActivity.this, urlTCourse, entity, "application / x-www-form-urlencoded;charset=gb2312", new AsyncHttpResponseHandler())
成功后,再調(diào)用getViewState函數(shù)得到值vs3。
vs3=getViewState(strResult) //strResult為返回成功的網(wǎng)頁源碼
(8)最后,再將vs3與其他的參數(shù)一起進(jìn)行封裝,就可以得到真實(shí)的課表信息了。
結(jié)語
_ViewState雖然是一個(gè)隱藏的區(qū)域,但是它在網(wǎng)頁抓取的過程中是一個(gè)非常重要的參數(shù),有些頁面需要經(jīng)過多次提交回傳才能得到最終需要的數(shù)據(jù)信息,它的獲取相對(duì)復(fù)雜,本文提到的抓取教師課表就經(jīng)過了三次獲取_ViewState的值的過程,初始_ViewState的值vs1,選擇年份之后的_ViewState值vs2,選擇教師之后的_ViewState值vs3,最終獲取到教師課表信息。所以,熟練掌握_ViewState值的獲取方法是成功抓取.net網(wǎng)頁數(shù)據(jù)非常重要的一環(huán)。
參考文獻(xiàn):
[1] 莫學(xué)值.試析視圖狀態(tài)(ViewState)在ASP.NET中的應(yīng)用.廣西教育學(xué)院學(xué)報(bào),2009,03.
[2] 楊敏.關(guān)于Asp.net中static與ViewState使用的探討.吉林廣播電視大學(xué)學(xué)報(bào),2010,09.
[3] 翁巖青.網(wǎng)頁抓取策略研究.哈爾濱工程大學(xué),2010.