1. 需求:查找四川大学所有学院的网站的网址中的通知和新闻——以计算机学院为例
  2. 流程图

  3. 具体步骤

      (1) 学院的主页为:http://cs.scu.edu.cn/ 获取该页面的所有内容(本文只获取新闻的具体内容,通知的只需要更改下正则表达式) 

      

 /**
* 获取要抓取页面的所有内容
* @param url 网页地址
* @return
*/
public static String sendGet(String url) { BufferedReader in = null;
String result = "";
// 通过HttpClientBuilder创建HttpClient
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
CloseableHttpClient client = httpClientBuilder.build(); HttpGet httpGet = new HttpGet(url);
// 设置请求和传输超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000).build();
httpGet.setConfig(requestConfig); System.out.println(httpGet.getRequestLine()); try {
HttpResponse httpResponse = client.execute(httpGet); int statusCode = httpResponse.getStatusLine().getStatusCode(); // 响应状态
System.out.println("status:" + statusCode);
if (statusCode == HttpStatus.SC_OK) {
// 获取响应的消息实体
HttpEntity entity = httpResponse.getEntity(); // 判断实体是否为空
if (entity != null) {
System.out.println("contentEncoding:"
+ entity.getContentLength()); in = new BufferedReader(new InputStreamReader(
entity.getContent(), "GBK")); String line;
while ((line = in.readLine()) != null) {
// 遍历抓取到的每一行并将其存储到result里面
result += line;
}
}
}
} catch (Exception e) { e.printStackTrace();
} finally {
try {
client.close();
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}

    (2) 使用正则表达式提取通知页面和新闻页面的地址

      指向新闻页的地址源码为:<MAP name=Map3><AREA shape=RECT target=_blank coords=498,27,539,37 href="/cs/xyxw/H9501index_1.htm">

      所以正则表达式为:coords=498,27,539,37 href=\"(.+?)\">

      

      指向通知页的地址源码为:<MAP name=Map6><AREA shape=RECT target=_blank coords=498,11,538,23 href="/cs/xytz/H9502index_1.htm"></MAP>

       所以正则表达式可以为:coords=498,11,538,23 href=\"(.+?)\">

      

   /**
* 查找主页中的新闻和通知的URL
* @param context 主页内容
* @param type 查找类型
* @return
*/
public static String getURL(String context, int type) { Pattern pattern;
Matcher matcher; if (type == 0) {// 当type=0时,查找新闻
// 创建Pattern对象
pattern = Pattern.compile("coords=498,27,539,37 href=\"(.+?)\">");
// 创建Matcher对象,并匹配
matcher = pattern.matcher(context); if (matcher.find()) {// 查看是否找到,找到返回
return "http://cs.scu.edu.cn" + matcher.group(1);
}
} else if (type == 1) {// 当type=1时,查找通知
pattern = Pattern.compile("coords=498,11,538,23 href=\"(.+?)\">");
matcher = pattern.matcher(context);
if (matcher.find()) {
return "http://cs.scu.edu.cn" + matcher.group(1);
}
} else {
return "输入的type不正确";
}
return null;
}

    

    得到新闻和通知地址:

    a) 新闻页面地址为 http://cs.scu.edu.cn/cs/xyxw/H9501index_1.htm

    b) 通知页面地址为 http://cs.scu.edu.cn/cs/xytz/H9502index_1.htm

   (3)获取所有新闻的URL:(以新闻为例

    

    新闻的具体内容的地址在源码中的表示:

          <A href=/cs/xyxw/webinfo/2016/06/1466645005004306.htm target=_blank>计算机学院(软件学院)第三届第六次双代会圆满举行</A></TD></TD><TD><DIV align=right><FONT size=2>[2016-06-30]

      所以正则匹配表达式为:<A href=/cs/xyxw/webinfo(.+?) target=_blank>

    

     /**
* 查询具体新闻所在页面的所有URL
* @param url
* @return
*/
public static List<String> getRealURL(String url) { // 存储URL地址
List<String> list = new ArrayList<>();
// 获取的主页内容
String context = sendGet(url);
System.out.println(context);
// 匹配新闻地址的正则表达式
Pattern pattern = Pattern
.compile("<A href=/cs/xyxw/webinfo(.+?) target=_blank>");
Matcher matcher = pattern.matcher(context); // 匹配url中的数字2(2表示页数,可以通过观察地址得出) :
// http://cs.scu.edu.cn/cs/xyxw/H9501index_2.htm
// http://cs.scu.edu.cn/cs/xyxw/H9501index_3.htm
Pattern patternNext = Pattern.compile("index_(.+?).htm");
Matcher matcherNext = patternNext.matcher(url); int i = 0;
if (matcherNext.find()) {
System.out.println(matcherNext.group(1));
// 设置i为当前页数
i = Integer.parseInt(matcherNext.group(1));
} boolean isFind = matcher.find(); while (isFind) {
while (isFind) {// 遍历当前页的所有新闻的URL
// 将获取的URL存储到list中
list.add("http://cs.scu.edu.cn/cs/xyxw/webinfo"
+ matcher.group(1));
isFind = matcher.find();
} i++;
// 下一页地址
String nextUrl = "http://cs.scu.edu.cn/cs/xyxw/H9501index_" + i + ".htm";
context = sendGet(nextUrl);
// 匹配新页面
matcher = pattern.matcher(context);
isFind = matcher.find();
}
return list;
}

      得到结果:

    (4)获取具体新闻页的信息:

      a)使用封装类:

      

 package com.huang.domain;

 import java.util.Date;

 public class Message {

     private String type; //类型是新闻还是通知

     private String title; //信息标题

     private Date date;    //信息发布时间

     private String pic; //相关图片

     private String context;    //具体信息内容

     public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
} public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "Message [title=" + title + ", date=" + date + ", pic=" + pic
+ ", context=" + context + "]";
}
}

    (b)获取新闻具体页的信息:

    

        

   /**
* 获取所有新闻页和通知页具体信息
* @param listUrl
* @return
*/
public static List<Message> getAllInformation(List<String> listUrl) { Pattern pattern;
Matcher matcher;
// 存储查到的每条新闻
List<Message> list = new ArrayList<>(); // 根据前面获取的所有页面的url,遍历所有的信息主页,获取相关信息
for (String url : listUrl) { Message message = new Message();
// 获取当页信息的全部信息
String context = sendGet(url);
// 获取标题
pattern = Pattern.compile("<DIV align=center> (.+?)</DIV>");
matcher = pattern.matcher(context);
if (matcher.find()) {// 设置标题
message.setTitle(matcher.group(1));
}
// 获取日期
pattern = Pattern.compile("</SPAN> ([0-9].+?)<SPAN class=hangjc "
+ "style=\"LINE-HEIGHT: 30px\" valign=\"bottom\">");
matcher = pattern.matcher(context);
if (matcher.find()) {// 设置日期
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd HH:mm");//设置日期格式
try {
//将字符串转换成date类型
Date date = format.parse(matcher.group(1));
message.setDate(date);
} catch (ParseException e) {
System.out.println("日期格式不正确");
e.printStackTrace();
}
}
//获取图片
pattern = Pattern.compile("align=center src=\"(.+?).jpg\"");
matcher = pattern.matcher(context);
if (matcher.find()) {//设置图片
message.setPic("http://cs.scu.edu.cn/" + matcher.group(1)
+ ".jpg");
}
//获取内容
pattern = Pattern.compile("<DIV id=BodyLabel>.+?</DIV>");
matcher = pattern.matcher(context);
if (matcher.find()) {//设置内容
String result = matcher.group(0);
//过滤一些内容中的标签
result = result.replaceAll("&nbsp;", " ");
result = result.replaceAll("<br>", "\r\n");
result = result.replaceAll("<.*?>", "");
message.setContext(result);
}
//将查询到的新闻添加到list中
list.add(message);
}
return list;
}

    

    (5)测试代码:

     public static void main(String[] args) {
//获取计算机学院主页中的所有信息
String context = Spider.sendGet("http://cs.scu.edu.cn/");
System.out.println(context);
//获取新闻所在页的地址
String newsUrl = Spider.getURL(context, 0);
//查找每个新闻的地址
List<String> listUrl = Spider.getRealURL(newsUrl);
System.out.println(listUrl);
//查到出每个新闻的内容
List<Message> messages = Spider.getAllInformation(listUrl); System.out.println(messages); }

  (java正则知识可以参考:http://www.runoob.com/java/java-regular-expressions.html)

  

    

      

java爬虫查找四川大学所有学院的网站的网址中的通知和新闻——以计算机学院为例的更多相关文章

  1. java爬虫爬取https协议的网站时,SSL报错, java.lang.IllegalArgumentException TSLv1.2 报错

    目前在广州一家小公司实习,这里的学习环境还是挺好的,今天公司从业十几年的大佬让我检查一下几年前的爬虫程序是否还能使用…… 我从myeclipse上check out了大佬的程序,放到workspace ...

  2. 转:【Java并发编程】之十一:线程间通信中notify通知的遗漏(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17228213 notify通知的遗漏很容易理解,即threadA还没开始wait的时候,t ...

  3. 【Java并发编程】之十一:线程间通信中notify通知的遗漏

    notify通知的遗漏很容易理解,即threadA还没开始wait的时候,threadB已经notify了,这样,threadB通知是没有任何响应的,当threadB退出synchronized代码块 ...

  4. Java爬虫系列二:使用HttpClient抓取页面HTML

    爬虫要想爬取需要的信息,首先第一步就要抓取到页面html内容,然后对html进行分析,获取想要的内容.上一篇随笔<Java爬虫系列一:写在开始前>中提到了HttpClient可以抓取页面内 ...

  5. Java 爬虫遇到需要登录的网站,该怎么办?

    这是 Java 网络爬虫系列博文的第二篇,在上一篇 Java 网络爬虫,就是这么的简单 中,我们简单的学习了一下如何利用 Java 进行网络爬虫.在这一篇中我们将简单的聊一聊在网络爬虫时,遇到需要登录 ...

  6. Java爬虫爬取网站电影下载链接

    之前有看过一段时间爬虫,了解了爬虫的原理,以及一些实现的方法,本项目完成于半年前,一直放在那里,现在和大家分享出来. 网络爬虫简单的原理就是把程序想象成为一个小虫子,一旦进去了一个大门,这个小虫子就像 ...

  7. (java)selenium webdriver爬虫学习--爬取阿里指数网站的每个分类的top50 相关数据;

    主题:java 爬虫--爬取'阿里指数'网站的每个分类的top50 相关数据: 网站网址为:http://index.1688.com/alizs/top.htm?curType=offer& ...

  8. webmagic的设计机制及原理-如何开发一个Java爬虫

    之前就有网友在博客里留言,觉得webmagic的实现比较有意思,想要借此研究一下爬虫.最近终于集中精力,花了三天时间,终于写完了这篇文章.之前垂直爬虫写了一年多,webmagic框架写了一个多月,这方 ...

  9. 爬虫6:多页面增量Java爬虫-sina主页

    之前写过很多单页面python爬虫,感觉python还是很好用的,这里用java总结一个多页面的爬虫,迭代爬取种子页面的所有链接的页面,全部保存在tmp路径下. 1 序言 实现这个爬虫需要两个数据结构 ...

随机推荐

  1. Bootstrap入门(八)组件2:下拉菜单

    Bootstrap入门(八)组件2:下拉菜单   先引入本地的CSS文件和JS文件(注:1.bootstrap是需要jQuery支持的.2.需要在<body>当中添加) <link ...

  2. 第三章 Python 的容器: 列表、元组、字典与集合

    列表是Python的6种内建序列(列表,元组,字符串,Unicode字符串,buffer对象,xrange对象)之一, 列表内的值可以进行更改,操作灵活,在Python脚本中应用非常广泛 列表的语法格 ...

  3. 从RPC开始(二)、序列化

    在C++的世界里构建一个序列化框架:并非一件困难的事情,但也并非简单.因此,需要分成两部分来完成这项任务: 1.序列化容器. 2.序列化方式. 前者,很容易理解:但也决定着我们将要存储数据的方式:二进 ...

  4. ES2:ElasticSearch 集群配置

    ElasticSearch共有两个配置文件,都位于config目录下,分别是elasticsearch.yml和logging.yml,其中,elasticsearch.yml 用来配置Elastic ...

  5. 正则匹配所有的a标签

    <a\b[^>]+\bhref="([^"]*)"[^>]*>([\s\S]*?)</a>分组1和分组2即为href和value解释: ...

  6. 如何用CSS进行网页布局---学习总结

    页面布局:对页面的文字.图形或表格进行格式设置.包括字体.字号.颜色纸张大小和方向以及页边距等 页面布局分为4种: 一栏布局 两栏布局 三栏布局 混合布局 灵活利用float.position对页面进 ...

  7. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...

  8. Asp.net mvc 知多少(六)

    本系列主要翻译自<ASP.NET MVC Interview Questions and Answers >- By Shailendra Chauhan,想看英文原版的可访问http:/ ...

  9. Html中插入javascript不识别问题

    今天,在敲代码的时候往html中加入一个JavaScript代码段.如下所示,加入后var没有自动变颜色,起初以为没有大问题,于是就接着往下敲. 调试的时候,发现没有反应. <script la ...

  10. 【吐血整理】svn命令行,Subversion的正确使用姿势~

    一.写在前面 前面一直博主一直用svn的桌面版本,但看项目经理一直都用的命令行方式,不为性能,还能直接装逼呀!在这里先感谢赵哥,也把它分享给感兴趣的你们~ 二.直接上干货 1. svn checkou ...