热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用到lucene的爬虫的简单实现

2019独角兽企业重金招聘Python工程师标准小菜鸟我最近研究了一下lucene,以及前面的爬虫的写法,我想到能否用lucene写一个站内搜索&

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

小菜鸟我最近研究了一下lucene,以及前面的爬虫的写法,我想到能否用lucene写一个站内搜索,由于我对htmlprase不是很了解,对字符串的处理有点不行,但是结果是可以的。

package LuceneSpider;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;


import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumberTools;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.LockObtainFailedException;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.filters.OrFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;


public class LuceneSpider {
/**
* 使用种子初始化url队列
*/
private Set visitedUrlSet=new HashSet();
private LinkedList unvisitedUrlSet=new LinkedList();
String[] seeds;
String line;
String savepath;
String encoding;
int savenum;
Analyzer analyzer;
public LuceneSpider(String[] seeds,String line,String savepath,int savenum,Analyzer analyzer){
this.seeds=seeds;
this.line=line;
this.savepath=savepath;
this.savenum=savenum;
this.analyzer=analyzer;
}
public void init(){
Set seedsSet=new HashSet();
for(int i=0;i seedsSet.add(seeds[i]);
}
addToUnvisitedUrlSet(seedsSet);
}
public void run() throws ParserException, HttpException, IOException {
init();
for(int i=0;i if(IsUnvisitedUrlSetEmpty()==false){
String url=getFirstFromVisitedUrSet();
catchPages(url);
}
}
}

public void catchPages(String url) throws ParserException, HttpException, IOException{

HttpClient httpClient=new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
GetMethod getMethod=new GetMethod(url);
//生成getmthod对象并设置参数
//设置get请求超时5s
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
//设置请求重试处理
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
//执行http get请求
int statusCode;
statusCode = httpClient.executeMethod(getMethod);
if(statusCode!=HttpStatus.SC_OK){
System.err.print("Method faied:"+url+getMethod.getStatusLine());
}else{
encoding=getMethod.getResponseCharSet();
   createIndex(url);
addToVisitedUrlSet(url);
addToUnvisitedUrlSet(getUrls(url));
System.out.println(unvisitedUrlSet.size());
}
}
private void createIndex(String url) throws CorruptIndexException, LockObtainFailedException, IOException, ParserException {
// TODO Auto-generated method stub
String content="";
content=getContentByUrl(url);
Document doc = new Document();
//文件名称
doc.add(new Field("url", url, Store.YES, Index.NOT_ANALYZED));
//检索到的内容
doc.add(new Field("content",content, Store.YES, Index.ANALYZED));
System.out.println(url);
IndexWriter indexWriter = new IndexWriter(savepath, analyzer, false,
            MaxFieldLength.LIMITED);
    indexWriter.addDocument(doc);
    indexWriter.close();
}
/*
* 通过url得到网页去除标签后的内容
*/
private String getContentByUrl(String url) throws ParserException {
// TODO Auto-generated method stub
String content="";
Parser parser=new Parser(url);
Node nodes=null;
int j=0;
for(NodeIterator iterator=parser.elements();iterator.hasMoreNodes();){
j+=1;
nodes=iterator.nextNode();
content=content+nodes.toPlainTextString().replaceAll(" ","").replaceAll("\n", "");
}
return content;
}
/*
* 解析页面的url
*/
public Set getUrls(String url) throws ParserException {
Set links=new HashSet();
Parser parser=null;
parser = new Parser(url);
parser.setEncoding(encoding);
NodeFilter frameFilter=new NodeFilter() {
@Override
public boolean accept(Node node) {
// TODO Auto-generated method stub
if(node.getText().startsWith("frame src=")){
return true;
}else{
return false;
}
}
};
OrFilter linkFilter=new OrFilter(new NodeClassFilter(LinkTag.class),frameFilter);
if(parser!=null){
NodeList list=parser.extractAllNodesThatMatch(linkFilter);
for(int i=0;i Node tag=list.elementAt(i);
if(tag instanceof LinkTag){
LinkTag link=(LinkTag)tag;
String linkUrl=link.getLink();
if(frameFilter.accept(tag)){
//处理
String frameTxt=tag.getText();
int start=frameTxt.indexOf("src=");
frameTxt=frameTxt.substring(start);
int end=frameTxt.indexOf(" ");
if(end==-1){
end=frameTxt.indexOf(">");
}
String frameUrl=frameTxt.substring(5,end-1);
if(LinkFilter(frameUrl))
links.add(frameUrl);
}else{
//处理
if(LinkFilter(linkUrl)){
links.add(linkUrl);
}
}
}
}
}
return links;
}
//爬虫遵循的线索
public boolean LinkFilter(String url){
if(url.startsWith(line)){
return true;
}else{
return false;
}
}

//网页名filter,不然会出现存储错误
public String getFileNameByUrl(String url,String contentType){
//移除http;
url=url.substring(7);
//text/html类型
if(contentType.indexOf("html")!=-1){
url&#61;url.replaceAll("[\\?/:*|<>\"]", "_")&#43;".html";
return url;
}else{
return url.replaceAll("[\\?/:*|<>\"]","_")&#43;"."&#43;
contentType.substring(contentType.lastIndexOf("/")&#43;1);
}
}


public void addToVisitedUrlSet(String url){
visitedUrlSet.add(url);
}
public boolean IsUnvisitedUrlSetEmpty(){
boolean isEmpty&#61;false;
if(unvisitedUrlSet.isEmpty()){
isEmpty&#61;true;
}
return isEmpty; 
}
public  void addToUnvisitedUrlSet(Set urls){
for (String url : urls) {
if(!isVisited(url)){
unvisitedUrlSet.add(url);
}
}
}
public boolean isVisited(String url){
boolean isVisited&#61;false;
for (String visitedUrl : visitedUrlSet) {
if(visitedUrl.equals(url)){
isVisited&#61;true;
}
}
return isVisited;
}
public String getFirstFromVisitedUrSet(){
String url&#61;unvisitedUrlSet.getFirst().toString();
unvisitedUrlSet.removeFirst();
return url;
}

public void search(String about) throws Exception {
       //请求字段
       //String queryString &#61; "document";
       //String queryString &#61; "IndexWriter document a javadoc.txt";


       // 1&#xff0c;把要搜索的文本解析为 Query
       String[] fields &#61; { "url", "content" };
       QueryParser queryParser &#61; new MultiFieldQueryParser(fields, analyzer);
       Query query &#61; queryParser.parse(about);


       // 2&#xff0c;进行查询&#xff0c;从索引库中查找
       IndexSearcher indexSearcher &#61; new IndexSearcher(savepath);
       Filter filter &#61; null;
       TopDocs topDocs &#61; indexSearcher.search(query, filter, 10000);
       System.out.println("总共有【" &#43; topDocs.totalHits &#43; "】条匹配结果");


       // 3&#xff0c;打印结果
       for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
           // 文档内部编号
           int index &#61; scoreDoc.doc; 
           // 根据编号取出相应的文档
           Document doc &#61; indexSearcher.doc(index);
           System.out.println("------------------------------");
           System.out.println("url &#61; " &#43; doc.get("url"));
//            System.out.println("content &#61; " &#43; doc.get("content").replaceAll(" ",""));
       }
   }


}


下面是简单的调用&#xff1a;

package LuceneSpider;


import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;




public class Run {


/**
* &#64;param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] seeds&#61;{"http://localhost/openzone"};
String line&#61;"http://localhost";
String savepath&#61;"D:\\javaworkspace\\openzone";
int savenum&#61;100;
Analyzer analyzer&#61;new StandardAnalyzer();
LuceneSpider luceneSpider&#61;new LuceneSpider(seeds, line, savepath, savenum, analyzer);
try {
luceneSpider.run();
luceneSpider.search("合作站点");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}



转载于:https://my.oschina.net/u/1017099/blog/138693


推荐阅读
  • 本文探讨了2019年前端技术的发展趋势,包括工具化、配置化和泛前端化等方面,并提供了详细的学习路线和职业规划建议。 ... [详细]
  • 本文详细探讨了HTML表单中GET和POST请求的区别,包括它们的工作原理、数据传输方式、安全性及适用场景。同时,通过实例展示了如何在Servlet中处理这两种请求。 ... [详细]
  • MapReduce原理是怎么剖析的
    这期内容当中小编将会给大家带来有关MapReduce原理是怎么剖析的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1 ... [详细]
  • Python第三方库安装的多种途径及注意事项
    本文详细介绍了Python第三方库的几种常见安装方法,包括使用pip命令、集成开发环境(如Anaconda)以及手动文件安装,并提供了每种方法的具体操作步骤和适用场景。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • Coursera ML 机器学习
    2019独角兽企业重金招聘Python工程师标准线性回归算法计算过程CostFunction梯度下降算法多变量回归![选择特征](https:static.oschina.n ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 深入解析ESFramework中的AgileTcp组件
    本文详细介绍了ESFramework框架中AgileTcp组件的设计与实现。AgileTcp是ESFramework提供的ITcp接口的高效实现,旨在优化TCP通信的性能和结构清晰度。 ... [详细]
  • 本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ... [详细]
  • 2017-2018年度《网络编程与安全》第五次实验报告
    本报告详细记录了2017-2018学年《网络编程与安全》课程第五次实验的具体内容、实验过程、遇到的问题及解决方案。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • Java实现文本到图片转换,支持自动换行、字体自定义及图像优化
    本文详细介绍了如何使用Java实现将文本转换为图片的功能,包括自动换行、自定义字体加载、抗锯齿优化以及图片压缩等技术细节。 ... [详细]
  • 本文介绍了一个项目中如何在Windows平台上实现多声道音频数据的采集,特别是针对DANTE音频接口的8路立体声音频通道。文章详细描述了使用Windows底层音频API进行音频采集的方法,并提供了一个具体的实现示例。 ... [详细]
author-avatar
关注前世男友
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有