#JAVA-常用API-爬虫

news2025/10/27 7:01:23

1.爬虫

我们在正则表达式的讲解中可以使用字符串的方法materchs()来匹配,并且返回一个boolean

String name = "lshhhljh";
System.out.println(name.matches("lsh{3}\\s{3}"));
//true

现在我们将利用正则表达式来爬取本地或者网站上的文本内容

a.本地文本

在此之前我们先学习一下两个会用到的类

  • Pattern:表示正则表达式
  • Matcher:表示文本匹配器,按照正则表达式的规则去读取字符串,从头开始读取

Matcher表示在大串中获取符合规则的子串

我们来简单介绍一下这两个类:

  • Pattern:
    • 编译正则表达式:用于将正则表达式字符串编译为一个模式对象,这个编译后的对象可以高效的应用于多次匹配操作
    • 创建Matcher对象
  • Matcher:用于对输入的字符串进行基于正则表达式的匹配操作。它与Pattern类紧密相连

通过例子来介绍这Matcher的方法:

 String s = "文章包括各种文体的著作、作品,如诗歌、戏剧、小说、" +
       "科学论文,记叙文、议论文、说明文、应用文等等。" +
     "“千古文章未尽才”“文章千古事”“文章憎命达”“板凳要坐十年冷、文章不写一字空”" +
    "“积句而成章,积章而成篇”“言出为论,下笔成章”等";
Pattern p = Pattern.compile("文章");
Matcher matcher = p.matcher(s);
boolean b = matcher.find();
String s1 = matcher.group();
System.out.println(s1);

输出的结果是:文章

  1. boolean b = matcher.find()

拿着文本匹配器从头开始读取,寻找是否有满足规则的子串

  • 如果没有,方法返回false
  • 如果有,返回true。在底层记录子串的起始索引和结束索引+1
  1. String s1 = matcher.group()
  • 方法底层会根据find方法记录的索引进行字符的截取
  • 使用的是subString(起始索引,结束索引)包头不包尾。会把截取的小串进行返回。

所以find方法记录的索引才是结束索引+1


但是上述的代码只能返回一个匹配的结果,所以我们需要用到循环

 Pattern p = Pattern.compile("文章");
 Matcher matcher = p.matcher(s);

 while (matcher.find()) {
     String s1 = matcher.group();
     System.out.println(s1);
 }

在代码中需要我们注意的是我们需要反复的调用find方法,所以在while循环中要把find方法放进去。

find方法在多次调用时会依次往字符串的后面查找,所以可以使用循环找到所有的结果

b.网络文本

说明:略
代码示例:

//创建一个URL对象
URL url = new URL( spec: "https://m.sengzan.com/jiaoyu/29104.html?ivk_sa=1025883i");
//连接上这个网址
//细节:保证网络是畅通
URLConnection conn = url. openConnection();
//创建一个对象去读取网络中的数据
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
//获取正则表达式的对象 pattern
String regex = "[1-9]\\d{17}";
Pattern pattern = Pattern.compile(regex);
//在读取的时候每次读一整行
while ((line = br.readLine()) != null) {
	//拿着文本匹配器的对象matcher按照pattern的规则去读取当前的这一行信息
	Matcher matcher = pattern.matcher(line);
	while(matcher.find()){
	System.out.println(matcher.group());
}
br.close();

2.带条件爬取

有的时候我们要对爬取的内容作限制和修改,就用到了待条件爬取的规则

我们先看一个例子:来自黑马程序员

有如下文本,请按照要求爬取数据。
Java自从95年问世以来,经历了很多版本,目前企业中用的最多
的是Java8和Java11,因为这两个是长期支持版本,
下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台

需求1:爬取版本号为8,11,17的Java文本,但是只要Java,不显示版本号。
需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8Java11 Java17Java17
需求3:爬取除了版本号为8,11,17的Java文本,

代码示例:

String s="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,"+
"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//1.定义正则表达式
String regex = "Java( ?= 8|11|17)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while(m.find()){
	System.out.println(m.group());
}

输出的结果是4个Java
String regex = "Java( ?= 8|11|17)"中括号中的部分只是当作了限制条件,但是不会被输出。

  • ? 在这里被当作占位符,可以理解为前面的Java
  • =表示在占位符后面要跟的数据,在这里是指要获取的子串的Java后面要跟的数据
  • |表示“或者”的意思

因为第一个Java后面没有跟版本数字所以没有被打印

补充:((?i)Java)( ?= 8|11|17) ---- 第一个(?i)表示Java在匹配的时候忽略大小写,第二个? 表示前面的((?i)Java)


需求二:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8Java11 Java17Java17

  1. 第一种方法,不使用? 作为占位符
String regex = "Java(8|11|17)";
  1. 第二种方法:使用?
String regex = "Java(?:8|11|17)";

这两种方式都是可以满足上面的要求的


需求三:爬取除了版本号为8,11,17的Java文本

String regex = "Java(?!8|11|17)";

只需要修改正则表达式即可
在这里:表示去除的意思


4. 贪婪爬取和非贪婪爬取

我们前面介绍过正则表达式的数量词,其中有这两个:

  • * :表示 * 前面这个字符匹配零次或多次
  • + :表示 + 前面这个字符匹配一次或多次

那到底是匹配一次还是多次呢?
在Java编译器种默认的匹配机制是贪婪爬取:就是尽可能多的进行匹配

例如:

abbbbbbbbbbbaaaaa

这段字符,如果正则表达式为:ab+

  • 贪婪爬取:abbbbbbbbbbb
  • 非贪婪爬取:ab

默认的爬取方式为贪婪爬取,我们怎么样使用非贪婪爬取呢?

  • ab+?
  • ab*?

在正则表达式的后面加上一个?即可


5.正则表达式在字符串方法中的使用

返回值是字符串类型的方法中正则表达式的使用

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

代码示例:

有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠

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

//要求二
String[] arr = s.split( regex: "[\\w&&[^_]]+");
for (int i = 0; i < arr.length; i++) {
	System.out.println(arr[i]);
}

第二个切割的方法就是按照正则表达式去切割,把正则表达式匹配到的字符串当作断点切割


6.捕获分组和非捕获分组

题目的分组是针对正则表达式来说的
分组:就是正则表达式中的小括号:()

我们给出代码示例:

//简易身份证号码
String regex1 = "\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2})";
//邮箱号
String regex2 = "[1-9]\d{16}(\\d|x|x)";
//24小时时间的两种方式
String regex3 = "([01]\\d|2[0-3]): [0-5]\\d: [0-5]\d"
String regex4 = "([01]\d|2[0-3])(:[0-5]\\d){2}"

用括号表示分组,再使用分组进行复用


同时我们需要知道,分组其实是有序号的:

(\\d(\\d))(\\d)
1    2      3

分组的序号是看左括号进行排序的

a.捕获分组

就是把这一组的数据捕获出来再使用一次
代码示例:

//需求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));

代码示例二:

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

String result = str.replaceAll( regex:"(.)\\1+", replacement: "$1")这行代码在进行替换的时候仍然使用了第一组的内容。所以使用了$组号

因为是在正则表达式的外部使用组号,所以需要使用这个符号:$


b.非捕获分组

非捕获分组:
分组之后不需要再用本组数据,仅仅是把数据括起来。

符号含义举例
( ?: 正则)获取所有Java( ?: 8|11|17)
( ?= 正则)获取前面部分Java( ?= 8|11|17)
( ?! 正则)获取不是指定内容的前面部分Java( ?! 8 | 11|17)
非捕获分组不占用组号,仅仅是把数据括起来,并且括号内的数据是否进行获取还要看非捕获分组的分类

代码示例:前面的Java字符串案例,这里不再赘述


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何部署vue项目到Github Pages

1.创建vue项目 npm create vitelatest my-vue-app -- --template vue 2.创建github仓库 3.连接仓库 在项目根目录右键选择open git base here&#xff0c;如果没有安装git请先安装git。 初始化仓库 $ git init $ git add . $ git commit -m "init"将项目与仓库连…

Jenkins升级到最新版本后无法启动

1. 场景还原 最近在web界面将jenkins升级到最新版本后&#xff0c;后台无法启动jenkins服务&#xff0c;服务状态如下&#xff1a; 运行jenkins命令提示invalid Java version jenkins --version jenkins: invalid Java version: java version "1.8.0_202" Java(TM)…

「计算机网络性能指标」

速率 速率&#xff08;Speed&#xff09;&#xff1a;指连接到网络上的节点在信道上的传输数据的速率。也称数据率或比特率&#xff0c;数据传输速率 信道&#xff08;Channel&#xff09;&#xff1a;表示向某一方向传送信息的通道&#xff08;信道 ≠ 通信线路&#xff09;…

HTTP协议详解:从HTTP/1.0到HTTP/3的演变与优化

深入浅出&#xff1a;从头到尾全面解析HTTP协议 一、HTTP协议概述 1.1 HTTP协议简介 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是互联网上应用最广泛的通信协议之一。它用于客户端与服务器之间的数据传输&#xff0c;尤其是在Web…

【Docker】Docker 容器日志过大导致磁盘爆满

docker容器的日志文件目录位于/var/lib/docker/containers/容器/容器-json.log 查看日志大小 cd /var/lib/docker/containers/ du -h --max-depth1 临时删一点 cd xxxxxxx/ tail -100 xxxxxxx-json.log > xxxxxxx-json.log 如图 解决方式&#xff08;全局&#xff09; …

MySQL 索引创建 大数据查询 性能测试 SQL优化 慢查询

介绍 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些 数据结构以某种方式引用(指向)数据&#xff0c; 这样就可以在这些数据结构上实现高级查找算法&#xff0c;这种数据结构就是…

JAVA:Springboot 集成 WebSocket 和 STOMP 实时消息的技术指南

1、简述 随着互联网应用的复杂性和实时性需求的增加&#xff0c;传统的 HTTP 请求响应模式已不能满足某些场景的需求。WebSocket 和 STOMP 协议为构建实时消息传输提供了极大的便利。本文将介绍如何在 Spring Boot 中使用 WebSocket 和 STOMP 创建一个实时消息应用&#xff0c…

华为仓颉编程环境搭建

1、仓颉介绍 摘自华为官方&#xff1a;仓颉编程语言作为一款面向全场景应用开发的现代编程语言&#xff0c;通过现代语言特性的集成、全方位的编译优化和运行时实现、以及开箱即用的 IDE 工具链支持&#xff0c;为开发者打造友好开发体验和卓越程序性能。 其具体特性表现为&am…

Vue+Elementui el-tree树只能选择子节点并且支持检索

效果&#xff1a; 只能选择子节点 添加配置添加检索代码 源码&#xff1a; <template><div><el-button size"small" type"primary" clearable :disabled"disabled" click"showSign">危险点评估</el-button>…

【前端】安装hadoop后,前端启动报错,yarn命令

新安装hadoop后&#xff0c;前端启动项目用yarn命令&#xff0c;报错。 报错&#xff1a;系统找不到指定的路径。 No HADOOP_CONF_DIR set. Please specify it either in yarn-env.cmd or in the environment. 解决&#xff1a;删掉hadoop目录下yarn的文件 检查&#xff1a;…

【数据事务】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

【381】基于springboot的银行客户管理系统

摘 要 伴随着信息技术与互联网技术的不断发展&#xff0c;人们进到了一个新的信息化时代&#xff0c;传统管理技术性没法高效率、容易地管理信息内容。为了实现时代的发展必须&#xff0c;提升管理高效率&#xff0c;各种各样管理管理体系应时而生&#xff0c;各个领域陆续进到…

VUE前端实现天爱滑块验证码--详细教程

第一步&#xff1a; Git地址&#xff1a;tianai-captcha-demo: 滑块验证码demo 找到目录 src/main/resources/static,拷贝 static 并改名为 tac 即可。 第二步&#xff1a; 将改为 tac 的文件&#xff0c;放进项目根目录中&#xff0c;如下图&#xff1a; 第三步&#xff1…

Profinet转EtherNet/IP网关是如何解决西门子S7-1500PLC与AB PLC的通讯问题的

一、 案例背景 在一个工业现场&#xff0c;一端是AB的PLC&#xff0c;IP地址192.168.1.20;另一端西门子是S7-1500系列&#xff0c;IP地址192.168.2.248。AB的PLC内有 B3、N7、F8 三个寄存器文件涉及到通讯&#xff0c;分别对应西门子PLC的M、DB1、DB2三个存储区域。通过捷米特…

SpringCloud Seata集成分布式事务管理 事务保护 XA AT两种模式的区别

介绍 阿里巴巴的 Seata&#xff08;Service Aligned Transaction Alternative&#xff09;是一个开源的分布式事务解决方案&#xff0c;旨在解决微服务架构中跨服务、跨数据库的事务一致性问题。它可以帮助开发者管理分布式系统中的全局事务&#xff0c;确保在多个服务之间的事…

java全栈day10--后端Web基础(基础知识)之续集

一、Servlet执行流程 二、Http协议&#xff08;相对Tomcat和servlet重要一点&#xff09; 2.1Http-概叙 2.2Http-请求协议 2.2.3请求数据格式 2.2.3请求数据获取 先启动服务器 访问/hello Servlet 访问浏览器端Http协议数据 查看数据 如何获取具体说明&#xff1a; 代码演示 …

【Python】ASCII-generator 将图像、文本或视频转换为 ASCII 艺术 生成字符图(测试代码)

目录 预览效果安装环境报错分析基本例程总结 欢迎关注 『Python』 系列&#xff0c;持续更新中 欢迎关注 『Python』 系列&#xff0c;持续更新中 预览效果 原图 黑白图 彩色图 安装环境 拉取代码 https://github.com/vietnh1009/ASCII-generatorpython3.8 pip install…

2024年大热,Access平替升级方案,也适合Excel用户

欢迎各位看官&#xff0c;您来了&#xff0c;就对了&#xff01; 您多半是Access忠实粉丝&#xff0c;至少是excel用户&#xff0c;亦或是WPS用户吧。那就对了&#xff0c;今天的分享肯定对您有用。 本文1100字&#xff0c;阅读时长2分50秒&#xff01; 现实总是不尽人意&am…

SpringMVC:入门案例

从此开始&#xff0c;我们步入SpringMVC的学习。 SpringMVC是一种基于Java实现MVC模型的轻量级Web框架 先来看一下web程序是如何工作的&#xff1a; 因为是异步调用&#xff0c;所以后端不需要返回view视图&#xff0c;将其去除前端如果通过异步调用的方式进行交互&#xff0…

云计算实验室建设方案

一、云计算实验室建设方案 云计算实验教学整体解决方案&#xff0c;包括&#xff1a;云计算服务器集群、云计算实训平台、实训课程体系、行业实战课程系统、行业数据等&#xff0c;系统性地解决云计算实训教学的痛点问题。 【硬件系统】云计算实训一体机 云计算实训一体机是唯…