myCrawler.java

package WebCrawler;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue; public class MyCrawler { private static final String SAVEPATH = "C:"+File.separator+"downloadURL"; public void crawl(ArrayList<URL> urls, int depth) { //初始化队列
Queue<URL> q = new LinkedList<URL>();
ArrayList<URL> visited = new ArrayList<URL>();
q.addAll(urls); while (!q.isEmpty()) { URL head = q.poll(); //出列
if(head.getDepth() > depth){
break;
}
visited.add(head);
String page = HtmlParserTool.getPage(head.toString());
String charset = HtmlParserTool.getCharset(page);
String urlFullPath = SAVEPATH+File.separator+head.toString().replaceAll("[?:<>*|////]","_")+".html";
HtmlParserTool.writeToDisk(urlFullPath, page, charset); //保存到磁盘
ArrayList<String> toVisit = HtmlParserTool.extractLinks(page); for (String s : toVisit) {
if (!visited.contains(s)) {
//visited.add(s);
q.add(new URL(s, head.getDepth()+1));
}
} }
} public static void main(String[] args) throws Exception { ArrayList<URL> urls = new ArrayList<URL>();
urls.add(new URL("http://www.baidu.com"));
new MyCrawler().crawl(urls,1);
}
}

HtmlParserTool.java

package WebCrawler;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.htmlparser.Parser;
import org.htmlparser.Tag;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.visitors.NodeVisitor; public class HtmlParserTool { //判断字符串是否是一个网址
private static boolean isValidUrl(String url) {
if (url.startsWith("http") | url.startsWith("https")) {
return true;
} else {
return false;
}
} //获取网页包含的超链接
public static ArrayList<String> extractLinks(String content){ ArrayList<String> links = new ArrayList<String>();
Parser parser = null;
NodeVisitor visitor = null;
try {
parser = new Parser(content);
visitor = new NodeVisitor() { @Override
public void visitTag(Tag tag) {
if(tag instanceof LinkTag) {
LinkTag link = (LinkTag)tag;
String linkString = link.getLink();
if(isValidUrl(linkString) && !links.contains(linkString)) {
links.add(linkString);
}
}
}
};
parser.visitAllNodesWith(visitor); } catch (Exception e) {
e.printStackTrace();
} return links;
} //获取字符集
public static String getCharset(String content) {
int startIdx = content.indexOf("charset");
int endIdx = content.indexOf("\"", startIdx+9);
String charset = content.substring(startIdx+9, endIdx);
return charset;
} //获取网页内容
public static String getPage(String url) { CloseableHttpClient client = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
String content="";
try {
CloseableHttpResponse response = client.execute(request);
//System.out.println("Response Code: " + response.getStatusLine().getStatusCode()); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); String line = "";
while ((line = rd.readLine()) != null) {
content = content + line + "\n";
} response.close();
client.close();
String charset = getCharset(content);
if(charset != null) {
content = new String(content.getBytes(),charset);
} } catch (Exception e) {
e.printStackTrace();
} return content;
} //将网页内容写至磁盘
public static void writeToDisk(String path, String content, String charset){ try {
File file = new File(path);
OutputStream o = new FileOutputStream(file);
o.write(content.getBytes(charset));
o.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

URL.java

package WebCrawler;

public class URL {

    private String url;
private int depth; public URL(String url) {
this.url = url;
this.depth = 1;
} public URL(String url, int depth) {
this.url = url;
this.depth = depth;
} public String toString() {
return this.url;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public int getDepth() {
return depth;
} public void setDepth(int depth) {
this.depth = depth;
}
}

用Java实现网络爬虫的更多相关文章

  1. Java之网络爬虫WebCollector2.1.2+selenium2.44+phantomjs2.1.1

    Java之网络爬虫WebCollector2.1.2+selenium2.44+phantomjs2.1.1 一.简介 版本匹配: WebCollector2.12 + selenium2.44.0 ...

  2. java之网络爬虫介绍

    文章大纲 一.网络爬虫基本介绍二.java常见爬虫框架介绍三.WebCollector实战四.项目源码下载五.参考文章   一.网络爬虫基本介绍 1. 什么是网络爬虫   网络爬虫(又被称为网页蜘蛛, ...

  3. 使用Java实现网络爬虫

    网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 另外一些不常使用的名字还有蚂蚁.自动索引.模 ...

  4. 基于java的网络爬虫框架(实现京东数据的爬取,并将插入数据库)

    原文地址http://blog.csdn.net/qy20115549/article/details/52203722 本文为原创博客,仅供技术学习使用.未经允许,禁止将其复制下来上传到百度文库等平 ...

  5. Jsoup-基于Java实现网络爬虫-爬取笔趣阁小说

    注意!仅供学习交流使用,请勿用在歪门邪道的地方!技术只是工具!关键在于用途! 今天接触了一款有意思的框架,作用是网络爬虫,他可以像操作JS一样对网页内容进行提取 初体验Jsoup <!-- Ma ...

  6. Java版网络爬虫基础(转)

    网络爬虫不仅仅可以爬取网站的网页,图片,甚至可以实现抢票功能,网上抢购,机票查询等.这几天看了点基础,记录下来. 网页的关系可以看做是一张很大的图,图的遍历可以分为深度优先和广度优先.网络爬虫采取的广 ...

  7. Java版网络爬虫基础

    网络爬虫不仅仅可以爬取网站的网页,图片,甚至可以实现抢票功能,网上抢购,机票查询等.这几天看了点基础,记录下来. 网页的关系可以看做是一张很大的图,图的遍历可以分为深度优先和广度优先.网络爬虫采取的广 ...

  8. java实现网络爬虫

    import java.io.IOException;   import java.util.HashSet;   import java.util.Set;   import java.util.r ...

  9. JAVA平台上的网络爬虫脚本语言 CrawlScript

    JAVA平台上的网络爬虫脚本语言 CrawlScript 网络爬虫即自动获取网页信息的一种程序,有很多JAVA.C++的网络爬虫类库,但是在这些类库的基础上开发十分繁琐,需要大量的代码才可以完成一 个 ...

随机推荐

  1. ORA-01102 报错解决方法

    Problem Explanation:  ====================   A database is started in EXCLUSIVE mode by default.  Th ...

  2. 适配器模式/adapter模式/结构型模式

    定义 将类的接口转化为客户端希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作,别名Wrapper(包装器). 适配器模式,最终改变一个已有对象的接口. 使用场景 当有那么个类, ...

  3. mysql开发小结

    目录 1. 使用mybatis操作mysql数据库SUM方法返回NULL解决 2. limit m,n 1. 使用mybatis操作mysql数据库SUM方法返回NULL解决解决方案一: SELECT ...

  4. 【转】Oracle索引列NULL值引发执行计划该表的测试示例

    有时开发进行表结构设计,对表字段是否为空过于随意,出现诸如id1=id2,如果允许字段为空,因为Oracle中空值并不等于空值,有可能得到意料之外的结果.除此之外,最关键的是,NULL会影响oracl ...

  5. android Context 持有导致的内存泄漏

    Context使用场景 为了防止Activity,Service等这样的Context泄漏于一些生命周期更长的对象,可以使用生命周期更长的ApplicationContext,但是不是所有的Conte ...

  6. SQL Server 日期字段作为查询标志字段的注意事项

    今天在做一个数据抽取程序时遇到一个问题困扰好久才解决,这不是技术问题,而是常识和细心的问题.写出来让大家引起重视一下. 由于之前的程序长期用Oracle,并且数据标志字段采用的日期类型.在Oracle ...

  7. python 之sqlalchemy many to one

    通过查询多个父亲,对应一个儿子 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @author: zengchuny ...

  8. php获取实时汇率数据

    支付时常常会用到支付汇率,但汇率数据是实时的,没办法首先设定好,为避免亏损,只能做到实时的了,先推荐个php函数,能实时获取汇率数据.需要curl模块支持. function getExchangeR ...

  9. *HDU1969 二分

    Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  10. mysql event_scheduler运行一段时间后 自动关闭

    应该是你重启过电脑或重启过服务了.  SELECT * FROM mysql.event;SET GLOBAL event_scheduler = 1; -- 开启定时器 0:off 1:on SHO ...