19-JavaSE基础巩固练习:爬虫

爬虫

一、正则表达式的作用

1、作用一
  • 校验字符串是否满足规则

2、作用二
  • 在一段文本中查找满足要求的内容


二、练习:本地爬虫和网络爬虫

1、本地爬虫
  • 有如下文本,请按照要求爬取数据。
    • Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
  • 要求:找出里面所有的JavaXX
package com.app.demo27_regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test3 {
    public static void main(String[] args) {
        /*
            正则表达式的作用:爬虫
            本地爬虫:
                有如下文本,请按照要求爬取数据:
                    Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,
                    因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
                要求:找出里面所有的JavaXX
         */
        String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
                "因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";

        method1(str);

        System.out.println("------------------------------");

        // 1.获取正则表达式的对象
        Pattern p = Pattern.compile("Java\\d{0,2}");
        // 2.获取文本匹配器的对象
        Matcher m = p.matcher(str);
        // 3.利用循环寻找符合规则的子串
        while (m.find()) {
            // 4.输出符合规则的子串
            System.out.println(m.group());
        }
    }

    private static void method1(String str) {
    /*
        Pattern: 表示正则表达式
        Matcher: 文本匹配器,作用是按照正则表达式的规则去读取字符串,从头开始读取。
                 在大串中去找符合匹配规则的子串。
     */
        // 1.获取正则表达式的对象
        Pattern p = Pattern.compile("Java\\d{0,2}");
        /*
            2.获取文本匹配器的对象
              m: 文本匹配器的对象
              str: 大串
              p: 规则
              意思: m要在str中找符合p规则的小串
         */
        Matcher m = p.matcher(str);

        /*
            拿着文本匹配其从头开始读取,寻找是否有满足规则的子串
            如果没有,find()方法返回false
            如果有,返回true。在底层会记录子串的起始索引和结束索引+1:
                假如字符串:Java自从95年
                匹配到Java,则记录Java子串的起始索引为0,结束索引为3+1=4
                (0,4)
         */
        boolean b = m.find();

        /*
            group()方法底层会根据find()方法记录的索引进行字符串的截取:
                subString(起始索引, 结束索引);  包头不包尾
                (0, 4) 截取时,不包含4索引的数据
            group()方法最终会把截取的小串返回
         */
        String s1 = m.group();
        System.out.println(s1);

        /*
            第二次调用find()方法的时候,会继续读取后面的内容
            读取到第二个满足规则的子串,find()方法会继续返回true
            并把第二个子串的起始索引和结束索引+1,进行记录
         */
        b = m.find();

        // 第二次调用group()方法的时候,会根据find()方法记录的索引再次截取子串
        String s2 = m.group();
        System.out.println(s2);
    }
}
Java
Java8
------------------------------
Java
Java8
Java11
Java17
Java17

Process finished with exit code 0



2、网络爬虫
  • 把链接:http://ent.cctv.com/lm/494/-1/54463.html中所有的身份证号码都爬取出来。
package com.app.demo27_regex;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test4 {
    public static void main(String[] args) throws Exception {
        /*
            扩展练习:正则表达式的作用-网络爬虫
                把链接:http://ent.cctv.com/lm/494/-1/54463.html
                中所有的身份证号码都爬取出来。
         */

        // 1.创建一个URL对象
        URL url = new URL("http://ent.cctv.com/lm/494/-1/54463.html");
        // 2.连接上这个网址
        URLConnection conn = url.openConnection();
        // 3.创建一个字符缓冲输入流对象去读取网络中的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        // 4.定义一个空字符串用于接收按照行读取到的数据
        String line;
        // 5.获取正则表达式的对象 pattern
        String regex = "[1-9]\\d{17}";
        Pattern pattern = Pattern.compile(regex);
        // 6.在读取的时候每次读取一整行
        while ((line = br.readLine()) != null) {
            // 7.拿着文本匹配器的对象matcher按照pattern的规则去读取当前的这一行信息
            Matcher matcher = pattern.matcher(line);
            while (matcher.find()) {
                // 8.输出读取到的当前行信息
                System.out.println(matcher.group());
            }
        }
        // 8.关闭流,释放资源
        br.close();
    }
}
410802197407191510
432623197801303011
410329197212250114
420105197812270020
110105197105175312
421022198301257824
370602198301275418
110102955100408672
370602198108300239
142601197107251920
110228197504206729

Process finished with exit code 0



3、练习
  • 需求:把下面文本中的座机电话、邮箱、手机号码、热线都爬取出来。

    来黑马程序员学习Java,
    手机号:18512516758,18512508907
    或者联系邮箱:boniu@itcast.cn,
    座机电话:01036517898,010-98951256
    邮箱:bozai@itcast.cn,
    热线电话:400-618-9090,400-618-4000,4006184000,4006189090
    
  • 分析

    • 手机号的正则表达式:

      1[3-9]\d{9}
      
    • 邮箱的正则表达式:

      \w+@[\w&&[^_]]{2,6}(\.[a-zA-Z]{2,3}){1,2}
      
    • 座机电话的正则表达式:

      0\d{2,3}-?[1-9]\d{4,9}
      
    • 热线电话的正则表达式:

      400-?[1-9]\d{2}-?[1-9]\d{3}
      
package com.app.demo27_regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test5 {
    public static void main(String[] args) {
        /*
            正则表达式练习:
                需求:把下面文本中的座机电话、邮箱、手机号码、热线都爬取出来。
                  来黑马程序员学习Java,
                  手机号:18512516758,18512508907
                  或者联系邮箱:boniu@itcast.cn,
                  座机电话:01036517898,010-98951256
                  邮箱:bozai@itcast.cn,
                  热线电话:400-618-9090,400-618-4000,4006184000,4006189090
               分析:
                 手机号的正则表达式:1[3-9]\d{9}
                 邮箱的正则表达式:\w+@[\w&&[^_]]{2,6}(\.[a-zA-Z]{2,3}){1,2}
                 座机电话的正则表达式:0\d{2,3}-?[1-9]\d{4,9}
                 热线电话的正则表达式:400-?[1-9]\d{2}-?[1-9]\d{3}
         */
        String str = "来黑马程序员学习Java,\n" +
                "手机号:18512516758,18512508907\n" +
                "或者联系邮箱:boniu@itcast.cn,\n" +
                "座机电话:01036517898,010-98951256\n" +
                "邮箱:bozai@itcast.cn,\n" +
                "热线电话:400-618-9090,400-618-4000,4006184000,4006189090";

        // 1.获取正则表达式的对象
        String regex = "(1[3-9]\\d{9})|(\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2})" +
                "|(0\\d{2,3}-?[1-9]\\d{4,9})|(400-?[1-9]\\d{2}-?[1-9]\\d{3})";
        Pattern p = Pattern.compile(regex);
        // 2.获取文本匹配器的对象
        // 利用m去读取str,会按照p的规则找里面的小串
        Matcher m = p.matcher(str);
        // 3.利用循环获取每一个数据
        while (m.find()) {
            // 4.输出符合规则的数据
            System.out.println(m.group());
        }
    }
}
18512516758
18512508907
boniu@itcast.cn
01036517898
010-98951256
bozai@itcast.cn
400-618-9090
400-618-4000
4006184000
4006189090

Process finished with exit code 0



三、带条件爬取

  • 有如下文本,请按照要求爬取数据。
    • java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和JAva11,因为这两个是长期支持版本,下一个长期支持版本是JAVa17,相信在未来不久JAVA17也会逐渐登上历史舞台。
  • 需求1:爬取版本号为8,11,17的Java文本,但是只要Java,忽略大小写,不显示版本号
  • 需求2:爬取版本号为8,11,17的Java文本,忽略大小写,显示版本号
  • 需求3:爬取除了版本号为8,11,17的Java文本
package com.app.demo27_regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test6 {
    public static void main(String[] args) {
        /*
            正则表达式的作用-爬虫:
                带条件的爬取数据:
                    - 有如下文本,请按照要求爬取数据。
                      - java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和JAva11,因为这两个是长期支持版本,
                        下一个长期支持版本是JAVa17,相信在未来不久JAVA17也会逐渐登上历史舞台。
                    - 需求1:爬取版本号为8,11,17的Java文本,但是只要Java,忽略大小写,不显示版本号
                    - 需求2:爬取版本号为8,11,17的Java文本,忽略大小写,显示版本号
                    - 需求3:爬取除了版本号为8,11,17的Java文本
         */
        String str = "java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和JAva11,因为这两个是长期支持版本," +
                     "下一个长期支持版本是JAVa17,相信在未来不久JAVA17也会逐渐登上历史舞台。";
        // 1.需求一:定义正则表达式
        /*
            ?: 理解为前面的数据Java
            =: 表示在Java后面要跟随的数据
            但是在获取的时候,只获取前半部分
         */
        String regex1 = "((?i)Java)(?=8|11|17)";
        // 2.需求二:定义正则表达式
        String regex2 = "((?i)Java)(8|11|17)";
        String regex3 = "((?i)Java)(?:8|11|17)";
        // 3.需求三:定义正则表达式
        String regex4 = "((?i)Java)(?!8|11|17)";

        reptile(str, regex1);
        System.out.println();
        reptile(str, regex2);
        reptile(str, regex3);
        System.out.println();
        reptile(str, regex4);
    }

    /**
     * 爬虫
     * @param str       数据
     * @param regex1    正则表达式
     */
    private static void reptile(String str, String regex1) {
        // 获取正则表达式的对象
        Pattern p = Pattern.compile(regex1);
        // 获取文本匹配器的对象,利用m去读取str,会按照p的规则找里面的小串
        Matcher m = p.matcher(str);
        // 利用循环获取每一个数据
        while (m.find()) {
            // 输出获取到的每一个数据
            System.out.println(m.group());
        }
    }
}
Java
JAva
JAVa
JAVA

Java8
JAva11
JAVa17
JAVA17
Java8
JAva11
JAVa17
JAVA17

java

Process finished with exit code 0



四、贪婪爬取和非贪婪爬取

  • 有如下文本,请按照要求爬取数据。

    • java自从95年问世以来,abbbbbbbbbbaaaaaaaaaaaaaaaaaaa

      经历了很多版本,目前企业中用的最多的是Java8和JAva11,因为这两个是长期支持版本,下一个长期支持版本是JAVa17,相信在未来不久JAVA17也会逐渐登上历史舞台。

  • 需求1:按照ab+的方式爬取ab,b尽可能多获取

  • 需求2:按照ab+的方式爬取ab,b尽可能少获取

package com.app.demo27_regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test7 {
    public static void main(String[] args) {
        /*
            贪婪爬取和非贪婪爬取:
                只写+或*表示贪婪匹配
                +?或*?表示非贪婪匹配
            贪婪爬取:在爬取数据的时候尽可能的多获取数据
            非贪婪爬取:在爬取数据的时候尽可能的少获取数据

            ab+:
                贪婪爬取:abbbbbbbbbb
                非贪婪爬取:ab
            Java当中,默认的就是贪婪爬取
            如果我们在数量词+或*的后面加上问号,那么此时就是非贪婪爬取

            - java自从95年问世以来,abbbbbbbbbbaaaaaaaaaaaaaaaaaaa
              经历了很多版本,目前企业中用的最多的是Java8和JAva11,因为这两个是长期支持版本,下一个长期支持版本是JAVa17,
              相信在未来不久JAVA17也会逐渐登上历史舞台。
            - 需求1:按照ab+的方式爬取ab,b尽可能多获取
            - 需求2:按照ab+的方式爬取ab,b尽可能少获取
         */
        String str = "java自从95年问世以来,abbbbbbbbbbaaaaaaaaaaaaaaaaaaa" +
                     "经历了很多版本,目前企业中用的最多的是Java8和JAva11,因为这两个是长期支持版本,下一个长期支持版本是JAVa17," +
                     "相信在未来不久JAVA17也会逐渐登上历史舞台。";
        // 需求1:
        String regex1 = "ab+";
        // 需求2:
        String regex2 = "ab+?";

        reptile(str, regex1);
        reptile(str, regex2);
    }

    /**
     * 爬虫
     * @param str       数据
     * @param regex    正则表达式
     */
    private static void reptile(String str, String regex) {
        // 获取正则表达式的对象
        Pattern p = Pattern.compile(regex);
        // 获取文本匹配器的对象,利用m去读取str,会按照p的规则找出小串
        Matcher m = p.matcher(str);
        // 利用循环获取每个数据
        while (m.find()) {
            System.out.println(m.group());
        }
    }
}
abbbbbbbbbb
ab

Process finished with exit code 0



五、正则表达式在字符串方法中的使用

方法名说明
public String[] matches(String regex)判断字符串是否满足正则表达式的规则
public String replaceAll(String regex,String newStr)按照正则表达式的规则进行替换
public String[] split(String regex)按照正则表达式的规则切割字符串
  • 有一段字符串:

    小诗诗fefefefdsdsfdge1232小蛋蛋sgwgkdkdj123123小灰灰
    
  • 需求1:把字符串中三个姓名之间的字符替换为vs

  • 需求2:把字符串中三个姓名切割出来

package com.app.demo27_regex;

public class Test8 {
    public static void main(String[] args) {
        /*
            正则表达式在字符串方法中的使用:
               - 有一段字符串:
                   小诗诗fefefefdsdsfdge1232小蛋蛋sgwgkdkdj123123小灰灰
               - 需求1:把字符串中三个姓名之间的字符替换为vs
               - 需求2:把字符串中三个姓名切割出来
         */
        String str = "小诗诗fefefefdsdsfdge1232小蛋蛋sgwgkdkdj123123小灰灰";
        // 需求1:
        /*
            细节:replaceAll方法在底层跟之前一样会创建文本解析器的对象
                 然后从头开始去读取字符串的内容,只要有满足的,那么就用第二个参数去替换。
         */
        String regex1 = "[\\w&&[^_]]+";
        String result1 = str.replaceAll(regex1, "vs");
        System.out.println(result1);
        
        // 需求2:
        String[] arr = str.split(regex1);
        for (String s : arr) {
            System.out.println(s);
        }
    }
}
小诗诗vs小蛋蛋vs小灰灰
小诗诗
小蛋蛋
小灰灰

Process finished with exit code 0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值