java搜索引擎mysql_用Java MySQL PHP轻松构建跨平台的搜索引擎

傅峰
2023-12-01

此搜索引擎适于在一个中等规模的局域网中使用,由于找到的网页存在数据库中,不仅可以索静态的HTML页面,可以搜索php、asp等动态页面。对于一个拥有5万个网页的系统(使用PII-400作为服务器),搜索响应时间在2-10秒左右,完全可以满足要求,由于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(10) unsigned NOT NULL auto_increment,

Url varchar(120) NOT NULL,

Class tinyint(3) unsigned NOT NULL default 0 ,

IsSearchLink tinyint(3) unsigned default 0,

PRIMARY KEY (Url),

UNIQUE Id (Id),

KEY Url (Url),

KEY Class (Class)

);

# 本局域网的初始主页地址,搜索蜘蛛从此网址开始搜索所有其他网页

INSERT INTO link VALUES( '1', 'HTTP://102.211.69.1/', '0', '0');

# 数据表 webpagelocal 用来存放下载的所有的网页

CREATE TABLE webpagelocal (

Id int(10) unsigned NOT NULL auto_increment,

Url varchar(120) NOT NULL,

Content text NOT NULL,

PRIMARY KEY (Url),

UNIQUE Id (Id),

KEY Url (Url)

);

# 数据表 webpagefindfast

# 用MakeFast.php从表webpagelocal中提取512字节的检索信息存放其中

CREATE TABLE webpagefindfast (

Id int(10) unsigned NOT NULL,

Url varchar(120) NOT NULL,

Title varchar(64),

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 java.net.*;

import java.lang.String;

import java.sql.*;

import java.text.*;

class Counter {

private int i = 1;

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[4096]; // 缓冲区:用于保存从 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!=-1) UrlPath = UrlFile.substring(0,v);

System.out.println("分析文件:" myurl);

int uclength=200000;

int ucError=0;

try{

uc = url.openConnection();

uc.setUseCaches(false);

uc.connect();

}

catch(IOException io) { ucError=1; System.out.println("打不开待分析网页:" myu

rl); }

if(ucError!=1){

uclength = uc.getContentLength();

if (uclength<200000) {

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(0,255); // 令牌范围为全部字符

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 s0="";

String s_NoCase="";

switch(st.ttype) {

case '<': //入标记字段

outsideTag=false;

continue; //countWords();

case '>': //出标记字段

outsideTag=true;

continue; //countWords();

case StreamTokenizer.TT_EOL: s0 = new String("EOL"); break;

case StreamTokenizer.TT_WORD: if(!outsideTag) s0 = st.sval; /*已经是字符

串*/ break;

default: s0 = "";// s0 = String.valueOf[1]{ //以这些开始的都是超级链接

int HREF_POS = -1;

if(s0.startsWith("FRAME ")||s0.startsWith("IFRAME ")) {

HREF_POS = s0.indexOf("SRC=");

s0 = s0.substring(HREF_POS 4).trim();

s_NoCase=s_NoCase.substring(HREF_POS 4).trim();

}

else {

HREF_POS=s0.indexOf("HREF=");

s0=s0.substring(HREF_POS 5).trim();

s_NoCase=s_NoCase.substring(HREF_POS 5).trim();

}

if(HREF_POS!=-1) {

if(s0.startsWith("\""))

{s0=s0.substring(1);s_NoCase=s_NoCase.substring(1);}

int QUOTE=s0.indexOf("\"");

if(QUOTE!=-1)

{s0=s0.substring(0,QUOTE).trim();s_NoCase=s_NoCase.substring(0,QUOTE).trim

();}

int SPACE=s0.indexOf(" ");

if(SPACE!=-1)

{s0=s0.substring(0,SPACE).trim();s_NoCase=s_NoCase.substring(0,SPACE).trim

();}

if(s0.endsWith("\""))

{s0=s0.substring(0,s0.length()-1);s_NoCase=s_NoCase.substring(0,s_NoCase.l

ength()-1);}

if(s0.indexOf("'")!=-1||s0.indexOf("JAVASCRIPT:")!=-1||s0.indexOf("..")!=-1

)

{s0="";s_NoCase="";} //有这些符号,认为非合法链接;两点表示上一目录,而我

只想向下级查找

if ( !s0.startsWith("FTP://") &&//以下后缀或前缀通常非网页格式

!s0.startsWith("FTP://") &&

!s0.startsWith("MAILTO:") &&

!s0.endsWith(".SWF") &&

!s0.startsWith("../")) //因../表示上一目录,通常只需考虑本级和下N级目录

s=s0;

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(7);s_NoCase=s_NoCase.substring(

7);}

int JinHao=s.indexOf("#"); //如果含有"#"号,表示有效的链接是此前的部分

if(JinHao!=-1) {s=s.substring(0,JinHao).trim();s_NoCase=s_NoCase.substring(

0,JinHao).trim();}

int H=-1; //以下将/./转换为/

for(int m=0;m<4;m ){

H=s.indexOf("/./");

if(H!=-1) {s=s.substring(0,H) s.substring(H 2);s_NoCase=s_NoCase.substring

(0,H) s_NoCase.substring(H 2);}

}

int TwoXG=-1; //以下将//转换为/

for(int m=0;m<5;m ){

TwoXG=s.indexOf("//");

if(TwoXG!=-1) {s=s.substring(0,TwoXG) s.substring(TwoXG 1);s_NoCase=s_NoCa

se.substring(0,TwoXG) s_NoCase.substring(TwoXG 1);}

}

int OneXG=s.indexOf("/");

if(OneXG==-1) {s=s "/";s_NoCase ="/";} //将xx.xx.xx.xxx转换为xx.xx.xx.xxx/的

标准形式

 类似资料: