分享
 
 
 

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

王朝mysql·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

此搜索引擎适于在一个中等规模的局域网中使用,由于找到的网页存在数据库中,不仅可以索静态的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((char)st.ttype);/*单一字符*/

}

if(outsideTag) continue;//出了标记区域(<a >)

String s = "";

s_NoCase = s0.trim();

s0=s_NoCase.toUpperCase();

if(s0.startsWith("A ")||s0.startsWith("AREA ")||s0.startsWith("FRAME ")||s0.s

tartsWith("IFRAME ")){ //以这些开始的都是超级链接

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/的

标准形式

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有