分享好友 最新资讯首页 最新资讯分类 切换频道
网站建设公司推广/成都搜狗seo
2024-12-29 17:14

之前写过很多单页面python爬虫,感觉python还是很好用的,这里用java总结一个多页面的爬虫,迭代爬取种子页面的所有链接的页面,全部保存在tmp路径下。

1 序言

实现这个爬虫需要两个数据结构支持,unvisited队列(priorityqueue:可以适用pagerank等算法计算出url重要度)和visited表(hashset:可以快速查找url是否存在);队列用于实现宽度优先爬取,visited表用于记录爬取过的url,不再重复爬取,避免了环。java爬虫需要的工具包有httpclient和htmlparser1.5,可以在maven repo中查看具体版本的下载。

1目标网站:新浪  http://www.sina.com.cn/

2结果截图

下面说说爬虫的实现,后期源码会上传到github中,需要的朋友可以留言

二 爬虫编程

1创建种子页面的url

MyCrawler crawler = newMyCrawler();

crawler.crawling(new String[]{"http://www.sina.com.cn/"});

2初始化unvisited表为上面的种子url

LinkQueue.addUnvisitedUrl(seeds[i]);

3最主要的逻辑实现部分:在队列中取出没有visit过的url,进行下载,然后加入visited的表,并解析改url页面上的其它url,把未读取的加入到unvisited队列;迭代到队列为空停止,所以这个url网络还是很庞大的。注意,这里的页面下载和页面解析需要java的工具包实现,下面具体说明下工具包的使用。

while(!LinkQueue.unVisitedUrlsEmpty()&&LinkQueue.getVisitedUrlNum()<=1000)

{//队头URL出队列

String visitUrl=(String)LinkQueue.unVisitedUrlDeQueue();if(visitUrl==null)continue;

DownLoadFile downLoader=newDownLoadFile();//下载网页

downLoader.downloadFile(visitUrl);//该 url 放入到已访问的 URL 中

LinkQueue.addVisitedUrl(visitUrl);//提取出下载网页中的 URL

Set links=HtmlParserTool.extracLinks(visitUrl,filter);//新的未访问的 URL 入队

for(String link:links)

{

LinkQueue.addUnvisitedUrl(link);

}

}

4下面html页面的download工具包

publicString downloadFile(String url) {

String filePath= null;HttpClient httpClient= newHttpClient();//设置 Http 连接超时 5s

httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);GetMethod getMethod= newGetMethod(url);//设置 get 请求超时 5s

getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);//设置请求重试处理

getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,newDefaultHttpMethodRetryHandler());

try{int statusCode =httpClient.executeMethod(getMethod);//判断访问的状态码

if (statusCode !=HttpStatus.SC_OK) {

System.err.println("Method failed:"

+getMethod.getStatusLine());

filePath= null;

}

byte[] responseBody = getMethod.getResponseBody();//读取为字节数组//根据网页 url 生成保存时的文件名

filePath = "temp\"

+getFileNameByUrl(url, getMethod.getResponseHeader("Content-Type").getValue());

saveToLocal(responseBody, filePath);

}catch(HttpException e) {//发生致命的异常,可能是协议不对或者返回的内容有问题

System.out.println("Please check your provided http address!");

e.printStackTrace();

}catch(IOException e) {//发生网络异常

e.printStackTrace();

}finally{//释放连接

getMethod.releaseConnection();

}returnfilePath;

}

5html页面的解析工具包

public static SetextracLinks(String url, LinkFilter filter) {

Set links = new HashSet();try{

Parser parser= newParser(url);

parser.setEncoding("gb2312");//过滤 标签的 filter,用来提取 frame 标签里的 src 属性所表示的链接

NodeFilter frameFilter = newNodeFilter() {publicboolean accept(Node node) {if (node.getText().startsWith("frame src=")) {return true;

}else{return false;

}

}

};//OrFilter 来设置过滤 标签,和 标签

OrFilter linkFilter = new OrFilter(newNodeClassFilter(

LinkTag.class), frameFilter);//得到所有经过过滤的标签

NodeList list =parser.extractAllNodesThatMatch(linkFilter);for (int i = 0; i < list.size(); i++) {

Node tag=list.elementAt(i);if (tag instanceof LinkTag)// 标签

{

LinkTag link=(LinkTag) tag;

String linkUrl= link.getLink();//url

if(filter.accept(linkUrl))

links.add(linkUrl);

}else// 标签

{//提取 frame 里 src 属性的链接如

String frame =tag.getText();int start = frame.indexOf("src=");

frame=frame.substring(start);int end = frame.indexOf(" ");if (end == -1)

end= frame.indexOf(">");

String frameUrl= frame.substring(5, end - 1);if(filter.accept(frameUrl))

links.add(frameUrl);

}

}

}catch(ParserException e) {

e.printStackTrace();

}returnlinks;

}

6未访问页面使用PriorityQueue带偏好的队列保存,主要是为了适用于pagerank等算法,有的url忠诚度更高一些;visited表采用hashset实现,注意可以快速查找是否存在

public classLinkQueue {//已访问的 url 集合

private static Set visitedUrl = newHashSet();//待访问的 url 集合

private static Queue unVisitedUrl = newPriorityQueue();//获得URL队列

public staticQueue getUnVisitedUrl() {returnunVisitedUrl;

}//添加到访问过的URL队列中

public static voidaddVisitedUrl(String url) {

visitedUrl.add(url);

}//移除访问过的URL

public static voidremoveVisitedUrl(String url) {

visitedUrl.remove(url);

}//未访问的URL出队列

public staticObject unVisitedUrlDeQueue() {returnunVisitedUrl.poll();

}//保证每个 url 只被访问一次

public static voidaddUnvisitedUrl(String url) {if (url != null && !url.trim().equals("")&& !visitedUrl.contains(url)&& !unVisitedUrl.contains(url))

unVisitedUrl.add(url);

}//获得已经访问的URL数目

public static intgetVisitedUrlNum() {returnvisitedUrl.size();

}//判断未访问的URL队列中是否为空

public staticboolean unVisitedUrlsEmpty() {returnunVisitedUrl.isEmpty();

}

最新文章
AI代码生成器:解放程序员的双手,让编程更简单
AI代码生成器:解放程序员的双手,让编程更简单!伙伴们,你们知道吗?最近我发现了一个编程神器,AI代码生成器!它简直就是解放
(完整word版)小学课程表模板.doc
1、课程表时间星期一星期二星期三星期四星期五类别早读第一节上第二节午第三节第四节第五节下第六节午第七节纳金小学课程表时间
4种方式,用ChatGPT实现副业赚钱,普通人都能用
这篇文章至少值100万,仔细看下去。 最近沉迷于玩ChatGPT,我敢说,这东西绝对能颠覆互联网,颠覆各行
ai绘图关键词推荐
ai绘图关键词推荐,ai绘图每天无限制无次数制作AI图画,是目前比较火热且新颖的新技术,那么有哪些比较合适的AI绘画关键词呢?接
AI写作助手对提升写作技能的全方位影响与效果评估
在当今数字化时代人工智能技术的发展已经渗透到各个领域其中自然语言应对技术的应用尤为广泛。写作助手作为一种新型的辅助工具在
2023加拿大硕士计算机专业排名哪些大学上榜?申请条件学费各多少?
  去加拿大读计算机专业是很多在校生及打工族的梦想,加拿大不仅有领先全球的计算机研究背景,更有宽松的移民政策,让IT专业精
ai作词创作版:在线作词作曲,一键生成歌词
随着科技的发展人工智能已经渗透到各个领域音乐创作也不例外。作词创作版作为一种新兴的音乐创作工具为广大音乐爱好者和创作者提
AI生成论文开题报告:智能系统实现与操作指南
在当今信息时代人工智能技术正以前所未有的速度发展,其在学术研究领域的应用也日益广泛。生成论文开题报告作为一种新兴的研究工
cms网站怎么做
CMS网站搭建全攻略:从入门到精通随着互联网的快速发展,越来越多的企业和个人开始意识到拥有一个自己的网站的重要性。而内容管