Java基础:爬虫

1.本地爬虫

Pattern:表示正则表达式

Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。在大串中去找符合匹配规则的子串。

1.2.获取Pattern对象

通过Pattern p = Pattern.compile("正则表达式");获得        

1.3.获取Matcher对象


通过Matcher m = p.matcher(str);获得  (m要在str中找符合p规则的小串)

其中, m为Matcher对象, p为正则表达式规则, str为要验证的字符串.

1.4.匹配文本中的对象


boolean b = m.find(); 表示拿着文本匹配器从头开始读取,寻找是否有满足规则的子串如果没有,方法返回false. 如果有,返回true。在底层记录子串的起始索引和结束索引+1.

1.5.截取文本匹配器的索引


String s = m.group(); 这时文本匹配器会停留在第一个匹配文本的结束索引+1处, 返回一个文本中索引为(0,4)不包含4索引的字符串(符合规则的). 

1.6.继续匹配和获取索引


重复第4步和第五步, 从上一次停留的地方开始向后查找.

第4步和第5步一般通过while(m.find()){}循环实现.

package com.itheima.a08regexdemo;import java.util.regex.Matcher;
import java.util.regex.Pattern;public class RegexDemo6 {public static void main(String[] args) {/* 有如下文本,请按照要求爬取数据。Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台要求:找出里面所有的JavaXX*/String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";//1.获取正则表达式的对象Pattern p = Pattern.compile("Java\\d{0,2}");//2.获取文本匹配器的对象//拿着m去读取str,找符合p规则的子串Matcher m = p.matcher(str);//3.利用循环获取while (m.find()) {String s = m.group();System.out.println(s);}}private static void method1(String str) {//Pattern:表示正则表达式//Matcher: 文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。//          在大串中去找符合匹配规则的子串。//获取正则表达式的对象Pattern p = Pattern.compile("Java\\d{0,2}");//获取文本匹配器的对象//m:文本匹配器的对象//str:大串//p:规则//m要在str中找符合p规则的小串Matcher m = p.matcher(str);//拿着文本匹配器从头开始读取,寻找是否有满足规则的子串//如果没有,方法返回false//如果有,返回true。在底层记录子串的起始索引和结束索引+1// 0,4boolean b = m.find();//方法底层会根据find方法记录的索引进行字符串的截取// substring(起始索引,结束索引);包头不包尾// (0,4)但是不包含4索引// 会把截取的小串进行返回。String s1 = m.group();System.out.println(s1);//第二次在调用find的时候,会继续读取后面的内容//读取到第二个满足要求的子串,方法会继续返回true//并把第二个子串的起始索引和结束索引+1,进行记录b = m.find();//第二次调用group方法的时候,会根据find方法记录的索引再次截取子串String s2 = m.group();System.out.println(s2);}
}

爬取数据练习

package pacong;import java.util.regex.Matcher;
import java.util.regex.Pattern;/*需求:把下面文本中的座机电话,邮箱,手机号,热线都爬取出来。来黑马程序员学习Java,手机号:18512516758,18512508907或者联系邮箱:boniu@itcast.cn,座机电话:01036517895,010-98951256邮箱:bozai@itcast.cn,热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090*/
public class pacongdemo2 {public static void main(String[] args) {
//400-?[1-9]\\d{2}-?[1-9]\\d{3}/*分析:手机号: "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 s = "来黑马程序员学习Java," +"电话:18512516758,18512508907" + "或者联系邮箱:boniu@itcast.cn," +"座机电话:01036517895,010-98951256" + "邮箱:bozai@itcast.cn," +"热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090";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})";//1.获取正则表达式的对象Pattern p = Pattern.compile(regex);//2.获取文本匹配器的对象Matcher m = p.matcher(s);//利用m去读取s,会按照p的规则去找大串s里面的小串//3.利用循环获取每一个数据 while(m.find())while (m.find()) {System.out.println(m.group());}}
}

结果

2.有条件的爬取数据


需求1:?相当于前面的java,起到占位符作用,后面的=表示在java后面跟随的数据,但是在获取的时候只获取前面部分.

需求2: 删除?= 表示java是8|11|17 或者是?:  ----:?相当于前面的java,起到占位符作用,:就表示我们要拼8|11|17的数据

需求3:除了8|11|17的文本不要 就输出?!即可

package pacong;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
//Pattern:表示正则表达式
Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。
在大串中去找符合匹配规则的子串。*/
public class pacongdemo4 {public static void main(String[] args) {/*需求1:爬取版本号为8,11.17的Java文本,但是只要Java,不显示版本号。需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8 Java11 Java17 Java17需求3:爬取除了版本号为8,11.17的Java文本,*/String s = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";//1.定义正则表达式//?理解为前面的数据Java//=表示在Java后面要跟随的数据//但是在获取的时候,只获取前半部分//需求1:String regex1 = "((?i)Java)(?=8|11|17)";String regex2 = "((?i)Java)(8|11|17)";String regex3 = "((?i)Java)(?:8|11|17)";Pattern P=Pattern.compile(regex3);Matcher m=P.matcher(s);while (m.find()){System.out.println(m.group());}}
}

3.贪婪爬取和非贪婪爬取

 

贪婪爬取 : 在爬取数据的时候尽可能的多获取数据 (如:abbbbbbbbbbbb)

非贪婪爬取 : 在爬取数据的时候尽可能的少获取数据 (如:ab)

Java当中,默认的就是贪婪爬取

如果我们在数量词+或者*的后面加上问号,那么此时就是非贪婪爬取

贪婪爬取

public class pacongdemo3 {public static void main(String[] args) {String s = "Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaaaaaaaaa" +"经历了很多版木,目前企业中用的最多的是]ava8和]ava11,因为这两个是长期支持版木。" +"下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";String regex="ab+";Pattern P=Pattern.compile(regex);Matcher M=P.matcher(s);while (M.find()) {System.out.println(M.group());}}
}

结果:

非贪婪爬取

public class pacongdemo3 {public static void main(String[] args) {String s = "Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaaaaaaaaa" +"经历了很多版木,目前企业中用的最多的是]ava8和]ava11,因为这两个是长期支持版木。" +"下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";String regex="ab+?";Pattern P=Pattern.compile(regex);Matcher M=P.matcher(s);while (M.find()) {System.out.println(M.group());}}
}

结果:

4.正则表达式在字符串中的使用

 先创建一个正则表达式规则, 然后传入字符串方法中, 返回的就是新的替换后的字符串或切割后的字符串数组了.        

String类的split()方法原型:

public String[] split(String regex)
//参数regex表示正则表达式。可以将当前字符串中匹配regex正则表达式的符号作为"分隔符"来切割字符串。

replaceAll用法

public class pacongdemo5 {public static void main(String[] args) {/*有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠要求1:把字符串中三个姓名之间的字母替换为vs要求2:把字符串中的三个姓名切割出来*/String s = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";//细节://方法在底层跟之前一样也会创建文本解析器的对象//然后从头开始去读取字符串中的内容,只要有满足的,就用第二个参数去替换String regex="[\\w&&[^_]]+";String result = s.replaceAll(regex, "vs");System.out.println(result);}
}

结果:

split用法

package pacong;public class pacongdemo5 {public static void main(String[] args) {/*有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠要求1:把字符串中三个姓名之间的字母替换为vs要求2:把字符串中的三个姓名切割出来*/String s = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";//细节://方法在底层跟之前一样也会创建文本解析器的对象//然后从头开始去读取字符串中的内容,只要有满足的,就用第二个参数去替换String regex="[\\w&&[^_]]+";/*String result = s.replaceAll(regex, "vs");System.out.println(result);*///细节://方法在底层跟之前一样也会创建文本解析器的对象//然后从头开始去读取字符串中的内容,只要有满足的,就用第二个参数去切割String[] str = s.split(regex);for (int i = 0; i < str.length; i++) {System.out.println(str[i]);}}
}

结果:

5.分组

5.1.捕获分组

红色为第一组, 蓝色为第二组, 绿色为第三组

 

 

\\组号表示的就是把该组匹配的内容在匹配一遍, 两部分的内容相同. 

package pacong;public class pacongdemo6 {public static void main(String[] args) {
/*需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
举例: a123a b456b 17891 &abc& a123b(false)
\\组号:表示把第X组的内容再出来用一次
*/String regex1 = "(.).+\\1";//第一个.说的就是开头的字符是任意的,第2个点说的是中间的字符是任意的并且至少出现一次//  \\1表示我要把第一组的数据a再用一次System.out.println("a123a".matches(regex1));System.out.println("b456b".matches(regex1));System.out.println("17891".matches(regex1));System.out.println("&abc&".matches(regex1));System.out.println("a123b".matches(regex1));System.out.println("--------------------------");//需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符//举例: abc123abc b456b 123789123 &!@abc&!@ abc123abd(false)String regex2 = "(.+).+\\1";System.out.println("abc123abc".matches(regex2));System.out.println("b456b".matches(regex2));System.out.println("123789123".matches(regex2));System.out.println("&!@abc&!@".matches(regex2));System.out.println("abc123abd".matches(regex2));System.out.println("---------------------");//需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致//举例: aaa123aaa bbb456bbb 111789111 &&abc&&//(.):把首字母看做一组// \\2:把首字母拿出来再次使用// *:作用于\\2,表示后面重复的内容出现0次或多次String regex3 = "((.)\\2*).+\\1";System.out.println("aaa123aaa".matches(regex3));System.out.println("bbb456bbb".matches(regex3));System.out.println("111789111".matches(regex3));System.out.println("&&abc&&".matches(regex3));System.out.println("aaa12aab".matches(regex3));System.out.println("---------------------");}
}

  String regex3 = "((.)\\2*).+\\1";

分析:

首先开头的是任意字母(.) ,接着是重复上一个的字母 我们写\\1,\\表示把第X组的内容再出来用一次,这里是第一组,然后写一个*,这个*表示重复0次或者多次, 接着出现了.+,这个.+表示中间的字符,.表示任意字符,+表示至少出现一次, 然后最后一段的字符和开头的字符重复,所以我们把第一组括起来,然后根据分组规则,已括号为基准,所以里面的为第二组,所以改为\\2

(.)代表的是a字符 ,接着\\1重复上一个字符a的内容,然后*代表的是a字符至少出现0次,在写中间的字符(123),写一个(.+)就即可,然后写末端的aaa,怎么写呢,其实就是把前面的整体拿着用重复一次罢了,于是我们就要用括号括起来,就要把\\1改成\\2,后面写\\1 

结果:


public class pacongdemo7 {public static void main(String[] args) {
//需求:把重复的内容 替换为 单个的
//学学                学
//编编编编            编
//程程程程程程        程
//  (.)表示把重复内容的第一个字符看做一组
//  \\1表示第一字符再次出现
//  + 至少一次
//  $1 表示把正则表达式中第一组的内容,再拿出来用String str = "我要学学编编编编程程程程程程";String regex="(.)\\1+";System.out.println(str.replaceAll(regex,"$1"));}
}

结果:

5.2非捕获分组

特点:不占用组号

总结

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/369546.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spire.PDF for .NET【文档操作】演示:以特定的缩放比例/百分比打开 PDF 文件

有时&#xff0c;我们可能需要在显示 PDF 文件时更改缩放比例以满足我们的要求。在本文中&#xff0c;我们将演示如何使用 Spire.PDF for .NET 以特定的缩放比例/百分比&#xff08;例如默认值、100% 或任何其他所需的缩放比例&#xff09;打开 PDF 文件。 Spire.PDF for .NET…

一种频偏估计与补偿方法

一种简易的频偏估计补偿方法&#xff0c;使用QAM等信号。估计精度受FFT长度限制&#xff0c;可以作为粗频偏估计。 Nfft 1024; % FFT长度 N 10*Nfft; % 仿真符号数 M 16; % 调制QAM16 freq 1e…

【SpringBoot3学习 | 第2篇】SpringBoot3整合+SpringBoot3项目打包运行

文章目录 一. SpringBoot3 整合 SpringMVC1.1 配置静态资源位置1.2 自定义拦截器&#xff08;SpringMVC配置&#xff09; 二. SpringBoot3 整合 Druid 数据源三. SpringBoot3 整合 Mybatis3.1 Mybatis整合3.2 声明式事务整合配置3.3 AOP整合配置 四. SpringBoot3 项目打包和运行…

三万字带你一遍跑通uer

三万字带你一遍跑通uer 参考文档 今天给大家介绍个非常强大的项目uer&#xff0c;集成了许多可以做自然语言的东西&#xff0c;效果的话也非常好&#xff0c;很适合企业级的应用&#xff01; 1. 先将项目uer从github拉取下来&#xff08;zip或git都ok&#xff09; 2. 用pycha…

Qt项目:基于Qt实现的网络聊天室---注册模块

文章目录 基本页面设计创建登录界面创建注册界面优化样式完善注册类界面 客户端逻辑完善客户端增加post逻辑客户端配置管理 邮箱注册服务认证服务读取配置邮箱验证服务联调设置验证码过期封装redis操作类封装redis连接池注册功能Server端接受注册请求封装mysql连接池封装DAO操作…

【CV炼丹师勇闯力扣训练营 Day24:§7 回溯3】

CV炼丹师勇闯力扣训练营 代码随想录算法训练营第24天 93 复原IP地址 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.…

智慧校园变革之路:资产标签设置功能的关键应用

在智慧校园的资产管理实践中&#xff0c;资产标签设置扮演着桥梁角色&#xff0c;将实体资产与数字化信息紧密相连&#xff0c;极大地提升了管理的效率与精确度。这项功能的核心在于&#xff0c;为校园内的每一项固定资产配备独一无二的标识——可能是传统的条形码、二维码&…

适合金融行业的国产传输软件应该是怎样的?

对于金融行业来说&#xff0c;正常业务开展离不开文件传输场景&#xff0c;一般来说&#xff0c;金融行业常用的文件传输工具有IM通讯、邮件、自建文件传输系统、FTP应用、U盘等&#xff0c;这些传输工具可以基础实现金融机构的文件传输需求&#xff0c;但也存在如下问题&#…

科普文:一文搞懂nginx原理和实战

1. Nginx简介与核心架构 1.1 Nginx简介 Nginx (engine x) 是一个高性能的 HTTP 和反向代理服务器&#xff0c;也是一个 IMAP/POP3/SMTP 邮件代理服务器。 由 Igor Sysoev 于2004年首次发布&#xff0c;其设计目标是解决 C10K 问题&#xff0c;即在一台服务器上同时处理一万个并…

2024年7月6日 十二生肖 今日运势

小运播报&#xff1a;2024年7月6日&#xff0c;星期六&#xff0c;农历六月初一 &#xff08;甲辰年庚午月辛未日&#xff09;&#xff0c;法定节假日。 红榜生肖&#xff1a;猪、马、兔 需要注意&#xff1a;狗、鼠、牛 喜神方位&#xff1a;西南方 财神方位&#xff1a;正…

C# 类型转换之显式和隐式

文章目录 1、显式类型转换2. 隐式类型转换3. 示例4. 类型转换的注意事项5. 类型转换的应用示例总结 在C#编程中&#xff0c;类型转换是一个核心概念&#xff0c;它允许我们在程序中处理不同类型的数据。类型转换可以分为两大类&#xff1a;显式类型转换&#xff08;Explicit Ca…

AR视频技术与EasyDSS流媒体视频管理平台:打造沉浸式视频体验

随着增强现实&#xff08;AR&#xff09;技术的飞速发展&#xff0c;其在各个领域的应用日益广泛。这项技术通过实时计算摄影机影像的位置及角度&#xff0c;将虚拟信息叠加到真实世界中&#xff0c;为用户带来超越现实的感官体验。AR视频技术不仅极大地丰富了我们的视觉体验&a…

c++重定向输出和输出(竞赛讲解)

1.命令行重定向 在命令行中指定输出文件 指令 .\重定向学习.exe > 1.txt 效果 命令行输入和输出 指令 .\重定向学习.exe < 2.txt > 1.txt 效果 代码 #include<bits/stdc++.h> using namespace std; int n; int main(){cin>>n;for(int i=0;i<n;i…

C++ 类和对象 构造函数

一 类的6个默认成员函数&#xff1a; 如果一个类中什么成员都没有&#xff0c;简称为空类。 例&#xff1a; #include <iostream> class Empty {// 空类&#xff0c;什么成员都没有 }; 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&a…

如何使用 SwiftUI 构建 visionOS 应用

文章目录 前言WindowsVolumes沉浸式空间结论 前言 Apple Vision Pro 即将推出&#xff0c;现在是看看 SwiftUI API 的完美时机&#xff0c;这使我们能够将我们的应用程序适应 visionOS 提供的沉浸式世界。苹果表示&#xff0c;构建应用程序的最佳方式是使用 Swift 和 SwiftUI。…

鸿翼ECM统一AI检索应用全景,为企业打造全方位搜索服务

随着企业的发展和信息化进程的加快&#xff0c;海量数据已沉淀至企业各类系统&#xff0c;系统间信息孤立、信息利用率低、数据价值无法发挥成为制约企业发展的重要因素。如何对散落在企业各系统中的数据、内容进行统一管理和高效利用&#xff0c;实现高效精准的信息检索&#…

谷粒商城学习-07-虚拟机网络设置

文章目录 一&#xff0c;找到配置文件Vagrantfile二&#xff0c;查询虚拟机网卡地址1&#xff0c;查看虚拟机网络配置2&#xff0c;查看宿主机网络配置 三&#xff0c;修改配置文件下的IP配置四&#xff0c;重新启动虚拟机即可生效五&#xff0c;Vagrantfile 的作用1&#xff0…

Qt中使用MySQL数据库详解,好用的模块类封装

本文将详细介绍如何在Qt应用程序中集成MySQL数据库&#xff0c;并封装实现好用的mysql数据库操作类。包括环境准备、连接数据库、执行查询及异常处理等关键步骤&#xff0c;同时包含mysql驱动的编译。分享给有需要的小伙伴&#xff0c;喜欢的可以点击收藏。 目录 环境准备 项…

Pinia:Vue 2 和 Vue 3 中更好用的状态管理框架

前言 还在用Vuex? 在Vue应用程序的开发过程中&#xff0c;高效且易于维护的状态管理一直是开发者关注的核心问题之一。随着Vue 3的发布&#xff0c;状态管理领域迎来了一位新星——Pinia&#xff0c;它不仅为Vue 3量身打造&#xff0c;同时也向下兼容Vue 2&#xff0c;以其简…

《C语言》认识数据类型和理解变量

&#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;C语言基础 目录 前言 一、数据类型的介绍 1.1 字符型 1.2 整形 1.3 浮点型 1.4 布尔类型 1.5 各种数据类型的长度 1.5.1 sizeof操作符 1.5.2 数据类型长度…