网络爬虫进阶

一、re模块compile

在爬虫或任何需要处理字符串和文本数据的Python程序中,re模块的compile()函数是一个非常重要的工具。这个函数用于编译一个字符串形式的正则表达式,将其转换为一个模式对象(Pattern对象)。使用编译后的模式对象进行匹配操作(如match()search()findall()等)通常比直接使用字符串形式的正则表达式更高效,特别是当需要对同一个正则表达式进行多次匹配操作时。

在爬虫开发中,经常需要从HTML或XML文档中提取信息。这些信息可能以各种形式存在,如标签内的文本、属性值等。通过使用re.compile()编译正则表达式,爬虫可以更高效地提取这些数据。

# 导入re
import re
# \d 数字 +1 次无数次 r表示原始字符串
patteren = re.compile(r'\d+')
print(patteren)

二、match方法使用

在Python的re模块中,match()方法用于从字符串的起始位置匹配正则表达式。如果匹配成功,它会返回一个匹配对象(Match对象),否则返回None。这个特性使得match()方法特别适用于检查一个字符串是否以某个模式开始。

在爬虫中,match()方法可能不是最常用的,因为爬虫通常需要处理的是HTML或XML文档,这些文档的结构往往比较复杂,不一定以简单的模式开始。然而,在处理某些特定格式的文本或响应头时,match()方法仍然非常有用。

# 导入re模块
import re
# 设置正则表达式匹配规则
pattern = re.compile(r"\d+")
# m1 = pattern.match('123456789')
# m1 = pattern.match('1234a56789')
# 匹配的目标文本,没有匹配到则终止匹配,由于o字母不是数字因此无匹配数据
m1 = pattern.match('one1234two56three789')
print(m1)
# print(m1.group())
#match 从第一个o匹配
# 参数2:匹配的起始位置,下标数包含
# 参数3:匹配的结束位置,下标数不包含
m1 = pattern.match('one1234two56three789',3,6) #,3,6定义区间 索引(下标数)表示 不是位数表示 由0开始
print(m1.group())  # 通过group查看匹配的数据

三、search方法的使用

在Python的re模块中,search()方法用于在字符串中搜索第一个匹配正则表达式的位置。与match()方法不同,search()方法不需要匹配发生在字符串的起始位置。如果找到匹配项,search()会返回一个匹配对象(Match对象),其中包含有关匹配的信息;如果没有找到匹配项,则返回None

在爬虫中,search()方法非常有用,因为它允许你在HTML文档或其他文本数据中搜索特定的模式,而不需要担心这些模式是否位于文本的开头。例如,你可以使用search()来查找HTML中的特定标签、属性或文本内容。

虽然findall()方法可能更常用于提取多个匹配项,但search()方法可以在找到第一个匹配项后立即停止搜索,这在某些情况下可以提高效率。然而,对于提取所有链接的情况,findall()通常是更好的选择。不过,为了说明search()的用法,我们可以假设我们只关心HTML中的第一个链接。

import re

pattern = re.compile(r"\d+")
# search 字符串中任意位置匹配,如果匹配失败则结束匹配 从第一个开始满足条件的开始往后走 然后在后边有不满足的直接结束 前边不满足的跳过 找到第一个满足的再继续往下走
#方法用于查找字符串的任意位置
#他是一次匹配,只要找到一个匹配的结果就返回,不是查找所有匹配的结果
m1 = pattern.search('one123two456three789')
print(m1.group())

四、findall方法使用

在Python的re模块中,findall()方法用于在字符串中查找所有匹配正则表达式的子串,并返回一个包含所有匹配项的列表。如果没有找到任何匹配项,它将返回一个空列表。这个方法非常适合于从文本中提取多个符合特定模式的片段,如电话号码、电子邮件地址、链接等。

在爬虫开发中,findall()方法常用于从HTML或XML文档中提取多个匹配项。例如,你可能需要从一个网页中提取所有图片的URL、所有链接的文本或所有特定类别的数据。

import re

# pattern = re.compile(r"\d+")  # 正则表达式规则要求
# #  finall 方法用于搜索整个字符串,获得所有匹配结果
# result = pattern.findall('hello 123 world 456')
# print(result)

# 获得所有字母
pattern = re.compile(r"\D+")
result = pattern.findall('hello 123 world 456')
print(result)

五、split方法的使用

在爬虫开发中,split() 方法是 Python 字符串对象的一个非常有用的内置方法,它用于将字符串分割成列表。虽然 split() 方法本身并不直接涉及网络请求或HTML解析等爬虫特有的操作,但它经常在处理从网页中提取的数据时使用,特别是在需要将数据从较大的字符串中分离成更小的、可管理的部分时。

split() 方法可以接受一个可选的分隔符作为参数,如果不提供参数,则默认使用任何空白字符(如空格、换行符 \n、制表符 \t 等)作为分隔符。

在爬虫中,split() 方法可以用于处理从网页中提取的字符串数据,比如将CSV格式的数据行分割成多个字段,或将包含多个值的字符串(由特定分隔符分隔)分解成单独的元素。

import re

str = 'a,b,c'
print(str.split(','))  # 逗号间隔符

str1 = 'a,b;; c d'
# 匹配的格式:按照, ; 空格 进行拆分
pattern = re.compile(r'[\s\,\;]+')  # \s表空格 ,表示,\;表示;
print(pattern.split(str1))

六、sub方法的使用

在爬虫开发中,sub() 方法并不是 Python 标准库中直接用于爬虫的一个特定方法,但它却是 re 模块(正则表达式模块)中一个非常有用的函数,经常在处理从网页中提取的文本数据时用到。sub() 方法用于替换字符串中所有匹配正则表达式的部分。

re.sub(pattern, repl, string, count=0, flags=0) 函数的基本参数如下:

  • pattern:正则表达式的模式字符串。
  • repl:替换的字符串(也可为一个函数)。
  • string:要被查找和替换的原始字符串。
  • count:模式匹配后替换的最大次数,默认为0,表示替换所有的匹配。
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。

在爬虫中,sub() 方法常用于清理或修改从网页中提取的文本数据。例如,你可能需要去除文本中的HTML标签、替换特定的字符或字符串、清理不必要的空格等。

import re

string = '<h1 class="test">HelloWorld</h1>'
pattern = re.compile(r'\d')
# 参数1:替换后的值
# 参数2:原字符串 原值
print(pattern.sub('2', string))
# 参数3:替换几个
print(pattern.sub('2', string,2))

# 分组
string='<h1 class="test">HelloWorld</h1>'
# P<classname>为组声明一个名字可以通过名字调用该组
pattern = re.compile(r'<(.\d)\sclass="(?P<classname>.*?)">.*?</(.1)>')
print(pattern.search(string).group(1))
print(pattern.search(string).group(2))
print(pattern.search(string).group('classname'))
print(pattern.search(string).group(3))

# 定义函数时定义一个形参m
def func(m):
    return "after sub" + m.group('classname')

# sub方法中传入函数,
# 参数1:函数名
# 参数2:目标字符串
print(pattern.sub(func,string))

七、贪婪匹配

在爬虫和正则表达式(Regular Expressions)中,贪婪匹配(Greedy Matching)是一种默认的行为模式,它会在满足匹配条件的前提下,尽可能多地匹配字符。这种匹配方式通常用于没有明确指定匹配次数的场景,如使用*(匹配0次或多次)、+(匹配1次或多次)、?(匹配0次或1次,但通常与贪婪性无关,因为它本身只涉及是否存在)以及大括号{}指定重复次数的范围时(如{m,n},其中n是可选的,表示至少匹配m次,如果指定了n,则最多匹配n次)。

要避免贪婪匹配,我们可以使用非贪婪(或非贪婪、懒惰)匹配模式。在正则表达式中,通过在量词(如*+?{m,n})后面加上?来实现非贪婪匹配。这样,匹配引擎就会在满足条件的情况下尽可能少地匹配字符。

注意事项

  • 贪婪匹配和非贪婪匹配的选择取决于你的具体需求。在爬虫和正则表达式中,通常建议使用非贪婪匹配来避免匹配过多的内容。

  • 在处理复杂的HTML或XML文档时,建议使用专门的HTML/XML解析器(如BeautifulSoup、lxml等),因为正则表达式可能无法准确处理嵌套标签和复杂的文档结构。

  • 在使用正则表达式时,请确保对正则表达式有足够的了解,以避免出现意外的匹配结果。

    import re

    string = '

    HelloWorld

    '

    pattern = re.compile(r'<.\d\sclass=.*>')

    pattern = re.compile(r'<.\d\sclass=.*?>')

    匹配到最近的

    print(pattern.search(string).group())

相关推荐
捕鲸叉2 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer6 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq8 分钟前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
阡之尘埃36 分钟前
Python数据分析案例61——信贷风控评分卡模型(A卡)(scorecardpy 全面解析)
人工智能·python·机器学习·数据分析·智能风控·信贷风控
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
音徽编程2 小时前
Rust异步运行时框架tokio保姆级教程
开发语言·网络·rust
观音山保我别报错2 小时前
C语言扫雷小游戏
c语言·开发语言·算法
小屁孩大帅-杨一凡3 小时前
java后端请求想接收多个对象入参的数据
java·开发语言