#JAVA-常用API-爬虫

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字符串案例,这里不再赘述


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【小白学机器学习39】如何用numpy生成总体,生成样本samples

目录 1 目的&#xff1a;研究 样本和总体之间的关系 2 先生成1个理论总体 2.0 下面是关于这一步的完整代码 2.1 一般情况下&#xff0c;我们先生成一个符合正态分布的总体 2.1.1 设置总体 &#xff0c;或者说生成一个总体 2.2 为什么一定要是一个符合正态分布的总体&…

什么是sfp,onu,​为什么PON(​俗称“光猫”​)模块使用SC光纤接口

在现代网络设备中&#xff0c;我们经常会看到SFP或SFP接口的身影&#xff0c;这些接口有时被简称为光口&#xff0c;但这个称呼并不严谨。有些厂商则称之为多功能口或多用途口&#xff0c;然而这对于不了解的人来说可能还是一头雾水。SFP&#xff0c;即Small Form-Factor Plugg…

Java个人博客系统项目文档

项目名称 Java个人博客系统 项目概述 该博客系统是一个多功能的Java应用程序。该系统支持用户发布新文章、浏览他人文章、管理个人文章收藏和删除不再需要的文章。通过该博客系统&#xff0c;用户可以享受一个安全、便捷的在线写作和阅读体验。 运行环境 编程语言&#xff1…

飞凌嵌入式受邀亮相OpenHarmony人才生态大会2024

2024年11月27日&#xff0c;OpenHarmony人才生态大会2024在武汉洲际酒店举行。在这场汇聚了行业精英、技术大咖及生态伙伴的年度盛会上&#xff0c;飞凌嵌入式作为OpenHarmony社区的重要成员受邀出席&#xff0c;并展示了其在OpenHarmony 4.1系统适配方面的最新成果。 在大会的…

SpringMVC:入门案例

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

【Java基础】笔记

List和ArrayList区别 public class Arrays_BugDemo {public static void main(String[] args){/** List 是一个固定大小的列表&#xff0c;虽然可以进行查询操作&#xff0c;但不支持添加、删除或修改元素。* 如果需要一个可以动态修改的列表&#xff0c;可以使用 ArrayList 进…

思维导图+实现一个登录窗口界面

QQ2024122-205851 import sys from PyQt6.QtGui import QIcon, QPixmap, QMovie from PyQt6.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QLabel, QVBoxLayout# 封装我的窗口类 class LoginWidget(QWidget):# 构造函数def __init__(self):# 初始化父类su…

InterHub:为自动驾驶提供密集互动事件的自然驾驶轨迹数据集

InterHub 是一个为自动驾驶领域设计的自然驾驶轨迹数据集&#xff0c;它通过深入挖掘自然驾驶记录中的密集互动事件而构建。 InterHub 的特点在于其形式化的方法&#xff0c;这使得数据集能够精确描述和提取多智能体之间的互动事件&#xff0c;揭示了现有自动驾驶解决方案的局限…

VSCode修改资源管理器文件目录树缩进(VSCode目录结构、目录缩进、文件目录外观)workbench.tree.indent

文章目录 方法点击左下角小齿轮点击设置点击工作台&#xff0c;点击外观&#xff0c;找到Tree: Indent设置目录树的缩进 方法 点击左下角小齿轮 点击设置 点击工作台&#xff0c;点击外观&#xff0c;找到Tree: Indent设置目录树的缩进 "workbench.tree.indent"默认…

idea 自动导包,并且禁止自动导 *(java.io.*)

自动导包配置 进入 idea 设置&#xff0c;可以按下图所示寻找位置&#xff0c;也可以直接输入 auto import 快速定位到配置。 Add unambiguous imports on the fly&#xff1a;自动帮我们优化导入的包Optimize imports on the fly&#xff1a;自动去掉一些没有用到的包 禁止导…

阅读笔记--知识蒸馏

1.一些基本概念 教师模型&#xff08;Teacher Model&#xff09;&#xff1a;预训练复杂神经网络&#xff0c;高精度&#xff0c;计算存储开销大。学生模型&#xff08;Student Model&#xff09;&#xff1a;简单参数少推理快的模型&#xff0c;目标从教师模型获取知识&#…

永磁同步电机谐波抑制算法(11)——基于矢量比例积分调节器(vector PI controller,VPI controller)的谐波抑制策略

1.前言 相比于传统的谐振调节器&#xff0c;矢量比例积分调节器&#xff08;vector PI controller&#xff0c;VPI controller&#xff09;多一个可调零点&#xff0c;能够实现电机模型的零极点对消。因此VPI调节器也被广泛应用于交流控制/谐波抑制中。 2.参考文献 [1] A. G…

你还没有将 Siri 接入GPT对话功能吗?

由于各种原因&#xff0c;国内ios用户目前无缘自带 AI 功能&#xff0c;但是这并不代表国内 ios 无法接入 AI 功能&#xff0c;接下来手把手带你为iPhone siri 接入 gpt 对话功能。 siri 接入 chatGPT 暂时还无法下载 ChatGPT app&#xff0c;或者没有账号的读者可以直接跳到…

【Point-LIO】基于Ubuntu20.04的ROS1平台的Point-LIO部署Mid-360激光雷达

0、前言 1、代码拉取 2、代码编译运行 文件结构 编译流程&#xff1a; 1、先编译livox_ros_driver2 2、编译整个工程文件 3、运行launch文件&#xff08;livox_ros_driver2&#xff09; 成功启动&#xff1a; 3、实物运行 看得出来&#xff0c;在rviz出了问题&am…

使用 Monaco Editor 实现 ECharts 变量使用功能

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

实验七 用 MATLAB 设计 FIR 数字滤波器

实验目的 加深对窗函数法设计 FIR 数字滤波器的基本原理的理解。 学习用 Matlab 语言的窗函数法编写设计 FIR 数字滤波器的程序。 了解 Matlab 语言有关窗函数法设计 FIR 数字滤波器的常用函数用法。 掌握 FIR 滤波器的快速卷积实现原理。 不同滤波器的设计方法具有不同的优…

泷羽sec-burp功能介绍(1) 学习笔记

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

Unity 模拟百度地图,使用鼠标控制图片在固定区域内放大、缩小、鼠标左键拖拽移动图片

效果展示&#xff1a; 步骤流程&#xff1a; 1.使用的是UGUI&#xff0c;将下面的脚本拖拽到图片上即可。 using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems;public class CheckImage : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragH…

Wend看源码-Durid

项目地址 GitHub - alibaba/druid: 阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品&#xff0c;为监控而生的数据库连接池 简介 Druid连接池是阿里巴巴开源的数据库连接池项目&#xff0c;自2011年开源以来&#xff0c;它因其卓越的…

基于单片机的WIFI、语音、储存、时钟、闹钟、定位系统

所有仿真详情导航&#xff1a; PROTEUS专栏说明-CSDN博客 目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DS1302时钟模块&#xff0c;通过LCD1602显示实时时间&#xff0c;也可以储存时间在AT2DC02中&#xff0c…