一、环境

1、平台:MyEclipse8.5/JDK1.5

2、框架:Lucene3.6.1/IKAnalyzer2012/htmlparser

二、目标

1、整合前面连篇文章(Lucene学习——IKAnalyzer中文分词(一)和Lucene学习——初探搜索引擎),使该搜索引擎雏形支持中文站点

2、试图发现些什么

三、开发调试

1、改写原有的搜索引擎程序,利用IKAnalyzer使之支持中文分词,代码如下

package org.cyxl.lucene.test;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.beans.StringBean;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.HtmlPage;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class ParseURL {
//索引目录
private static final String INDEX_DIR = "myindex";
//已经存在的url列表
private static List<String> urls=new ArrayList<String>();
/**
* 索引器,对目标url创建索引
* @param url   目标网址
* @throws IOException
* @throws ParserException
*/
@SuppressWarnings("deprecation")
private static void indexer(String url) throws IOException, ParserException {
//存储索引的目录
File indexDir = new File(INDEX_DIR);
//目录不存在,创建该目录
if (!indexDir.exists()) {
indexDir.mkdir();
}
//获取网页纯文本
String content = getText(url);
//获取网页标题
String title = getTitle(url);
System.out.println("title:" + title);
if(title==null || content==null || content.trim().equals(""))
{
return;
}
//      System.out.println("content:" + content);
//      URL path=new URL(url);
//      InputStream stream=path.openStream();
//
//      Reader reader=new InputStreamReader(stream);
//      Reader reader=new InputStreamReader(new ByteArrayInputStream(content.getBytes()));
//      Reader reader2=new InputStreamReader(new ByteArrayInputStream(title.getBytes()));
Document doc = new Document();
//加入url域
doc.add(new Field("url", url, Field.Store.YES,
Field.Index.NOT_ANALYZED));
//加入标题域
doc.add(new Field("title", title, Field.Store.YES,
Field.Index.ANALYZED));
//      doc.add(new Field("title",reader2));
//Index.ANALYZED分词后构建索引
//加入内容域
doc.add(new Field("content", content, Field.Store.YES,
Field.Index.ANALYZED));
//      doc.add(new Field("content",reader));
//创建IKAnalyzer中文分词对象
Analyzer analyzer=new IKAnalyzer();
//索引目录
Directory dir=FSDirectory.open(indexDir);
//配置IndexWriterConfig
IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_36 , analyzer);
iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
//创建写索引对象
IndexWriter writer = new IndexWriter(dir,iwConfig);
//写入文档
writer.addDocument(doc);
//关闭
writer.close();
//创建了索引的网址加入到已经存在的网址列表中
urls.add(url);
}
/**
* 搜索器,根据输入的文本去搜索
* @param words     输入的文本
* @param field     搜索的域
* @throws CorruptIndexException
* @throws IOException
* @throws ParseException
*/
@SuppressWarnings("deprecation")
private static void searcher(String words,String field) throws CorruptIndexException,
IOException, ParseException {
File indexDir = new File(INDEX_DIR);
//索引目录
Directory dir=FSDirectory.open(indexDir);
//根据索引目录创建读索引对象
IndexReader reader = IndexReader.open(dir);
//搜索对象创建
IndexSearcher searcher = new IndexSearcher(reader);
//IKAnalyzer中文分词
Analyzer analyzer = new IKAnalyzer();
//创建查询解析对象
QueryParser parser = new QueryParser(Version.LUCENE_36,field, analyzer);
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
//根据域和目标搜索文本创建查询器
Query query = parser.parse(words);
System.out.println("Searching for: " + query.toString(field));
//对结果进行相似度打分排序
TopScoreDocCollector collector = TopScoreDocCollector.create(5 * 10,false);
searcher.search(query, collector);
//获取结果
ScoreDoc[] hits = collector.topDocs().scoreDocs;
int numTotalHits = collector.getTotalHits();
System.out.println(numTotalHits + " total matching pages");
//显示搜索结果
for (int i = 0; i < hits.length; i++) {
Document doc = searcher.doc(hits[i].doc);
String url = doc.get("url");
String title=doc.get("title");
String content=doc.get("content");
System.out.println((i + 1) + "." + title);
System.out.println("-----------------------------------");
System.out.println(content.substring(0,100)+"......");
System.out.println("-----------------------------------");
System.out.println(url);
System.out.println();
}
}
/**
* 收入网站
* @param url   网站首页url,也可以为网站地图url
* @throws ParserException
* @throws IOException
* @throws ParseException
*/
private static void addSite(String url) throws ParserException, IOException, ParseException
{
long start=System.currentTimeMillis();
System.out.println("start add...");
//获取目标网页的所有链接
List<String> links = getLinks(url);
System.out.println("url count:"+links.size());
for(int i=0;i<links.size();i++)
{
String link=links.get(i);
System.out.println((i+1)+"."+link);
if(!urls.contains(link))
{
//对未创建过索引的网页创建索引
indexer(link);
}
else
{
System.out.println("["+link+"] exist");
}
}
System.out.println("end...");
long end=System.currentTimeMillis();
System.out.println("cost "+(end-start)/1000+" seconds");
}
/**
* 获取网页纯文本
* @param url   目标网址
* @return
* @throws ParserException
*/
private static String getText(String url) throws ParserException {
StringBean sb = new StringBean();
// 设置不需要得到页面所包含的链接信息
sb.setLinks(false);
// 设置将不间断空格由正规空格所替代
sb.setReplaceNonBreakingSpaces(true);
// 设置将一序列空格由一个单一空格所代替
sb.setCollapse(true);
// 传入要解析的URL
sb.setURL(url);
// 返回解析后的网页纯文本信息
String content = sb.getStrings();
// System.out.println(content);
return content;
}
/**
* 获取网页标题
* @param path
* @return
* @throws IOException
* @throws ParserException
*/
private static String getTitle(String path) throws IOException,
ParserException {
String title = "";
try {
Parser parser=new Parser(path);
HtmlPage page = new HtmlPage(parser);
parser.visitAllNodesWith(page);
title=page.getTitle();
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
title = "no title";
}
return title.trim();
}
/**
* 获取网页中所有的链接
* @param url
* @return
* @throws ParserException
*/
private static List<String> getLinks(String url) throws ParserException
{
List<String> links=new ArrayList<String>();
//创建链接节点的过滤器
NodeFilter filter = new NodeClassFilter(LinkTag.class);
Parser parser = new Parser();
parser.setURL(url);
//设置目标网页的编码方式
//parser.setEncoding("utf-8");
//因为有些时候不清楚目标网页的编码方式,这里我们采用指定一
//个编码集合,然后通过试探的方式得到目标网页的编码方式
parser.setEncoding(CharsetAutoSwitch.dectedEncode(url));
NodeList list = parser.extractAllNodesThatMatch(filter);
for (int i = 0; i < list.size(); i++) {
LinkTag node = (LinkTag) list.elementAt(i);
//获取链接的目标网址
String link=node.extractLink();
if(link!=null && !link.trim().equals("") && !link.equals("#"))
{
//将目标网址加入到该页面的所有网址列表中
links.add(link);
}
}
return links;
}
public static void main(String[] args) throws IOException, ParseException,
InterruptedException, ParserException {
String url = "http://www.csdn.net/";
//收录网站
addSite(url);
//搜有标题带有“搜索引擎”字眼的网页
searcher("搜索引擎","title");
}
}

2、测试结果,如下

加载扩展词典:ext.dic
加载扩展停止词典:stopword.dic
加载扩展停止词典:chinese_stopword.dic
Searching for: +搜索引擎 +搜索 +索引 +引擎
3 total matching pages
1.搜索引擎-CSDN.NET
-----------------------------------
搜索引擎-CSDN.NET
业界
移动开发
云计算
软件研发
专题
程序员杂志
产品
创业
职场
人物
设计
开源
iOS
Android
WindowsPhone
H......
-----------------------------------
http://www.csdn.net/article/tag/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E
2.充分使用HTML5特性进行搜索引擎优化(SEO) | Intel? Developer Zone
-----------------------------------
充分使用HTML5特性进行搜索引擎优化(SEO) | Intel? Developer Zone
跳转到主要内容
Intel? Developer Zone
社区
按行业焦点选择
游戏和媒体......
-----------------------------------
http://g.csdn.net/5231640
3.庞果网-Pongo.cn -IT互联网计算机通信领域职位搜索引擎
-----------------------------------
庞果网-Pongo.cn -IT互联网计算机通信领域职位搜索引擎
企业用户
登录
CSDN会员可直接登录
帐 号
密 码
记住我 忘记密码
").append("
我的pongo |"......
-----------------------------------
http://www.pongo.cn

3、具体的代码解释根据代码注释进行理解

四、总结

1、由于IKAnalyzer2012只支持Lucene3.3以上版本,所以我们这里采用Lucene3.6.1,和之前的方式稍微有些差别,具体参见代码和注释

2、该程序已经支持了中文站点的收录的搜索,以初步达成了中文分词和搜索的目的

3、试图发现些什么,主要有一下几点

1)ext.dic自己的词典如何扩展。比如我们这里收录了CSDN网站,由于它是一个以程序开发为主的博客站点,所以我们搜索“搜索引擎”时,应该将其看成一个词,而不是分成“搜索引擎 +搜索 +索引 +引擎”,还有“存储过程”等,我们可以将其加入到扩展词典中。这里主要跟项目的业务关系比较大,所以应该根据项目来确定扩展词典

2)chinese_stopword.dic的扩展也可以根据项目业务来扩展,但这个相对固定和简单些

3)对于网站的收录,这里只做了简单的首页中链接的挖掘。实际收录时可以更加深层次的挖掘出所有该站点的页面。但某页面如何判定是否属于该站点对我目前来说是一个难点,希望知者不吝赐教

4)该程序只是个简单的测试雏形,如何使之有用值得我去思考

Lucene学习——IKAnalyzer中文分词(二)相关推荐

  1. Lucene学习——IKAnalyzer中文分词(一)

    一.环境 1.平台:MyEclipse8.5/JDK1.5 2.开源框架:Lucene3.6.1/IKAnalyzer2012 3.目的:测试IKAnalyzer的分词效果 二.开发调试 1.下载框架 ...

  2. Solr的学习使用之(三)IKAnalyzer中文分词器的配置

    1.为什么要配置? 1.我们知道要使用Solr进行搜索,肯定要对词语进行分词,但是由于Solr的analysis包并没有带支持中文的包或者对中文的分词效果不好,需要自己添加中文分词器:目前呼声较高的是 ...

  3. solr集成IKAnalyzer中文分词器

    如果想要知道如何安装solr,集成IKAnalyzer中文分词器,批量导入数据库数据,java使用参照以下本博主博文: 安装solr https://blog.csdn.net/u013294097/ ...

  4. IKAnalyzer中文分词分析内容目录

    IKAnalyzer中文分词的学习: Java开源分词系统IKAnalyzer学习(一) 大致简介 Java开源分词系统IKAnalyzer学习(二) 架构 Java开源分词系统IKAnalyzer学 ...

  5. IKAnalyzer 中文分词器

    IK Analyzer 2012 介绍 IK Analyzer 是一个开源的,基亍 java 语言开发的轻量级的中文分词工具包.从 2006 年 12 月推出 1.0 版开始, IKAnalyzer ...

  6. 基于垃圾短信与垃圾邮件的检测以及iphone中siri所使用的IKAnalyzer中文分词技术

    刚开始接触安卓开发,导师就让做了一个基于安卓的垃圾短信检测软件,其中中文分词让我搞了一天,我所使用的是IKAnalyzer中文分词技术,这个包已经很是成熟.因为新手在使用中可能会出现导入的工程包错误而 ...

  7. Java实现敏感词过滤 - IKAnalyzer中文分词工具

    IKAnalyzer 是一个开源的,基于java语言开发的轻量级的中文分词工具包. 官网: https://code.google.com/archive/p/ik-analyzer/ 本用例借助 I ...

  8. ACL 2021 | 基于全局字符关联机制联邦学习的中文分词

    作者 | 陈桂敏 来源 | QTrade AI研究中心 QTrade AI 研究中心是一支将近 30 人的团队,主要研究方向包括:预训练模型.信息抽取.对话机器人.内容推荐等.本文介绍的是一篇收录于 ...

  9. 发布IKAnalyzer中文分词器V3.1.3GA生日祝福版

    [size=large][b]生日祝福[/b][/size] 谨以此版本献给我的老婆,今天是她的生日,在这里,要祝福她生日快乐,天天无忧无虑. 感谢她一直以来对我从事开源项目的支持和鼓励,想对她说:谢 ...

最新文章

  1. Error:(1, 0) Your project path contains non-ASCII characters.
  2. 基于点云强度的3D激光雷达与相机的外参标定
  3. 25~50K|云视科技SLAM算法工程师/机器人算法软件工程师招聘(社招+实习)
  4. nginx 缓存动态内容 和使用自定义错误503
  5. 单臂路由与三层交换机实现VLAN通信
  6. 滚动视差?CSS 不在话下
  7. cmd中如何切换指定目录
  8. [react] 说说你对Error Boundaries的理解
  9. Lucene-01 全文检索基本介绍
  10. 轻触开源(一)-Java泛型Type类型的应用和实践
  11. 并发数据结构- 1.1.1 性能
  12. elasticsearch最大节点数_ElasticSearch读写底层原理及性能调优
  13. [ckeditor系列]CKeditor自定义上传图片功能
  14. 集群间动态扩展和删除hdfs的datanode和hbase的regionserver
  15. [IOI2018] seats 排座位
  16. 数据结构-03-队列
  17. 《DNS与BIND(第5版)》——10.12 系统优化
  18. Bootstrap栅格系统(屏幕大小)
  19. 小程序图形验证码输入校验例子
  20. w ndows7与windows10区别,windows7和10区别

热门文章

  1. FileInputStream与BufferedInputStream的区别
  2. 韩信点兵的问题求解方法
  3. JDBC--基础JDBC
  4. PMIX ERROR: ERROR in file gds_ds12_lock_pthread.c
  5. 常见UNIXLINUX系统
  6. 蓝牙HC05模块,AT其他指令爆出ERROR[0] 解决方法
  7. 阿里云周宇:神龙计算平台智能运维体系建设
  8. 【C#编程】两点距离计算
  9. Vue生命周期,axios及动画
  10. zsh : corrupt history file ~/.zsh_history