当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>Java进阶

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


  此搜索引擎适于在一个中等规模的局域网中使用,由于找到的网页存在数据库中,不仅可以索静态的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/的
  标准形式
相关内容
赞助商链接