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


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

       

    2. 流程图

      3. 具体步骤

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

          

     1 /**
     2      * 获取要抓取页面的所有内容
     3      * @param url 网页地址
     4      * @return
     5      */
     6     public static String sendGet(String url) {
     7         
     8         BufferedReader in = null;
     9         String result = "";
    10         // 通过HttpClientBuilder创建HttpClient
    11         HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
    12         CloseableHttpClient client = httpClientBuilder.build();
    13         
    14         HttpGet httpGet = new HttpGet(url);
    15         // 设置请求和传输超时时间
    16         RequestConfig requestConfig = RequestConfig.custom()
    17                 .setConnectTimeout(5000).build();
    18         httpGet.setConfig(requestConfig);
    19 
    20         System.out.println(httpGet.getRequestLine());
    21 
    22         try {
    23             HttpResponse httpResponse = client.execute(httpGet);
    24 
    25             int statusCode = httpResponse.getStatusLine().getStatusCode();
    26 
    27             // 响应状态
    28             System.out.println("status:" + statusCode);
    29             if (statusCode == HttpStatus.SC_OK) {
    30                 // 获取响应的消息实体
    31                 HttpEntity entity = httpResponse.getEntity();
    32 
    33                 // 判断实体是否为空
    34                 if (entity != null) {
    35                     System.out.println("contentEncoding:"
    36                             + entity.getContentLength());
    37 
    38                     in = new BufferedReader(new InputStreamReader(
    39                             entity.getContent(), "GBK"));
    40 
    41                     String line;
    42                     while ((line = in.readLine()) != null) {
    43                         // 遍历抓取到的每一行并将其存储到result里面
    44                         result += line;
    45                     }
    46                 }
    47             }
    48         } catch (Exception e) {
    49 
    50             e.printStackTrace();
    51         } finally {
    52             try {
    53                 client.close();
    54                 if (in != null) {
    55                     in.close();
    56                 }
    57             } catch (Exception e2) {
    58                 e2.printStackTrace();
    59             }
    60         }
    61         return result;
    62     }

        (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="(.+?)">

          

     1   /**
     2      * 查找主页中的新闻和通知的URL
     3      * @param context  主页内容
     4      * @param type  查找类型
     5      * @return
     6      */
     7     public static String getURL(String context, int type) {
     8 
     9         Pattern pattern;
    10         Matcher matcher;
    11 
    12         if (type == 0) {// 当type=0时,查找新闻
    13             // 创建Pattern对象
    14             pattern = Pattern.compile("coords=498,27,539,37 href="(.+?)">");
    15             // 创建Matcher对象,并匹配
    16             matcher = pattern.matcher(context);
    17 
    18             if (matcher.find()) {// 查看是否找到,找到返回
    19                 return "http://cs.scu.edu.cn" + matcher.group(1);
    20             }
    21         } else if (type == 1) {// 当type=1时,查找通知
    22             pattern = Pattern.compile("coords=498,11,538,23 href="(.+?)">");
    23             matcher = pattern.matcher(context);
    24             if (matcher.find()) {
    25                 return "http://cs.scu.edu.cn" + matcher.group(1);
    26             }
    27         } else {
    28             return "输入的type不正确";
    29         }
    31         return null;
    32     }

         

        得到新闻和通知地址:

        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>

        

     1     /**
     2      * 查询具体新闻所在页面的所有URL
     3      * @param url
     4      * @return
     5      */
     6     public static List<String> getRealURL(String url) {
     7 
     8         // 存储URL地址
     9         List<String> list = new ArrayList<>();
    10         // 获取的主页内容
    11         String context = sendGet(url);
    12         System.out.println(context);
    13         // 匹配新闻地址的正则表达式
    14         Pattern pattern = Pattern
    15                 .compile("<A href=/cs/xyxw/webinfo(.+?) target=_blank>");
    16         Matcher matcher = pattern.matcher(context);
    17 
    18         // 匹配url中的数字2(2表示页数,可以通过观察地址得出) :
    19         //    http://cs.scu.edu.cn/cs/xyxw/H9501index_2.htm
    20         //  http://cs.scu.edu.cn/cs/xyxw/H9501index_3.htm
    21         Pattern patternNext = Pattern.compile("index_(.+?).htm");
    22         Matcher matcherNext = patternNext.matcher(url);
    23         
    24         int i = 0; 
    25         if (matcherNext.find()) {
    26             System.out.println(matcherNext.group(1));
    27             // 设置i为当前页数
    28             i = Integer.parseInt(matcherNext.group(1));
    29         }
    30 
    31         boolean isFind = matcher.find();
    32 
    33         while (isFind) {
    34             while (isFind) {// 遍历当前页的所有新闻的URL
    35                 // 将获取的URL存储到list中
    36                 list.add("http://cs.scu.edu.cn/cs/xyxw/webinfo"
    37                         + matcher.group(1));
    38                 isFind = matcher.find();
    39             }
    40             
    41             i++;
    42             // 下一页地址
    43             String nextUrl = "http://cs.scu.edu.cn/cs/xyxw/H9501index_" + i    + ".htm";
    44             context = sendGet(nextUrl);
    45             // 匹配新页面
    46             matcher = pattern.matcher(context);
    47             isFind = matcher.find();
    48         }
    49         return list;
    50     }

          得到结果:

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

          a)使用封装类:

          

     1 package com.huang.domain;
     2 
     3 import java.util.Date;
     4 
     5 public class Message {
     6 
     7     private String type; //类型是新闻还是通知
     8     
     9     private String title; //信息标题
    10     
    11     private Date date;    //信息发布时间
    12     
    13     private String pic; //相关图片
    14     
    15     private String context;    //具体信息内容
    16     
    17     public String getPic() {
    18         return pic;
    19     }
    20     public void setPic(String pic) {
    21         this.pic = pic;
    22     }
    23     
    24     public String getTitle() {
    25         return title;
    26     }
    27     public void setTitle(String title) {
    28         this.title = title;
    29     }
    30     public String getContext() {
    31         return context;
    32     }
    33     public void setContext(String context) {
    34         this.context = context;
    35     }
    36     public Date getDate() {
    37         return date;
    38     }
    39     public void setDate(Date date) {
    40         this.date = date;
    41     }
    42     public String getType() {
    43         return type;
    44     }
    45     public void setType(String type) {
    46         this.type = type;
    47     }
    48     @Override
    49     public String toString() {
    50         return "Message [title=" + title + ", date=" + date + ", pic=" + pic
    51                 + ", context=" + context + "]";
    52     }   
    56 }

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

        

            

     1   /**
     2      * 获取所有新闻页和通知页具体信息
     3      * @param listUrl
     4      * @return
     5      */
     6     public static List<Message> getAllInformation(List<String> listUrl) {
     7 
     8         Pattern pattern;
     9         Matcher matcher;
    10         // 存储查到的每条新闻
    11         List<Message> list = new ArrayList<>();
    12         
    13         // 根据前面获取的所有页面的url,遍历所有的信息主页,获取相关信息
    14         for (String url : listUrl) {
    15 
    16             Message message = new Message();
    17             // 获取当页信息的全部信息
    18             String context = sendGet(url);
    19             // 获取标题
    20             pattern = Pattern.compile("<DIV align=center> (.+?)</DIV>");
    21             matcher = pattern.matcher(context);
    22             if (matcher.find()) {// 设置标题
    23                 message.setTitle(matcher.group(1));
    24             }
    25             // 获取日期
    26             pattern = Pattern.compile("</SPAN> ([0-9].+?)<SPAN class=hangjc "
    27                     + "style="LINE-HEIGHT: 30px" valign="bottom">");
    28             matcher = pattern.matcher(context);
    29             if (matcher.find()) {// 设置日期
    30                 SimpleDateFormat format = new SimpleDateFormat(
    31                         "yyyy-MM-dd HH:mm");//设置日期格式
    32                 try {
    33                     //将字符串转换成date类型
    34                     Date date = format.parse(matcher.group(1));
    35                     message.setDate(date);
    36                 } catch (ParseException e) {
    37                     System.out.println("日期格式不正确");
    38                     e.printStackTrace();
    39                 }
    40             }
    41             //获取图片
    42             pattern = Pattern.compile("align=center src="(.+?).jpg"");
    43             matcher = pattern.matcher(context);
    44             if (matcher.find()) {//设置图片
    45                 message.setPic("http://cs.scu.edu.cn/" + matcher.group(1)
    46                         + ".jpg");
    47             }
    48             //获取内容
    49             pattern = Pattern.compile("<DIV id=BodyLabel>.+?</DIV>");
    50             matcher = pattern.matcher(context);
    51             if (matcher.find()) {//设置内容
    52                 String result = matcher.group(0);
    53                 //过滤一些内容中的标签
    54                 result = result.replaceAll("&nbsp;", " ");
    55                 result = result.replaceAll("<br>", "
    ");
    56                 result = result.replaceAll("<.*?>", "");
    57                 message.setContext(result);
    58             }
    59             //将查询到的新闻添加到list中
    60             list.add(message);
    61         }
    62         return list;
    63     }

        

        (5)测试代码:

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

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

      

     

        

     

     

          

  • 相关阅读:
    Tabular DataStream protocol 协议
    Redis 分片实现 Redis Shard [www]
    进程线程协程那些事儿
    Linux下用freetds执行SQL Server的sql语句和存储过程
    unixODBC
    在linux下有没有什么软件可以连接windows上的MSSQL SERVER
    Nginx使用ssl模块配置HTTPS支持
    谈一款MOBA类游戏《码神联盟》的服务端架构设计与实现
    core dump使用方法、设置、测试用例
    linux下生成core dump文件方法及设置
  • 原文地址:https://www.cnblogs.com/huangyichun/p/5686500.html
Copyright © 2020-2023  润新知