999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

Java開(kāi)發(fā):實(shí)現(xiàn)網(wǎng)站信息批量析取

2007-01-01 00:00:00劉大勇
現(xiàn)代商貿(mào)工業(yè) 2007年2期

摘 要:使用java字符串處理和多線程并發(fā)技術(shù),構(gòu)造實(shí)用的頁(yè)面解析工具,實(shí)現(xiàn)網(wǎng)站內(nèi)容高效、低噪地批量析取。

關(guān)鍵詞:噪音;線程;析取

隨著網(wǎng)絡(luò)應(yīng)用的普及、使用、加工網(wǎng)站信息的需求日益增多,如何方便、及時(shí)、快捷的獲取互聯(lián)網(wǎng)網(wǎng)站的信息成為網(wǎng)絡(luò)編程開(kāi)發(fā)的一項(xiàng)新課題。近年來(lái),java技術(shù)在網(wǎng)絡(luò)編程領(lǐng)域悄然興起,在各種開(kāi)源產(chǎn)品的支持下,java技術(shù)的應(yīng)用如火如荼,網(wǎng)站信息的析取方面,出現(xiàn)了DOM、SAX等成熟的開(kāi)發(fā)技術(shù),這些技術(shù)的基本特征是先格式化網(wǎng)站頁(yè)面,再使用標(biāo)簽?zāi)0暹^(guò)濾析取相關(guān)內(nèi)容,但是了解并掌握這些技術(shù)需要有較高的java開(kāi)發(fā)水平,對(duì)于java的初學(xué)者來(lái)說(shuō)學(xué)習(xí)消化的周期比較長(zhǎng),難以上手。

筆者曾利用字符串處理等較易掌握的技術(shù)開(kāi)發(fā)出了網(wǎng)站信息的批量析取系統(tǒng),在實(shí)際工作中取得了較好的應(yīng)用效果,在此共享出來(lái),供各位讀者參考。

1 網(wǎng)站頁(yè)面析取

這是系統(tǒng)功能實(shí)現(xiàn)的基礎(chǔ),把網(wǎng)站頁(yè)面轉(zhuǎn)換為可以操作的字符串形式,這里使用了一款開(kāi)源產(chǎn)品HTMLPARSER,筆者通過(guò)實(shí)際測(cè)試,發(fā)現(xiàn)HTMLPARSER比其他同類產(chǎn)品(如Jtidy等)的容錯(cuò)性、通用性更好,解析頁(yè)面的完整度更高,具體做法如下:

1.1 構(gòu)造解析器

這里采用LinkTag.class格式解析頁(yè)面中的部分,可以解析到j(luò)avascript的跳轉(zhuǎn)代碼,而HTMLPARSER中推薦的StringExtractor用法只能解析到部分,所以系統(tǒng)使用LinkTag.class作為頁(yè)面解析格式。

核心代碼如下:

NodeFilter filter = new NodeClassFilter(LinkTag.class);

Parser parser = new Parser();

parser.setURL(url);//url:需要解析的頁(yè)面地址

parser.setEncoding(codeset);//codeset:頁(yè)面編碼設(shè)置

NodeList list = parser.extractAllNodesThatMatch(filter);

list就是解析出的結(jié)果集,再使用toHtml()方法就能得到一般的html代碼了:

for (int i = 0; i < list.size(); i++)

{

String s[i]= list.elementAt(i).toHtml();

}

至此,系統(tǒng)完成了頁(yè)面解析工作,網(wǎng)站頁(yè)面轉(zhuǎn)換成了普通的html代碼,存入數(shù)組s中,為下一步進(jìn)行字符串操作做好準(zhǔn)備。

1.2 頁(yè)面內(nèi)容抽取

頁(yè)面轉(zhuǎn)換完成后,如何從一大堆字符中獲取需要的文本呢?目前許多做法是使用DOM技術(shù)進(jìn)行節(jié)點(diǎn)遍歷,但是由于封裝了許多底層的操作,使得程序靈活性、執(zhí)行效率大打折扣,同時(shí)頁(yè)面的匹配問(wèn)題使得抽取內(nèi)容不可避免的帶有噪聲。

進(jìn)行網(wǎng)站頁(yè)面的抽取工作應(yīng)該是基于這樣一個(gè)前提:網(wǎng)站頁(yè)面是由統(tǒng)一的發(fā)布系統(tǒng)生成的,頁(yè)面具有統(tǒng)一的樣式。如果沒(méi)有這樣一個(gè)前提,那么任何一個(gè)工具都不可能對(duì)樣式繁多的頁(yè)面進(jìn)行統(tǒng)一匹配。如果不能對(duì)頁(yè)面實(shí)行統(tǒng)一匹配,那批量抽取也就不可能了,頁(yè)面內(nèi)容的抽取就失去了意義。如今大型網(wǎng)站內(nèi)容的發(fā)布基本上都是使用統(tǒng)一的發(fā)布工具進(jìn)行的,這就使得網(wǎng)站頁(yè)面具有統(tǒng)一的格式,具備了內(nèi)容抽取的應(yīng)用前提。

經(jīng)過(guò)解析器的解析,就可以使用java方便的字符處理功能對(duì)規(guī)律性頁(yè)面內(nèi)容進(jìn)行抽取,筆者開(kāi)發(fā)的系統(tǒng)以用戶指定的標(biāo)題頁(yè)面為起始點(diǎn),自動(dòng)抽取頁(yè)面中所有標(biāo)題的內(nèi)容,以下是抽取代碼片段:

/*--參數(shù)說(shuō)明--

t_start:開(kāi)始析取具體標(biāo)題行的起始標(biāo)志

l_start:標(biāo)題頁(yè)面超聯(lián)區(qū)域起始點(diǎn)標(biāo)識(shí)串

l_end:標(biāo)題頁(yè)面超聯(lián)區(qū)域終結(jié)點(diǎn)標(biāo)識(shí)串

l_len:l_start的字符串長(zhǎng)度

txt_start:內(nèi)容頁(yè)面起始標(biāo)識(shí)串

txt_len:txt_start字符串的長(zhǎng)度

txt_end:內(nèi)容頁(yè)有效區(qū)域終結(jié)點(diǎn)標(biāo)識(shí)

*/

……

for (int i = 0; i < list.size(); i++)

{

if(s[i].indexOf(t_start)!=-1)

{

s1=s[i].substring(s[i].indexOf(l_start)+l_len);

m[n][0]=s1.substring(0,s1.indexOf(l_end)); //標(biāo)題超聯(lián)

s3=s1.substring(s1.indexOf(\">\")+1);

s3=s3.replaceAll(\"[<][^>]*\",\"\");

m[n][1]=s3.replaceAll(\"[>]\",\"\");//標(biāo)題主體

try

{

//獲得具體內(nèi)容

StringExtractor xx=new StringExtractor(m[n][0]);

String yy=xx.extractStrings(1);

if(txt_start.equals(\"\"))

{

m[n][2]=yy.substring(yy.indexOf(s3.trim()),yy.indexOf(txt_end));

}

else

{

m[n][2]=yy.substring(yy.indexOf(txt_start)+txt_len,yy.indexOf(txt_end));

}

n++;//數(shù)組增加一行

}

……

}

}

……

執(zhí)行完成后,頁(yè)面的鏈接、標(biāo)題和內(nèi)容就儲(chǔ)存在二維數(shù)組m中,其行數(shù)就是頁(yè)面包含的標(biāo)題條數(shù)。然后可以根據(jù)需要利用java的數(shù)據(jù)庫(kù)操作或文件操作,將數(shù)組m中的數(shù)據(jù)存入數(shù)據(jù)庫(kù)或?qū)懗晌谋疚募?/p>

通過(guò)字符串操作方式抽取出的文本最大的特點(diǎn)是數(shù)據(jù)噪音小,更加干凈,便于進(jìn)一步的分析使用。

2 析取數(shù)據(jù)的批量操作

通過(guò)頁(yè)面解析與內(nèi)容抽取,已經(jīng)可以非常輕松地得到頁(yè)面干凈的純文本數(shù)據(jù),接下來(lái)的工作就是讓計(jì)算機(jī)高效率地為我們析取多個(gè)網(wǎng)站的頁(yè)面,這里需要使用java的多線程技術(shù)。

從便于代碼封裝的角度考慮,筆者使用 Runnable 接口來(lái)實(shí)現(xiàn)多線程,把第一部分中頁(yè)面內(nèi)容析取代碼統(tǒng)一寫(xiě)成一個(gè)方法,再創(chuàng)建 一個(gè)Thread 類的實(shí)例,并將該方法置入run()中,實(shí)現(xiàn)多線程的并發(fā)運(yùn)行。相關(guān)java多線程的開(kāi)發(fā)細(xì)節(jié)讀者可以去查閱具體開(kāi)發(fā)手冊(cè),在這里重點(diǎn)闡述一下線程同步過(guò)程中的關(guān)鍵點(diǎn),即共享互斥的控制。

在Java中,當(dāng)多個(gè)線程試圖同時(shí)修改某個(gè)實(shí)例的內(nèi)容時(shí),就會(huì)造成沖突,要實(shí)現(xiàn)共享互斥,使多線程同步,最簡(jiǎn)單的方法是使用synchronized標(biāo)記,對(duì)同一個(gè)實(shí)例來(lái)說(shuō),任一時(shí)刻只能有一個(gè)synchronized方法在執(zhí)行。當(dāng)一個(gè)方法正在執(zhí)行某個(gè)synchronized方法時(shí),其他線程如果想要執(zhí)行這個(gè)實(shí)例的任意一個(gè)synchronized方法,都必須等待當(dāng)前執(zhí)行synchronized方法的線程退出此方法后,才能依次執(zhí)行,因此對(duì)多線程共享互斥的控制關(guān)鍵是確定需要使用synchronized方法保護(hù)。

筆者將網(wǎng)站析取代碼統(tǒng)一寫(xiě)成一個(gè)方法,主程序采用循環(huán)調(diào)用的方式啟動(dòng)多個(gè)并發(fā)線程,各個(gè)線程通過(guò)接受不同的頁(yè)面參數(shù)來(lái)實(shí)現(xiàn)不同網(wǎng)站頁(yè)面的析取,這就要確保線程參數(shù)在執(zhí)行前不被置換,采用生產(chǎn)者——消費(fèi)者模式,利用synchronized標(biāo)記實(shí)現(xiàn)線程并發(fā)控制。核心代碼如下:

//--主程序--

public static void main(String[] args)

{

int k=0;

MultiExtractInfo r=new MultiExtractInfo();//初始化類

Thread[] th = new Thread[20];//線程數(shù)量

for (k=0;k<20;k++)

{

synchronized(r)

{

isdone=1;

if (num>5) //線程最大并發(fā)量為6

{

isWait=true;

}

while (isWait)

{

try

{

r.wait();

}

……

}

r.SetV();//析取頁(yè)面參數(shù)賦值

th[k]=new Thread(r);

th[k].start();//啟動(dòng)線程

num++;

while (!isdone)

{

try

{

r.wait();//等待析取頁(yè)面參數(shù)被賦值

}

……

}

}

}

}

//--run方法--

public void run()

{

this.result_js();//頁(yè)面析取方法

synchronized(this)

{

if (num>0)

{

num--;

}

if(isWait)

{

isWait = 1;

this.notify();

}

}

}

//--頁(yè)面析取方法封裝--

void result_js()

{

……

try

{

synchronized(this)

{

if (!isdone)

{

isdone=true;

this.notify();

}

}

……

}

……

}

這樣,使用以上生產(chǎn)者——消費(fèi)者模式,利用java的synchronized標(biāo)記,實(shí)現(xiàn)了多進(jìn)程的并發(fā)運(yùn)行。

3 系統(tǒng)運(yùn)行

具備了頁(yè)面析取的核心功能,接下來(lái)就是讓系統(tǒng)在實(shí)際工作環(huán)境中有效運(yùn)轉(zhuǎn)起來(lái),為此,還需要進(jìn)行數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)連續(xù)析取等功能的開(kāi)發(fā)。筆者將析取的內(nèi)容放入數(shù)據(jù)庫(kù)使用,析取的網(wǎng)站數(shù)據(jù)通過(guò)jdbc存入Ms SQL Server中,每次析取時(shí)將獲得的數(shù)據(jù)與上次析取的最新數(shù)據(jù)比較,若相同則終止析取,若不同則存入數(shù)據(jù)庫(kù),以此實(shí)現(xiàn)數(shù)據(jù)的連續(xù)析取。讀者也可以根據(jù)系統(tǒng)的核心功能在其他方面進(jìn)行擴(kuò)展,比如以文件和時(shí)間戳的方式實(shí)現(xiàn)析取數(shù)據(jù)的連續(xù)存儲(chǔ),為搜索引擎提供數(shù)據(jù)源等等。

筆者開(kāi)發(fā)的網(wǎng)站信息批量析取系統(tǒng)目前正在安徽省政府網(wǎng)站管理平臺(tái)上運(yùn)行,在全省網(wǎng)站監(jiān)督、信息采集等方面發(fā)揮了巨大作用。系統(tǒng)結(jié)構(gòu)簡(jiǎn)潔、功能強(qiáng)大、伸縮性和適應(yīng)性較好,運(yùn)行至今,表現(xiàn)十分穩(wěn)定,得到的數(shù)據(jù)噪音小,是一款高效、實(shí)用的應(yīng)用系統(tǒng)。

注:本文中所涉及到的圖表、注解、公式等內(nèi)容請(qǐng)以PDF格式閱讀原文。

主站蜘蛛池模板: 啊嗯不日本网站| 亚洲永久精品ww47国产| 国产精品福利导航| 91偷拍一区| 亚洲国产成人精品无码区性色| 国产91无码福利在线| 久久精品人人做人人爽| 小蝌蚪亚洲精品国产| 日本国产在线| 在线网站18禁| 欧美日本激情| www欧美在线观看| 麻豆国产在线观看一区二区| 久久a级片| 国产经典免费播放视频| 精品国产一二三区| 蜜桃臀无码内射一区二区三区| 亚洲天堂网在线播放| 欧美国产精品不卡在线观看| 国产精品理论片| 日韩精品一区二区三区免费在线观看| 人与鲁专区| 免费一级无码在线网站| 国产免费久久精品99re不卡| 凹凸国产熟女精品视频| 国产97视频在线| 女人18毛片一级毛片在线| AV无码无在线观看免费| 亚洲色欲色欲www网| 91在线一9|永久视频在线| 视频二区亚洲精品| 国产麻豆精品久久一二三| 国产精品真实对白精彩久久| 亚洲永久视频| 国产女人在线| 色香蕉影院| 国产精品天干天干在线观看| 欧美亚洲国产日韩电影在线| 成人在线观看不卡| 高清色本在线www| 欧美成一级| 亚洲激情区| AV无码国产在线看岛国岛| 青青青国产视频| 在线免费无码视频| 国产女人水多毛片18| 另类专区亚洲| 国产小视频网站| 啪啪啪亚洲无码| 国产成人无码AV在线播放动漫| 国产成人免费手机在线观看视频| 欧美性色综合网| 在线a视频免费观看| 亚洲三级电影在线播放| 欧美日韩国产成人高清视频| 亚洲av无码久久无遮挡| 欧美在线一二区| 欧美亚洲日韩不卡在线在线观看| 国产精品视频系列专区| 成人福利在线视频| 亚洲色偷偷偷鲁综合| 亚洲成人一区在线| 一级成人欧美一区在线观看 | 亚洲乱码在线播放| 午夜视频www| 国产亚洲精品自在久久不卡| 一区二区三区成人| 永久在线精品免费视频观看| 91精品啪在线观看国产| 国产视频 第一页| 又爽又大又光又色的午夜视频| 亚洲精品无码AⅤ片青青在线观看| 国产美女91呻吟求| 亚洲欧洲国产成人综合不卡| 欧美日本在线一区二区三区| 亚洲色精品国产一区二区三区| 91黄视频在线观看| 国产在线日本| 99中文字幕亚洲一区二区| 婷婷成人综合| 午夜视频免费试看| 国产91av在线|