Python爬虫(四)正则表达式(Regular Expressions for Python Crawlers)

news2024/11/27 10:29:20

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

推荐:Linux运维老纪的首页,持续学习,不断总结,共同进步,活到老学到老
全面总结 IT核心技术:系统基础、数据库、网路技术、系统安全、自动化运维、容器技术、监控工具、脚本编程、云计算、人工智能、运维开发、算法结构、物联网、JAVA Python语言等。
不同类型针对性训练,提升编程思维,剑指大厂非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。

信息提取--正则表达式或者bs或者lmxl等
保存本地数据
  正则表达式,简称为regex,是文本模式的描述方法,用于描述一组字符串特征的模式,用来匹配特定的字符串。通过特殊字符+普通字符来进行模式描述,从而达到文本匹配目的工具。

‌在Python爬虫中的数据分析应用,通常用于从网页或其他文本数据中提取特定模式的信息。正则表达式是一种强大的文本处理工具,它允许用户通过创建模式来匹配、查找、替换复杂的文本数据。在Python中,re模块提供了全部的正则表达式功能,使得开发者能够利用正则表达式进行字符串的模式匹配、查找和替换操作。

正则表达式的应用场景非常广泛,包括但不限于:

  • ‌数据提取‌:从网页或其他结构化或非结构化的文本数据中提取所需的信息。例如,从一个包含电话号码的文本中提取电话号码。
  • ‌数据验证‌:确保输入的数据符合特定的格式或规则。例如,验证一个字符串是否是一个有效的电子邮件地址。
  • ‌文本处理‌:对文本进行复杂的搜索和替换操作,如删除多余的空格或符号。

在Python爬虫中,正则表达式常用于解析网页源代码,抽取需要的数据。网页源代码本质上是一长串字符,而正则表达式提供了一种使用表达式的方式对字符串进行匹配的语法规则,从而实现对字符串的加工处理和抽取。学会编写正则表达式的逻辑关系是重点,因为它直接关系到能否正确地从网页中提取出需要的数据。

正则表达式的构造方法与创建数学表达式相似,通过多种元字符与运算符将多个小运算组合成一个大运算。例如,.匹配除换行符以外的任意字符,\d匹配数字,^匹配字符串的开始,$匹配字符串的结尾等。这些元字符和运算符的组合使用,使得正则表达式能够灵活地匹配各种复杂的文本模式。

总之,正则表达式在Python爬虫中的数据分析应用是非常重要的,它提供了一种强大的工具来处理和分析文本数据,从而提取出有价值的信息‌12

	我们举一个例子,比如说我们要判断电话号码,我们可以编写出这样的一个函数代码
def isPhoneNumber(text):
    if len(text) != 12:
        return False
    for i in range(0, 3):
        if not text[i].isdecimal():
            return False
    if text[3] != '-':
            return False
    for i in range(4, 7):
        if not text[i].isdecimal():
                return False
    if text[7] != '-':
                return False
    for i in range(8, 12):
        if not text[i].isdecimal():
            return False
    return True
isPhoneNumber('425-434-3434') #刚好匹配正确
isPhoneNumber('4325-434-3434') #匹配不正确
	那么我们继续从一长串字符中查找电话号码
message = 'Call me at 415-555-1011 tomorrow. 415-555-9999 is my office.'
for i in range(len(message)):
    chunk = message[i:i+12]
    if isPhoneNumber(chunk):
        print('Phone number found: ' + chunk)
print('Done')
	通过运行代码,我们可以得到结果:
	Phone number found: 415-555-1011
	Phone number found: 415-555-9999
	Done

  我们通过代码逻辑,可以发现到的是,这样的函数代码去匹配电话号码,其实效率很低,我们需要从一长串字符中,12个字符为一组,然后对字符串进行切片,然后直到12个字符完全符合isPhoneNumber()函数。

	那么如果我们采用正则表达式呢?
import re
phoneNumRegex = re.compile('\d\d\d-\d\d\d-\d\d\d\d')
mo = phoneNumRegex.search('My number is 441-545-4242.') #返回首次出现
mo.group()#通过group返回匹配结果
	运行结果:'441-545-4242'
	※	\d是一个正则表达式中的特殊字符,表示一位数字字符,即任何一位0到9的数字

  那么其实我们很明显的看到的就是 正则表达式在匹配文本时,要比去敲写一段代码,效率更高了。
  我们来根据上述代码来分析一下正则表达式的流程。

二、正则表达式的流程

  1. 首先,Python中所有正则表达式的函数都在re模块

  2. 然后会向re.compile()传入一个字符串值,表示正则表达式,它将返回一个regex模式对象

    那么正则表达式是如何匹配regex对象的呢?
    
    1. regex对象的search()方法查找传入的字符串,寻找该正则表达式的 所有匹配
    2. 如果字符串中没有找到该正则表达式模式,search()方法将None。如果找到了该模式,search()方法将返回一个match对
    3. search对象有一个group()方法,它返回被查找字符串中实际匹配的文本,如果没有实际匹配的文本,就会报错,所以一般来说,代码会这么写。
phoneNumRegex = re.compile('\d\d\d-\d\d\d-\d\d\d\d')#raw
mo = phoneNumRegex.search('My number is 34-555-4242.')#首次出现
if mo:
    print(mo.group())#通过group返回匹配结果

三、正则表达式的使用

  这里将介绍正则表达式中不同的匹配的方式

1.括号的使用

   利用括号进行分组

   比如将区号从电话号码中分离,添加括号将在正则表达式中创建“分组” —— (\d\d\d)-(\d\d\d-\d\d\d\d)
   然后可以使用group()匹配对象方法,从一个分组中获取匹配的文本
   第一对括号是第1组。第二对括号是第2组。向group()传入整数1或2,可以取得匹配文本的不同部分。向group()方法传入0或不传入参数,将返回整个匹配的文本。

import re
phoneNumRegex = re.compile('(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo = phoneNumRegex.search('My number is 341-555-4242.')
mo.group(0)# 返回所有的匹配结果
mo.group(1)# 返回第一个括号的匹配结果
mo.groups()# 返回元组
返回结果:'341-555-4242'
         '341'
         ('341', '555-4242')
2.管道匹配

   利用管道进行分组

   字符|称为“管道”。希望匹配许多表达式中的一个时,就可以使用它 。 例 如 , 正则表达式 ‘Batman|Spiderman’ 将匹配 ‘Batman’ ‘Spiderman’
   如果Batman和Spiderman都出现在被查找的字符串中,第一次出现的匹配文本,将作为match对象返回

mport re
heroRegex = re.compile ('Batman|Spiderman')
mo1 = heroRegex.search('Batman Spiderman Batman')
mo1.group()#第一次出现的匹配文本
	运行结果:'Batman'
batRegex = re.compile('Bat(man|mobile|copter|bat)')
#可以匹配'Batman'、'Batmobile'、'Batcopter'和'Batbat'中任意一个。因为所有这些字符串都以Bat开始
mo = batRegex.search('Batmobile lost a wheel')
mo.group()
	运行结果:'Batmobile'
3.问号匹配

  用问号实现可选匹配

  不论这段文本在不在,正则表达式都会认为匹配。字符?表明它前面的分组在这个模式中是可选

import re
batRegex = re.compile('Bat(wo)?man')
# 既可以匹配Batman ,也可以匹配Batwomen
mo1 = batRegex.search('The Adventures of Batman')
mo1.group()
	运行结果:'Batwoman'
phoneRegex = re.compile('(\d\d\d-)?\d\d\d-\d\d\d\d')
#包含或者不包含区号
mo1 = phoneRegex.search('My number is 415-555-4242')
print(mo1.group())
mo2 = phoneRegex.search('My number is 555-4242')
print(mo2.group())
运行结果:415-555-4242
 		 555-4242
4.星号匹配

  用星号匹配零次或多次

   *(称为星号)意味着“匹配零次或多次”,即星号之前的分组,可以在文本中出现任意次。它可以完全不存在,或一次又一次地重复

import re
batRegex = re.compile('Bat(wo)*man')
mo1 = batRegex.search('The Adventures of Batwowoman')
mo2 = batRegex.search('The Adventures of Batman')
mo1.group()
mo2.group()
	运行结果:'Batwowoman'
	         'Batman'
5.加号匹配

  用加号匹配一次或多次

  +(加号)则意味着“匹配一次或多次”。星号不要求分组出现在匹 配的字符串中,但加号不同,加号前面的分组必须“至少出现一次”

import re
batRegex = re.compile('Bat(wo)+man')
mo1 = batRegex.search('The Adventures of Batwowoman')
mo1.group()
	运行结果:'Batwowoman'
6.花括号匹配

   花括号匹配特定次数

   如果想要一个分组重复特定次数,就在正则表达式中该分组的后面,跟上花括号包围的数字。例如,正则表达式(Ha){3}将匹配字符串’HaHaHa’,但不会匹配’HaHa’
   可以指定一个范围,即在花括号中写下一个最小值、一个逗号和一个最大值 。 例 如 , 正则表达式 (Ha){3,5} 将匹配 ‘HaHaHa’ 、‘HaHaHaHa’和’HaHaHaHaHa’ 即可以匹配Ha3次到5次。

#花括号匹配特定次数
haRegex = re.compile('(ha){3}')
mo1 = haRegex.search('hahahahha')
mo1.group()
 	运行结果:'hahaha'

   正则表达式默认是贪婪的,尽可能匹配最长的字符串
   非贪婪:加问号,尽可能匹配最短的字符

#匹配特定次数,指定范围
haRegex = re.compile('(ha){2,4}')#贪婪匹配。
mo1 = haRegex.search('hahahaha')
mo1.group()
	运行结果:'hahahaha'
#匹配特定次数,
haRegex = re.compile('(ha){2,4}?')#非贪婪匹配
mo1 = haRegex.search('hahahahha')
mo1.group()
	运行结果:'haha'
7.用点-星匹配所有字符

   .:匹配任意字符,除非换行
   *:匹配零个或者多个表达式

#点匹配任意一个字符
haRegex = re.compile('<.>')
mo2 = haRegex.search('fdf<4>kkkfk')
mo2.group()
	运行结果:'<4>'
#点星匹配任意字符
haRegex = re.compile('<.*>')
mo2 = haRegex.search('fdf<4fd809475049758094gg>kkkfk')
mo2.group()
	运行结果:'<4fd809475049758094gg>'
#点星匹配任意字符
haRegex = re.compile('<.*?>')#非贪婪模式,用得最多
mo2 = haRegex.search('fdf<hahaha>haha>kkkfk')
mo2.group()
	运行结果:'<hahaha>'
8.跨行匹配

   re.DOTALL匹配跨行

haRegex = re.compile('<.*>',re.DOTALL)
text='''weret<ttt
fdfd>fdf'''
mo2 = haRegex.search(text)
mo2.group()
	运行结果:'<ttt\nfdfd>'
9.findall方法

   匹配表达式的所有内容(包括首次出现)

#findall
import re
kk = re.compile('\d+')
kk.findall('one1two2three34four4444')
#匹配所有数字,加表示一个或者多个
	运行结果:['1', '2', '34', '4444']

 10. 关于findall方法,还可以写第二种方法

import re
patt='[1-5][0-9]'
lis=[10,20,30,40,2,3,59,60,'aa','3aaa']
match=re.findall(patt,str(lis))
	运行结果:['10', '20', '30', '40','59','60']
11.其他常用字符匹配

在这里插入图片描述

注意:^表示的是匹配字符串的开头;[ ^ 字符串 ]表示匹配方括号内字符串以外的字符串。

12.例子
#例子一
#匹配哪些字符
import re
words=['gold',' Google','Sogu','Guess']
patt=re.compile('.*g[^u]')  
for w in words:
   m=patt.findall(w)
   if m: #条件判断中,只要不为0,不为none,不为空的值均和Ture等价
      print(w)
	运行结果:gold
			 Google
#例子二
#把字符中,10至59取出来 lis=[10,20,30,40,2,3,59,60,'aa','3aaa']
import re
patt='[1-5][0-9]' # 正则表达式
lis=[10,20,30,40,2,3,59,60,'aa','3aaa']
match=re.findall(patt,str(lis)) # 转换成字符串
if match:
  print(match)
	运行结果:['10', '20', '30', '40', '59']
#例子三
#匹配电话号码和邮箱
import re
import pyperclip
#为电话创建一个正则表达式
phoneRegex = re.compile('\d{8,11}')#8位
#为E-mail 地址创建一个正则表达式
emailRegex = re.compile('''(
[a-zA-Z0-9_%+-]+ # username
@  # @symbol
[a-zA-Z0-9-]+ # domain name
\.
[a-zA-Z]{2,4}  #dot-something
)''', re.VERBOSE) 				#管理复杂文本模式,忽略空白符和注释

# Find matches in clipboard text.
text = str(pyperclip.paste())		#从粘贴板过来的字符串
matches = []
for groups in phoneRegex.findall(text):
    matches.append(groups)   
for groups in emailRegex.findall(text):
    matches.append(groups)
# Copy results to the clipboard.
if len(matches) > 0:
    print('Copied to clipboard:')
    print('\n'.join(matches))
else:
    print('No phone numbers or email addresses found.')

注:
  因为Text文本过长,所以我不粘贴到这里,其实text文本不重要,大家自己找一个text文本就可以运行。代码里同学们可能陌生的是pyperclip模块和matchs.append(groups)
  下面这是链接解释
    pyperclip模块
    append的使用

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

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

相关文章

ctf.bugku-各种绕过呦

题目来源&#xff1a;各种绕过哟 - Bugku CTF 访问页面&#xff0c;得到代码如下&#xff1a; <?php highlight_file(flag.php); $_GET[id] urldecode($_GET[id]); $flag flag{xxxxxxxxxxxxxxxxxx}; if (isset($_GET[uname]) and isset($_POST[passwd])) {if ($_GET[una…

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波 前言MPU6050寄存器代码详解mpu6050.cmpu6050.h 使用说明 前言 本篇文章基于卡尔曼滤波的原理详解与公式推导&#xff0c;来详细的解释下如何使用卡尔曼滤波来解算MPU6050的姿态 参考资料&#xff1a;Github_mpu6050 MPU6050寄存器…

利用网络流量分析仪进行网络故障排除:提升IT运维效率的关键工具

目录 一、什么是网络流量分析仪&#xff1f; 主要功能&#xff1a; 二、为什么网络流量分析仪在网络故障排除中如此重要&#xff1f; 三、实际案例&#xff1a;使用网络流量分析仪快速排查网络故障 案例一&#xff1a;流量拥塞导致的带宽不足 案例二&#xff1a;服务器响…

element-ui的树形结构样式调整,添加线条和边框样式

element-ui的树形结构样式调整&#xff0c;添加线条和边框样式 先看图效果&#xff1a; <template><div class"temperature_monitoring"><div class"temperature_monitoring_left"><div class"tree-container"><e…

萤石云 ezuikit-js 视频监控

父组件 <template><div class"securityProtectLargeScreen" v-if"waterWorks?.length > 0"><div class"leftSide"><ul class"leftItems flexColumnCenter"><liv-for"(item, index) in waterWork…

Java | Leetcode Java题解之第470题用Rand7()实现Rand10()

题目&#xff1a; 题解&#xff1a; class Solution extends SolBase {public int rand10() {int a, b, idx;while (true) {a rand7();b rand7();idx b (a - 1) * 7;if (idx < 40) {return 1 (idx - 1) % 10;}a idx - 40;b rand7();// get uniform dist from 1 - 63…

安卓13禁止用户打开开发者选项 android13禁止用户打开开发者选项

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 设置 =》关于平板电脑 =》版本号,一般的话,在这里连续点击就可以打开我们的开发者选项了。但是有些系统要进行保密,因此要禁止用户进入。 2.问题分析 这里我们是通过点…

FastAPI框架使用枚举来型来限定参数、FastApi框架隐藏没多大意义的Schemes模型部分内容以及常见的WSGI服务器Gunicorn、uWSGI了解

一、FastAPI框架使用枚举来型来限定参数 FastAPI框架验证时&#xff0c;有时需要通过枚举的方式来限定参数只能为某几个值中的一个&#xff0c;这时就可以使用FastAPI框架的枚举类型Enum了。publish:December 23, 2020 -Wednesday 代码如下&#xff1a; #引入Enum模块 from fa…

【自注意力与Transformer架构在自然语言处理中的演变与应用】

背景介绍 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;序列到序列&#xff08;seq2seq&#xff09;模型和Transformer架构的出现&#xff0c;极大地推动了机器翻译、文本生成和其他语言任务的进展。传统的seq2seq模型通常依赖于循环神经网络&#xff08;RNN&…

【idea】切换多个仓库到一个分支

需求描述 打开个一个Project 里面包含多个子项目&#xff0c;每一个子项目都有一个自己的git仓库。在idea 中有没有一次性把多个项目切换到同一个分支上面。 解决方案 右键git -> branch 点击右上角的此轮 勾选Execute Branch Operations on All Roots 点击ommon Remote …

萱仔求职复习系列——2 Linux的常用方法(包含基础进阶高级操作)

由于最近接了一个笔试&#xff0c;发现笔试可能涉及到Linux&#xff0c;我准备临时抱佛脚一下赶紧复习一下Linux的用法哈哈。Linux 的基础用法包含文件系统操作、权限管理、网络配置、进程管理等基本命令&#xff1b;进阶操作包括网络调试、包管理、服务管理和用户管理等&#…

【jdk19虚拟线程 VS 普通线程】

文章目录 一.什么是虚拟线程二.虚拟线程与普通线程的区别1.普通线程2.虚拟线程3. 实际应用中的区别 三.上demo对比性能。1.线程池配置2.Service实现3.测试结果 四.小结 一.什么是虚拟线程 虚拟线程&#xff0c;也称作轻量级线程&#xff0c;是由JVM直接管理的线程类型&#xf…

jmeter入门:脚本录制

1.设置代理。 网络连接-》代理-》手动设置代理. ip&#xff1a; 127.0.0.1&#xff0c; port&#xff1a;8888 2. add thread group 3. add HTTP(s) test script recorder, target controller chooses Test plan-> thread Group 4. click start. then open the browser …

Golang | Leetcode Golang题解之第467题环绕字符串中唯一的子字符串

题目&#xff1a; 题解&#xff1a; func findSubstringInWraproundString(p string) (ans int) {dp : [26]int{}k : 0for i, ch : range p {if i > 0 && (byte(ch)-p[i-1]26)%26 1 { // 字符之差为 1 或 -25k} else {k 1}dp[ch-a] max(dp[ch-a], k)}for _, v :…

Java主流框架项目实战——SpringBoot入门

单元1-1 1&#xff09; IDEA工具安装好 2&#xff09; Maven安装&#xff0c;配置好 IDEA安装及永久试用 配置maven 单元1-2 使用aliyun(https://start.aliyun.com/)创建一个spring boot项目&#xff0c;hello world&#xff01; 构建项目 1&#xff09;构建项目 直接默认…

MicroFlow:一种高效的基于Rust的TinyML推理引擎

英文论文标题&#xff1a;MICROFLOW: AN EFFICIENT RUST-BASED INFERENCE ENGINE FOR TINYML 中文论文标题&#xff1a;MicroFlow&#xff1a;一种高效的基于Rust的TinyML推理引擎 作者信息&#xff1a; Matteo Carnelos&#xff0c;意大利帕多瓦大学&#xff0c;Grepit AB,…

什么软件可以晚上睡觉录音

什么软件可以晚上睡觉录音&#xff0c;在日常生活中&#xff0c;我们常常忽略夜间的声音&#xff0c;然而这些声音有时可能会揭示重要信息&#xff0c;比如打鼾情况、说梦话、甚至是潜在的睡眠问题。因此&#xff0c;一款适合夜间录音的软件对于关注健康及生活细节的人来说至关…

在IDEA中配置Selenium和WebDriver

前言&#xff1a; 在当今自动化测试和网络爬虫的领域&#xff0c;Selenium是一个被广泛使用的工具。它不仅能够模拟用户与浏览器的交互&#xff0c;还能进行网页测试和数据抓取。而为了使用Selenium与谷歌/Edge浏览器进行自动化测试&#xff0c;配置合适的WebDriver至关重要。本…

【时时三省】(C语言基础)指针笔试题8

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 笔试题8 c是个数组 它的每个元素是char* 它初始化了四个字符串 把这四个字符串的首字符的地址 传到了c里面 cp有四个元素 每个元素的类型是char** 所以c3指向FORST c2指向POINT c1指向NE…

数学建模算法与应用 第9章 支持向量机及其方法

目录 9.1 支持向量机的基本原理 核函数的种类&#xff1a; 9.2 支持向量机的Matlab命令及应用 Matlab代码示例&#xff1a;二分类支持向量机 9.3 乳腺癌的诊断案例 Matlab代码示例&#xff1a;乳腺癌数据分类 9.4 支持向量回归&#xff08;SVR&#xff09; Matlab代码示…