网站建设公司推广/成都搜狗seo

   日期:2024-12-29     作者:u11xu       评论:0    移动:http://oml01z.riyuangf.com/mobile/news/13704.html
核心提示:之前写过很多单页面python爬虫,感觉python还是很好用的,这里用java总结一个多页面的爬虫,迭代爬取种子页面

之前写过很多单页面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();

}

 
特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。

举报收藏 0打赏 0评论 0
 
更多>同类最新资讯
0相关评论

相关文章
最新文章
推荐文章
推荐图文
最新资讯
点击排行
{
网站首页  |  关于我们  |  联系方式  |  使用协议  |  隐私政策  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号