【搜索引擎Jediael开发笔记】V0.1完整代码 2014-05-26 15:16 443人阅读 评论(0) 收藏
详细代码请见
E:\Project\【重要】归档代码\SearchEngine归档代码
或
https://code.csdn.net/jediael_lu/jediael/tree/10991c839c51d32f825708b09451b2618a20ee94
或
http://download.csdn.net/detail/jediael_lu/7402827
本版本完成以下功能:
(1)创建用于保存种子URL的配置文件及其数据结构
(2)创建用于保存Todo信息(未下载URL)的数据结构
(3)创建用于保存Visited信息(已下载的URL)的数据结构
(4)下载网页时同步更新Tode与Visited。下载网页前,判断某个网页是否已经下载过。
(5)从上述第3步下载的网页抽取链接并继续下载,直到Todo列表为空。
(6)为每个种子url创建一个独立的线程。
至此,搜索引擎已具体基本功能。
下一阶段工作:
(1)引入dao,使用数据库保存一些信息,如种子url等?
(2)使用Berkey DB保存Frontier?使用布隆过滤器保存已访问的url。
(3)继续学习后面内容,引入其它内容。如访问blog.csdn.net时,返回403。
1、创建用于保存种子url的数据结构
由于一般而言,种子url的数据量均小,因此先使用PriorityQueue,以图方便,今后视应用情况修改成其它数据结构。
package org.ljh.search.frontier; import java.util.PriorityQueue; public class SeekUrlQueue {
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//保存种子url的队列。由于一般而言,种子url的数据量均小,因此先使用PriorityQueue,以图方便,今后视应用情况修改成其它数据结构。
<span style="white-space:pre"> </span>private PriorityQueue<String> seekUrlQueue = new PriorityQueue<String>(); <span style="white-space:pre"> </span>//Getter
<span style="white-space:pre"> </span>public PriorityQueue<String> getSeekUrlQueue() {
<span style="white-space:pre"> </span>return seekUrlQueue;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//将url添加至种子url队列中
<span style="white-space:pre"> </span>public boolean add(String url){
<span style="white-space:pre"> </span>return seekUrlQueue.add(url);
<span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>//判断种子url队列是否为空
<span style="white-space:pre"> </span>public boolean isEmpty(){
<span style="white-space:pre"> </span>return seekUrlQueue.isEmpty();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//从种子url队列中获取下一个种子url
<span style="white-space:pre"> </span>public String getNext(){
<span style="white-space:pre"> </span>return seekUrlQueue.poll();
<span style="white-space:pre"> </span>}<span style="white-space:pre"> </span>
}
2、创建用于保存已访问url的数据结构
(1)先创建一个接口,用于提供最基本功能
package org.ljh.search.frontier; public interface VisitedUrlQueue { //判断某个Url是否已经存在于已访问队列中
public boolean contains(String url); //将已下载的url放入已访问的列表
public boolean add(String url); }
(2)创建具体的实施类
package org.ljh.search.frontier; import java.util.HashSet; public class HashSetVisitedUrlQueue implements VisitedUrlQueue{ //用于保存已访问的Url的数据结构。由于已访问列表会被经常查询,因此,使用HashSet。由于只要其中任何一个线程下载过,此url即算做已经下载,因此使用了static。
private static HashSet<String> visitedUrlQueue = new HashSet<String>(); public HashSet<String> getVisitedUrlQueue() {
return visitedUrlQueue;
} @Override
public boolean contains(String url) {
return visitedUrlQueue.contains(url);
} @Override
public boolean add(String url) {
visitedUrlQueue.add(url);
return true;
}
}
3、创建待访问的url列表的数据结构
(1)先创建接口
package org.ljh.search.frontier; public interface Frontier {
//获取下一个待访问的url
public String getNextUrl(); //将从其它网页中提取出来的url放到待访问url中。
public boolean putUrlIntoTodoQueue(String url); }
(2)创建具体实现类
package org.ljh.search.frontier; import java.util.PriorityQueue; public class PriorityQueueFrontier implements Frontier { //保存待访问的url的列表。考虑到先入先出及可在一定程度上控制访问顺序,即带偏好的宽度优先搜索策略,使用了PriorityQueue。
private PriorityQueue<String> todoUrlQueue = new PriorityQueue<String>(); @Override
public String getNextUrl() {
return todoUrlQueue.poll();
} @Override
public boolean add(String url) {
todoUrlQueue.add(url);
return true;
} @Override
public boolean isEmpty(){
return todoUrlQueue.isEmpty();
} }
4、修改主类
(1)下载网页前,判断某个网页是否已经下载过。
(2)分析刚下载的网页,提取链接,继续放入frontier。
(3)为每个种子url创建一个独立的线程。
package org.ljh.search; import java.io.IOException;
import java.util.Iterator;
import java.util.Set; import org.ljh.search.downloadpage.PageDownloader;
import org.ljh.search.frontier.HashSetVisitedUrlQueue;
import org.ljh.search.frontier.PriorityQueueFrontier;
import org.ljh.search.frontier.SeekUrlQueue;
import org.ljh.search.html.HtmlParserTool;
import org.ljh.search.html.LinkFilter; public class MyCrawler { public static void main(String[] args) { // 种子url
final SeekUrlQueue seekUrlQueue = new SeekUrlQueue();
seekUrlQueue.add("http://www.sohu.com");
seekUrlQueue.add("http://www.baidu.com");
seekUrlQueue.add("http://www.eoeandroid.com/"); // 已访问过的url
final HashSetVisitedUrlQueue visitedUrl = new HashSetVisitedUrlQueue(); // 设定过滤器,用于指明搜索范围
final LinkFilter linkFilter = new LinkFilter() {
@Override
public boolean accept(String url) {
if ((url.contains("baidu") || url.contains("sohu")||url.contains("eoe"))
&& !url.contains("baike") && !url.contains("@")) {
return true;
} else {
return false;
}
}
}; while (!seekUrlQueue.isEmpty()) { // 根据种子url对frontier进行初始化
final String nextSeek = seekUrlQueue.getNext();
System.out.println(nextSeek); //为每一个种子url,启动一个线程
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// 待访问 的url
PriorityQueueFrontier frontier = new PriorityQueueFrontier();
frontier.add(nextSeek); //直到frontier为空,才会结束下载
while (!frontier.isEmpty()) {
//获取下一个待访问的url,然后判断是否已经访问过,若否,则下载,并将其添加到已访问列表。
String nextUrl = frontier.getNextUrl();
if (!visitedUrl.contains(nextUrl)) {
try {
PageDownloader.downloadPageByGetMethod(nextUrl);
} catch (IOException e) {
e.printStackTrace();
}
visitedUrl.add(nextUrl); //从刚下载的页面中提取链接,并将其放入frointier.正常而言,应该使用刚下载到本地的文件作参数,但此处还是使用了url,会导致再一次连接网络。
Set<String> urlSet = HtmlParserTool.extractLinks(
nextUrl, linkFilter);
Iterator<String> iterator = urlSet.iterator();
while (iterator.hasNext()) {
frontier.add(iterator.next());
}
}
}
} }); t.start();
}
} }
版权声明:本文为博主原创文章,未经博主允许不得转载。
【搜索引擎Jediael开发笔记】V0.1完整代码 2014-05-26 15:16 443人阅读 评论(0) 收藏的更多相关文章
- 【搜索引擎Jediael开发笔记】v0.1完整代码 2014-05-26 15:17 463人阅读 评论(0) 收藏
详细代码请见 E:\Project\[重要]归档代码\SearchEngine归档代码 或 https://code.csdn.net/jediael_lu/jediael/tree/10991c83 ...
- Latex笔记(参考文献) 分类: LaTex 2014-11-08 17:41 239人阅读 评论(0) 收藏
当你用LaTeX来写文档,在管理参考文献时,你可能会用到bibtex, 也许你会嫌麻烦,会选择用 \begin{thebibliography}{10} \bibitem xxxx \bibitem ...
- shell入门之变量测试 分类: 学习笔记 linux ubuntu 2015-07-10 15:49 31人阅读 评论(0) 收藏
格式:test 测试条件 字符串测试: 注意空格: test str1 == str2 测试字符串是否相等 test str1 != str2 测试字符串是否不相等 test str1 测试字符串是否 ...
- 公众号第三方平台开发 获取 component_verify_ticket 2015-07-05 10:16 59人阅读 评论(0) 收藏
8.推送component_verify_ticket协议 在公众号第三方平台创建审核通过后,微信服务器会向其"授权事件接收URL"每隔10分钟定时推送component_veri ...
- 使用Broadcast实现android组件之间的通信 分类: android 学习笔记 2015-07-09 14:16 110人阅读 评论(0) 收藏
android组件之间的通信有多种实现方式,Broadcast就是其中一种.在activity和fragment之间的通信,broadcast用的更多本文以一个activity为例. 效果如图: 布局 ...
- ubuntu常用文件搜索命令 分类: linux 学习笔记 ubuntu 2015-07-05 15:40 84人阅读 评论(0) 收藏
1.find find [搜索路径] [搜索关键字] 比如查找/test中文件名为t5.tmp的文件: 查找根目录下大于100M的文件 注意,这里的204800单位是块,1块=512字节 在根目录下查 ...
- shell脚本实现冒泡排序 分类: 学习笔记 linux ubuntu 2015-07-10 14:16 79人阅读 评论(0) 收藏
手动输入一行字符串,并对其排序. 脚本如下: #!/bin/bash #a test about sort echo "please input a number list" re ...
- iOS开发 调用系统相机和相册 分类: ios技术 2015-03-30 15:52 65人阅读 评论(0) 收藏
调用系统相机和相册 (iPad,iPhone) 打开相机:(iPad,iPhone) //先设定sourceType为相机,然后判断相机是否可用(ipod)没相机,不可用将sourceType设定为 ...
- 架构师速成6.7-设计开发思路-uml 分类: 架构师速成 2015-07-29 18:25 157人阅读 评论(0) 收藏
uml是什么东西?统一建模语言,一门语言,是用来进行软件设计的一门语言. 其实一门语言的诞生并不伟大,让大多数人都使用才足够伟大.uml就是一门伟大的语言,因为目前软件设计的唯一语言就是它. UML其 ...
随机推荐
- Android开发经验之获取画在画布上的字符串长度、宽度(所占像素宽度)
Android中获取字符串长度.宽度(所占像素宽度) 计算出当前绘制出来的字符串有多宽,可以这么来! 方法1: Paint paint = new Paint(); Rect rect = new R ...
- 关于Sleep函数介绍
函数名: Sleep 功 能: 执行挂起一段时间 用 法: void Sleep(DWORD dwMilliseconds); 在VC中使用带上头文件 #include <windows.h&g ...
- 2.3 Streams API 官网剖析(博主推荐)
不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ 2.3 Streams API 2.3 Streams API 在0..0增加了一个 ...
- bind()和trigger()额外数据
$(function(){ $('input').click(function(e,data1,data2,data3,data4){ alert(data1 + '|' + data2 + '|' ...
- 新手前端笔记之--初识html标签
接触前端(好大气的名字啊)已经一个多月了,看了很多视频和博客,有了一定的感性认识,但还是需要总结一下以便系统化所学习的知识,就从html标签开始吧.关于标签,谈论最多的就是简洁和语义化.简洁指html ...
- 洛谷 P1755 斐波那契的拆分
P1755 斐波那契的拆分 题目背景 无 题目描述 已知任意一个正整数都可以拆分为若干个斐波纳契数,现在,让你求出n的拆分方法 输入输出格式 输入格式: 一个数t,表示有t组数据 接下来t行,每行一个 ...
- 三个水杯(BFS)
三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描写叙述 给出三个水杯.大小不一,而且仅仅有最大的水杯的水是装满的,其余两个为空杯子. 三个水杯之间相互倒水,而且水杯 ...
- python3 turtle画正方形、矩形、正方体、五角星、奥运五环
python3 环境 turtle模块 分别画出 正方形.矩形.正方体.五角星.奥运五环 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:H ...
- 5.容器管理【Docker每天5分钟】
原文:5.容器管理[Docker每天5分钟] Docker给PaaS世界带来的“降维打击”,其实是提供了一种非常便利的打包机制.该机制打包了应用运行所需要的整个操作系统,从而保证了本地环境和云端环境的 ...
- REGEXP_LIKE,REGEXP_INSTR,REGEXP_SUBSTR,REGEXP_REPLACE
参考: http://www.cnblogs.com/scottckt/archive/2012/10/11/2719562.html http://www.jb51.net/article/3842 ...