直接上代码:

package com.jeecg.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; public class WebCrawlerDemo {
public static void main(String[] args) {
WebCrawlerDemo webCrawlerDemo = new WebCrawlerDemo();
webCrawlerDemo.myPrint("https://kyfw.12306.cn/");
}public void myPrint(String baseUrl) {
Map<String, Boolean> oldMap = new LinkedHashMap<String, Boolean>();
// 存储链接-是否被遍历
// 键值对
String oldLinkHost = ""; // host
Pattern p = Pattern.compile("(https?://)?[^/\\s]*");
// 比如:http://www.zifangsky.cn
Matcher m = p.matcher(baseUrl);
if (m.find()) {
oldLinkHost = m.group();
}
oldMap.put(baseUrl, false);
oldMap = crawlLinks(oldLinkHost, oldMap);
//oldMap = crawlLinks(baseUrl, oldMap);
for (Map.Entry<String, Boolean> mapping : oldMap.entrySet()) {
System.out.println("链接:" + mapping.getKey());
}
} /**
* * 抓取一个网站所有可以抓取的网页链接,在思路上使用了广度优先算法 *
* 对未遍历过的新链接不断发起GET请求,一直到遍历完整个集合都没能发现新的链接 * 则表示不能发现新的链接了,任务结束 * * @param
* oldLinkHost 域名,如:http://www.zifangsky.cn * @param oldMap 待遍历的链接集合 *
* * @return 返回所有抓取到的链接集合 *
*/
private Map<String, Boolean> crawlLinks(String oldLinkHost, Map<String, Boolean> oldMap) {
Map<String, Boolean> newMap = new LinkedHashMap<String, Boolean>();
String oldLink = "";
for (Map.Entry<String, Boolean> mapping : oldMap.entrySet()) {
System.out.println("link:" + mapping.getKey() + "--------check:" + mapping.getValue());
// 如果没有被遍历过
if (!mapping.getValue()) {
oldLink = mapping.getKey();
// 发起GET请求
try {
URL url = new URL(oldLink);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(2000);
connection.setReadTimeout(2000);
if (connection.getResponseCode() == 200) {
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line = "";
Pattern pattern = Pattern.compile("<a.*?href=[\"']?((https?://)?/?[^\"']+)[\"']?.*?>(.+)</a>");
Matcher matcher = null;
while ((line = reader.readLine()) != null) {
matcher = pattern.matcher(line);
if (matcher.find()) {
String newLink = matcher.group(1).trim();
// 链接
// String title = matcher.group(3).trim(); //标题
// 判断获取到的链接是否以http开头
if (!newLink.startsWith("http")) {
if (newLink.startsWith("/"))
newLink = oldLinkHost + newLink;
else
newLink = oldLinkHost + "/" + newLink;
}
// 去除链接末尾的 /
if (newLink.endsWith("/"))
newLink = newLink.substring(0, newLink.length() - 1);
// 去重,并且丢弃其他网站的链接
if (!oldMap.containsKey(newLink) && !newMap.containsKey(newLink)
&& newLink.startsWith(oldLinkHost)) {
// System.out.println("temp2: " + newLink);
newMap.put(newLink, false);
}
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} oldMap.put(oldLink, true);
}
}
// 有新链接,继续遍历
if (!newMap.isEmpty()) {
oldMap.putAll(newMap);
oldMap.putAll(crawlLinks(oldLinkHost, oldMap));
// 由于Map的特性,不会导致出现重复的键值对
}
return oldMap;
} }

运行结果如下:

一个简单的java爬虫的更多相关文章

  1. Java实现一个简单的网络爬虫

    Java实现一个简单的网络爬虫 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWri ...

  2. 超简单的java爬虫

    最简单的爬虫,不需要设定代理服务器,不需要设定cookie,不需要http连接池,使用httpget方法,只是为了获取html代码... 好吧,满足这个要求的爬虫应该是最基本的爬虫了.当然这也是做复杂 ...

  3. 一个简单的Java web服务器实现

    前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...

  4. Java学习笔记 11/15:一个简单的JAVA例子

    首先来看一个简单的 Java 程序. 来看下面这个程序,试试看是否看得出它是在做哪些事情! 范例:TestJava.java   // TestJava.java,java 的简单范例  public ...

  5. Java入门篇(一)——如何编写一个简单的Java程序

    最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...

  6. 一个简单的python爬虫程序

    python|网络爬虫 概述 这是一个简单的python爬虫程序,仅用作技术学习与交流,主要是通过一个简单的实际案例来对网络爬虫有个基础的认识. 什么是网络爬虫 简单的讲,网络爬虫就是模拟人访问web ...

  7. python实现的一个简单的网页爬虫

    学习了下python,看了一个简单的网页爬虫:http://www.cnblogs.com/fnng/p/3576154.html 自己实现了一个简单的网页爬虫,获取豆瓣的最新电影信息. 爬虫主要是获 ...

  8. Ant—使用Ant构建一个简单的Java工程(两)

    博客<Ant-使用Ant构建一个简单的Java项目(一)>演示了使用Ant工具构建简单的Java项目,接着这个样例来进一步学习Ant: 上面样例须要运行多条ant命令才干运行Test类中的 ...

  9. 一个简单的C#爬虫程序

    这篇这篇文章主要是展示了一个C#语言如何抓取网站中的图片.实现原理就是基于http请求.C#给我们提供了HttpWebRequest和WebClient两个对象,方便发送请求获取数据,下面看如何实 1 ...

随机推荐

  1. c# 泛型study

    1.引用类型约束:  类型实参包含任何类,接口,数组,委托,或者是已知是引用类型的另一个类型参数 class demo<T> where T:class 有效的封闭区间demo<St ...

  2. gRPC应用C++

    1.  gRPC简述 RPC,远程方法调用,就是像调用本地方法一样调用远程方法. gRPC是Google实现的一种RPC框架,基于HTTP/2标准设计,带来诸如双向流.流控.头部压缩.单 TCP 连接 ...

  3. 【笔记】MAML-模型无关元学习算法

    目录 论文信息: Finn C, Abbeel P, Levine S. Model-agnostic meta-learning for fast adaptation of deep networ ...

  4. ELK-Elasticsearch 基础使用

    一.基本概念 1 Node 与 Cluster Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例.单个 Elastic 实例称为一个节点( ...

  5. 团队最后一次——冲刺+Beta发布

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign/ 这个作业要求在哪里 https:// ...

  6. P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]

    题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...

  7. django 项目需要注意的一些点

    1.创建新项目    把静态文件夹的名字放在settings文件里面 STATIC_URL = '/static/' STATICFILES_DIRS=[ os.path.join(BASE_DIR, ...

  8. 通过vue-cli搭建vue项目

    一.搭建环境 安装node.js 从node.js官网下载并安装node,安装过程很简单,一路“下一步”就可以了.安装完成之后,打开命令行工具(win+r,然后输入cmd),输入 node -v,如下 ...

  9. idea拉取最新代码弹窗(Ctrl + T)

    在此设置

  10. c语言的可变参数实例

    可变参数函数实现的步骤如下: 1.在函数中创建一个va_list类型变量 2.使用va_start对其进行初始化 3.使用va_arg访问参数值 4.使用va_end完成清理工作 接下来我们来实现一个 ...