java creeper
第三方jsoup解析包 , 学习了使用jsoup解析html后就简单写个小爬虫。
1. jsoup
jsoup的使用自己百度,google,使用非常简单
2. 具体思路
最终我们的目的是得到很多网页的html文件,从一个网站入口,解析得到全部的超链接,把全部的超链接加到工作队列中继续下载网页,下载完成一个网页就分析得到新的超链接,依次循环,程序没有做重复判断。
3. 代码分析
3.1 流程类
/**启动类*/
public class Start {
//cpu核心数
public static final int CORE_CPU_NUMBER = Runtime.getRuntime().availableProcessors();
public static final int THREAD_POOL_NUMBER = CORE_CPU_NUMBER + 1;
public static boolean flag = true;
public static void main(String[] args) {
//开启线程池,我们后边的下载网页操作都是在线程中完成
ExecutorService mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_NUMBER);
/**包装了阻塞队列,初始化后添加第一个网址座位入口----------------------------------可以改写-------------------------------------------*/
BlockArrayQueueLeo.getInstance().add("https://developer.android.com/training/index.html");
//这个线程的作用是在指定的时间Constans.CREEPER_TIME内退出程序
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(Constans.CREEPER_TIME);
flag = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
String url = null;
//循环从阻塞队列中获取网址进行新的开始
while (flag){
try {
url = BlockArrayQueueLeo.getInstance().take();
//具体的下载存储内容 , 解析html得到新的超链接在线程中进行
mThreadPool.submit(new ThreadLeo(url));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.err.println(Constans.CREEPER_TIME/60+ "s run over ------------------------------------------------------------------------>" );
System.exit(0);
}
}
/**包装了队列*/
public class BlockArrayQueueLeo {
private static BlockingQueue<String> urlSets = new ArrayBlockingQueue<String>(100);
public static synchronized BlockingQueue<String> getInstance(){
return urlSets;
}
private BlockArrayQueueLeo(){
}
}
3.2 核心业务类
public class ThreadLeo extends Thread {
private String url ;
private String titleStr;
private boolean ok = true;
BufferedWriter bw;
public ThreadLeo(String url) {
this.url = url;
System.out.println(url);
}
@Override
public void run() {
try {
//使用jsoup获取网页数据
Document doc = Jsoup.connect(url)
.timeout(5000)
.ignoreHttpErrors(true)
.get();
/**获取网页标题*/
Elements heads = doc.getElementsByTag("head");
for (Element head : heads) {
Elements titles = head.getElementsByTag("title");
for (Element title : titles) {
//保存文件的名称
titleStr = title.text().replace("|", "")
.replace(":", "")
.replace("*", "")
.replace("?", "")
.replace("<", "")
.replace(">", "")
.replace("*", "").trim();
}
}
/**保存网页*/
File saveFile = new File(Constans.SAVE_DIR, titleStr + ".html");
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(saveFile)));
bw.write(doc.toString());
bw.flush();
/**继续creeper , 解析网页内容得到新的url加到队列进行新的获取*/
Elements as = doc.getElementsByTag("a");
for (Element a : as) {
String addUrl = a.attr("href");
/**依靠标签a拿到的数据好多不是url*/
if (addUrl.startsWith("http")) {
BlockArrayQueueLeo.getInstance().put(addUrl);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.成果
程序可以抓取众多网页,只是简单的一个小实践