热门标签 | 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


推荐阅读
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
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社区 版权所有