此搜索引擎適於在一個中等規模的局域網中使用
由於找到的網頁存在數據庫中
不僅可以索靜態的HTML頁面
可以搜索php
asp等動態頁面
對於一個擁有
萬個網頁的系統(使用PII
作為服務器)
搜索響應時間在
秒左右
完全可以滿足要求
由於Java
MySQL
PHP都是跨平台的軟件
所以此搜索引擎不僅可以工作在Windows服務器上
而且也可以工作在Linux等其他系統中
一
建立搜索引擎需要的數據庫和數據表
首先建立數據庫
c:\mysql\bin\> mysqladmin
uroot
pmypasswd create Spider
然後建立數據庫中的表結構
c:\mysql\bin\> mysql
uroot
pmypasswd Spider < Spider
mysql
其中Spider
mysql為一個文本文件
其內容如下
CREATE TABLE link (
Id int(
) unsigned NOT NULL auto_increment
Url varchar(
) NOT NULL
Class tinyint(
) unsigned NOT NULL default
IsSearchLink tinyint(
) unsigned default
PRIMARY KEY (Url)
UNIQUE Id (Id)
KEY Url (Url)
KEY Class (Class)
);
# 本局域網的初始主頁地址
搜索蜘蛛從此網址開始搜索所有其他網頁
INSERT INTO link VALUES(
HTTP://
/
);
# 數據表 webpagelocal 用來存放下載的所有的網頁
CREATE TABLE webpagelocal (
Id int(
) unsigned NOT NULL auto_increment
Url varchar(
) NOT NULL
Content text NOT NULL
PRIMARY KEY (Url)
UNIQUE Id (Id)
KEY Url (Url)
);
# 數據表 webpagefindfast
# 用MakeFast
php從表webpagelocal中提取
字節的檢索信息存放其中
CREATE TABLE webpagefindfast (
Id int(
) unsigned NOT NULL
Url varchar(
) NOT NULL
Title varchar(
)
Content blob
PRIMARY KEY (Url)
KEY Url (Url)
KEY Title (Title)
);
二
以下為搜索網頁和下載網頁至本地數據庫的Java程序LinkToDB
java
它也是此搜索引擎的核心和基礎
/***************************** LinkToDB
java ***********************************
*
* 對URL中的http鏈接進行分析
將相對路徑轉換為絕對路徑
排序方式輸出結果到數據庫
*
* 如果分析得到的URL是Link表中唯一的
就將其內容下載到表 WebPageLocal 中
*
********************************************************************************
/
import java
io
*;
import java
util
*;
import
*;
import java
lang
String;
import java
sql
*;
import java
text
*;
class Counter {
private int i =
;
int read() { return i; }
void increment() { i++; }
}
public class LinkToDB {
String UrlHost =
;
String UrlFile =
;
String UrlPath =
;
static String StartWith = null;
boolean outsideTag = true; //判斷是否在標記之中
static char[] buffer = new char[
]; // 緩沖區:用於保存從 URL 讀的數據
InputStreamReader read = null;
BufferedReader reader = null;
URLConnection uc = null;
private URL url = null;
private StreamTokenizer st;
private TreeMap counts = new TreeMap();//以排序方式保存找到的鏈接
LinkToDB(String myurl
String StartOnly){
try {
StartWith = StartOnly;
if(StartOnly!=null) { if(!myurl
startsWith(StartOnly)) return; }//只搜索此網站
url = new URL(myurl);
UrlHost = url
getHost();
UrlHost = UrlHost
toUpperCase();
UrlFile = url
getFile();
int v=UrlFile
lastIndexOf(
/
);
if(v!=
) UrlPath = UrlFile
substring(
v);
System
out
println(
分析文件
+myurl);
int uclength=
;
int ucError=
;
try{
uc = url
openConnection();
uc
setUseCaches(false);
nnect();
}
catch(IOException io) { ucError=
; System
out
println(
打不開待分析網頁:
+myu
rl); }
if(ucError!=
){
uclength = uc
getContentLength();
if (uclength<
) {
try{ read = new InputStreamReader(url
openStream()); }
catch(IOException io) {System
out
println(
流打開錯誤:
+myurl);}
}
else System
out
println(
文件太大
不分析
);
}
if(read!=null){
reader=new BufferedReader(read);
if(reader!=null){
st = new StreamTokenizer(reader);
st
resetSyntax(); // 重置語法表
st
wordChars(
); // 令牌范圍為全部字符
st
ordinaryChar(
<
); // HTML標記兩邊的分割符
st
ordinaryChar(
>
);
}
}
}
catch(MalformedURLException e){ System
out
println(
Malformed URL String!
);}
}
void cleanup() {
try { read
close(); }
catch(IOException e) { System
out
println(
流關閉錯誤
); }
}
void countWords() {
try {
while(st
nextToken()!=StreamTokenizer
TT_EOF) {
String s
=
;
String s_NoCase=
;
switch(ype) {
case
<
: //入標記字段
outsideTag=false;
continue; //countWords();
case
>
: //出標記字段
outsideTag=true;
continue; //countWords();
case StreamTokenizer
TT_EOL: s
= new String(
EOL
); break;
case StreamTokenizer
TT_WORD: if(!outsideTag) s
= st
sval; /*已經是字符
串*/ break;
default: s
=
;// s
= String
valueOf((char)ype);/*單一字符*/
}
if(outsideTag) continue;//出了標記區域(<a >)
String s =
;
s_NoCase = s
trim();
s
=s_NoCase
toUpperCase();
if(s
startsWith(
A
)||s
startsWith(
AREA
)||s
startsWith(
FRAME
)||s
s
tartsWith(
IFRAME
)){ //以這些開始的都是超級鏈接
int HREF_POS =
;
if(s
startsWith(
FRAME
)||s
startsWith(
IFRAME
)) {
HREF_POS = s
indexOf(
SRC=
);
s
= s
substring(HREF_POS+
)
trim();
s_NoCase=s_NoCase
substring(HREF_POS+
)
trim();
}
else {
HREF_POS=s
indexOf(
HREF=
);
s
=s
substring(HREF_POS+
)
trim();
s_NoCase=s_NoCase
substring(HREF_POS+
)
trim();
}
if(HREF_POS!=
) {
if(s
startsWith(
\
))
{s
=s
substring(
);s_NoCase=s_NoCase
substring(
);}
int QUOTE=s
indexOf(
\
);
if(QUOTE!=
)
{s
=s
substring(
QUOTE)
trim();s_NoCase=s_NoCase
substring(
QUOTE)
trim
();}
int SPACE=s
indexOf(
);
if(SPACE!=
)
{s
=s
substring(
SPACE)
trim();s_NoCase=s_NoCase
substring(
SPACE)
trim
();}
if(s
endsWith(
\
))
{s
=s
substring(
s
length()
);s_NoCase=s_NoCase
substring(
s_NoCase
l
ength()
);}
if(s
indexOf(
)!=
||s
indexOf(
JAVASCRIPT:
)!=
||s
indexOf(
)!=
)
{s
=
;s_NoCase=
;} //有這些符號
認為非合法鏈接
兩點表示上一目錄
而我
只想向下級查找
if ( !s
startsWith(
FTP://
) &&//以下後綴或前綴通常非網頁格式
!s
startsWith(
FTP://
) &&
!s
startsWith(
MAILTO:
) &&
!s
endsWith(
SWF
) &&
!s
startsWith(
/
)) //因
/表示上一目錄
通常只需考慮本級和下N級目錄
s=s
;
if (!s
startsWith(
HTTP://
)&&!s
equals(
)) {s=UrlHost+UrlPath+
/
+s;s_No
Case=UrlHost+UrlPath+
/
+s_NoCase;}
else if(s
startsWith(
/
)) {s=UrlHost+s;s_NoCase=UrlHost+s_NoCase;}
if(s
startsWith(
HTTP://
)) {s=s
substring(
);s_NoCase=s_NoCase
substring(
);}
int JinHao=s
indexOf(
#
); //如果含有
#
號
表示有效的鏈接是此前的部分
if(JinHao!=
) {s=s
substring(
JinHao)
trim();s_NoCase=s_NoCase
substring(
JinHao)
trim();}
int H=
; //以下將/
/轉換為/
for(int m=
;m<
;m++){
H=s
indexOf(
/
/
);
if(H!=
) {s=s
substring(
H)+s
substring(H+
);s_NoCase=s_NoCase
substring
(
H)+s_NoCase
substring(H+
);}
}
int TwoXG=
; //以下將//轉換為/
for(int m=
;m<
;m++){
TwoXG=s
indexOf(
//
);
if(TwoXG!=
) {s=s
substring(
TwoXG)+s
substring(TwoXG+
);s_NoCase=s_NoCa
se
substring(
TwoXG)+s_NoCase
substring(TwoXG+
);}
}
int OneXG=s
indexOf(
/
);
if(OneXG==
) {s=s+
/
;s_NoCase+=
/
;} //將xx
xx
xx
xxx轉換為xx
xx
xx
xxx/的
標准形式
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19732.html