Pyhton爬虫知识之正则表达式详解


Posted in Python onApril 01, 2022

前言

在爬虫的开发中,需要把有用的信息从一大段文本中提取出来,正则表达式是提取信息的方法之一。

1、正则表达式基础

正则表达式(Regular Expression)是一段字符串,它可以表示一段有规律的信息。Python自带一个正则表达式模块 - re,通过这个模块可以查找、提取、替换一段有规律的信息。在程序开发中,要让计算机程序从一大段文本中找到需要的内容,就可以使用正则表达式来实现。

使用正则表达式有如下步骤:

(1)寻找规律

(2)使用正则符号表示规律

(3)提取信息

2、正则表达式的基本符号

2.1 点号 “.”

一个点号可以代替除了换行符以外的任何一个字符,包括但不限于英文字母、数字、汉字、英文标点符号和中文标点符号。

2.2 星号 “*”

一个星号可以表示它前面的一个子表达式(普通字符、另一个或几个正则表达式符号)0次到无限次。

2.3 问号 “?”

一个问号可以表示它前面的子表达式0次或者1次。注意,这里的问号是英文问号。

2.4 反斜杠 “\”

反斜杠在正则表达式里面不能单独使用,甚至在整个 Python 里都不能单独使用。反斜杠需要和其他的字符配合使用来把特殊符号变成普通符号,把普通符号变成特殊符号:

Pyhton爬虫知识之正则表达式详解

2.5 数字 “\d”

正则表达式里面使用 “\d” 来表示一位数字。为什么要用字母d呢?因为d是英文“digital(数字)”的首字母。强调一下,“\d”虽然是由反斜杠和字母d构成的,但是要把“\d”看成一个正则表达式符号整体。

2.6 小括号 “()”

小括号可以把括号里面的内容提取出来。

3、Python中使用正则表达式

Python 已经自带了一个功能非常强大的正则表达式模块。使用这个模块可以非常方便地通过正则表达式来从一大段文字中提取有规律的信息。Python的正则表达式模块名字为“re”,也就是“regularexpression”的首字母缩写。在Python中需要首先导入这个模块再进行使用。导入的语句为:

import re # pycharm 如果报错 Alt+Enter 自动导入即可

下面我们来介绍一下常用的API:

3.1 findall

Python的正则表达式模块包含一个findall方法,它能够以列表的形式返回所有满足要求的字符串。

def findall(pattern, string, flags=0):
    """Return a list of all non-overlapping matches in the string.

    If one or more capturing groups are present in the pattern, return
    a list of groups; this will be a list of tuples if the pattern
    has more than one group.

    Empty matches are included in the result."""
    return _compile(pattern, flags).findall(string)

pattern表示正则表达式,string表示原来的字符串,flags表示一些特殊功能的标志。

findall 的结果是一个列表,包含了所有的匹配到的结果。如果没有匹配到结果,就会返回空列表:

content = '我的电脑密码是:123456,我的手机密码是:888888,我的家门密码是:000000,勿忘!'

pwd_list = re.findall('是:(.*?),', content)
machine_list = re.findall('我的(.*?)密码是:', content)
name_list = re.findall('名字是(.*?),', content)
print('所有密码为:{}'.format(pwd_list))
print('所属为:{}'.format(machine_list))
print('用户姓名为:{}'.format(name_list))

结果中很明显没有匹配到结果的为空 List 。这里还有一个变化:在匹配密码的时候,如左图会少一个。原因就出在匹配上面,我的匹配规则为:'是:(.*?),',必须严格满足这个格式的文本的中间密码部分才能被提取出来,重点就是后面的 , ,如右图加上了 ,勿忘! 就使得前面的文本满足匹配规则,从而进行提取:

Pyhton爬虫知识之正则表达式详解

当需要提取某些内容的时候,使用小括号将这些内容括起来,这样才不会得到不相干的信息。如果包含多个 “(.*?)” 如下图所示,返回的仍然是一个列表,但是列表里面的元素变为了元组,元组里面的第1个元素是账号,第2个元素为密码:

Pyhton爬虫知识之正则表达式详解

函数原型中有一个flags参数。这个参数是可以省略的;当不省略的时候,具有一些辅助功能,例如忽略大小写、忽略换行符等。这里以忽略换行符为例来进行说明:

Pyhton爬虫知识之正则表达式详解

常用的参数:

re.I
    IGNORECASE
    忽略字母大小写

re.L
    LOCALE
    影响 “w, “W, “b, 和 “B,这取决于当前的本地化设置。

re.M
    MULTILINE
    使用本标志后,‘^’和‘$’匹配行首和行尾时,会增加换行符之前和之后的位置。

re.S
    DOTALL
    使 “.” 特殊字符完全匹配任何字符,包括换行;没有这个标志, “.” 匹配除了换行符外的任何字符。

re.X
    VERBOSE
    当该标志被指定时,在 RE 字符串中的空白符被忽略,除非该空白符在字符类中或在反斜杠之后。
    它也可以允许你将注释写入 RE,这些注释会被引擎忽略;
    注释用 “#”号 来标识,不过该符号不能在字符串或反斜杠之后。

参考:Python 正则表达式 flags 参数

3.2 serach

search() 的用法和 findall() 的用法一样,但是 search() 只会返回第1个满足要求的字符串。一旦找到符合要求的内容,它就会停止查找。对于从超级大的文本里面只找第1个数据特别有用,可以大大提高程序的运行效率。

def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)

对于结果,如果匹配成功,则是一个正则表达式的对象,要得到匹配到的结果,则需要通过.group()这个方法来获取里面的值;如果没有匹配到任何数据,就是 None:

Pyhton爬虫知识之正则表达式详解

只有在.group()里面的参数为1的时候,才会把正则表达式里面的括号中的结果打印出来。
.group()的参数最大不能超过正则表达式里面括号的个数。参数为1表示读取第1个括号中的内容,参数为2表示读取第2个括号中的内容,以此类推:

Pyhton爬虫知识之正则表达式详解

3.3 “.* ” 和 “.*?” 的区别

在爬虫开发中,.*? 这3个符号大多数情况下一起使用。

  • 点号表示任意非换行符的字符,星号表示匹配它前面的字符0次或者任意多次。所以“.*”表示匹配一串任意长度的字符串任意次。
  • 这个时候必须在“.*”的前后加其他的符号来限定范围,否则得到的结果就是原来的整个字符串。
  • 如果在“.*”的后面加一个问号,变成 “.*?”,那么可以得到什么样的结果呢?问号表示匹配它前面的符号0次或者1次。于是 “.*?” 的意思就是匹配一个能满足要求的最短字符串。

Pyhton爬虫知识之正则表达式详解

使用“(.*)”得到的是只有一个元素的列表,里面是一个很长的字符串。

使用“(.*?)”得到的结果是包含3个元素的列表,每个元素直接对应原来文本中的每个密码。

总结:

①“.*”:贪婪模式,获取最长的满足条件的字符串。②“.*?”:非贪婪模式,获取最短的能满足条件的字符串。

4、正则表达式提取技巧

4.1 不需使用 compile

def findall(pattern, string, flags=0):
    """Return a list of all non-overlapping matches in the string.

    If one or more capturing groups are present in the pattern, return
    a list of groups; this will be a list of tuples if the pattern
    has more than one group.

    Empty matches are included in the result."""
    return _compile(pattern, flags).findall(string)

def compile(pattern, flags=0):
    "Compile a regular expression pattern, returning a Pattern object."
    return _compile(pattern, flags)

使用re.compile()的时候,程序内部调用的是_compile()方法;当使用re.finall()的时候,在模块内部自动先调用了_compile()方法,再调用findall()方法。re.findall()自带re.compile()的功能,所以没有必要使用re.compile()。

4.2 先抓大再抓小

一些无效内容和有效内容可能具有相同的规则。这种情况下很容易把有效内容和无效内容混在一起,如下面这段文字:

有效用户:姓名: 张三姓名: 李四姓名: 王五无效用户:姓名: 不知名的小虾米姓名: 隐身的张大侠

有效用户和无效用户的名字前面都以“姓名: ”开头,如果使用“姓名: (.*?)\n”来进行匹配,就会把有效信息和无效信息混在一起,难以区分:

Pyhton爬虫知识之正则表达式详解

要解决这个问题,就需要使用先抓大再抓小的技巧。先把有效用户这个整体匹配出来,再从有效用户里面匹配出人名:

Pyhton爬虫知识之正则表达式详解

4.3 括号内和括号外

在上面的例子中,括号和“.*?”都是一起使用的,因此可能会有读者认为括号内只能有这3种字符,不能有其他普通的字符。但实际上,括号内也可以有其他字符,对匹配结果的影响结果如下:

Pyhton爬虫知识之正则表达式详解

其实不难理解,只需要记住:"按照匹配规则查找,括号内的被提取" 就可以了!

总结

到此这篇关于Pyhton爬虫知识之正则表达式的文章就介绍到这了,更多相关Pyhton爬虫正则表达式内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python 将字符串转换成字典dict
Mar 24 Python
Python环境下安装使用异步任务队列包Celery的基础教程
May 07 Python
python 容器总结整理
Apr 04 Python
深入浅析python 中的匿名函数
May 21 Python
python实现ip代理池功能示例
Jul 05 Python
python 定时器每天就执行一次的实现代码
Aug 14 Python
python分布式编程实现过程解析
Nov 08 Python
使用IDLE的Python shell窗口实例详解
Nov 19 Python
django在保存图像的同时压缩图像示例代码详解
Feb 11 Python
Python headers请求头如何实现快速添加
Nov 03 Python
Python机器学习之基础概述
May 19 Python
Python初学者必备的文件读写指南
Jun 23 Python
python 离散点图画法的实现
Python学习之迭代器详解
Python实战之大鱼吃小鱼游戏的实现
OpenCV实现常见的四种图像几何变换
关于Python使用turtle库画任意图的问题
Apr 01 #Python
python套接字socket通信
python文件与路径操作神器 pathlib
You might like
php数组合并的二种方法
2014/03/21 PHP
PHP魔术方法使用方法汇总
2016/02/14 PHP
Yii2使用$this->context获取当前的Module、Controller(控制器)、Action等
2017/03/29 PHP
JavaScript中通过闭包解决只能取得包含函数中任何变量最后一个值的问题
2010/08/12 Javascript
MooTools 页面滚动浮动层智能定位实现代码
2011/08/23 Javascript
Fixie.js 自动填充内容的插件
2012/06/28 Javascript
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
2013/12/02 Javascript
js触发select onchange事件的小技巧
2014/08/05 Javascript
js验证真实姓名与身份证号是否匹配
2015/10/13 Javascript
jQuery 1.9.1源码分析系列(十三)之位置大小操作
2015/12/02 Javascript
jQuery添加和删除输入文本框标签代码
2016/05/20 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
树结构之JavaScript
2017/01/24 Javascript
JavaScript中的E-mail 地址格式验证
2018/03/28 Javascript
Node.js进阶之核心模块https入门
2018/05/23 Javascript
Javascript 之封装(Package)
2018/09/14 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
2018/10/12 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
2019/04/08 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
2019/04/13 Javascript
vue+elementUI(el-upload)图片压缩,默认同比例压缩操作
2020/08/10 Javascript
Python中获取网页状态码的两个方法
2014/11/03 Python
使用Python编写提取日志中的中文的脚本的方法
2015/04/30 Python
Python的几个高级语法概念浅析(lambda表达式闭包装饰器)
2016/05/28 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
Python中的引用和拷贝实例解析
2019/11/14 Python
浅谈Python type的使用
2019/11/19 Python
Python原始套接字编程实例解析
2020/01/29 Python
Python实现石头剪刀布游戏
2021/01/20 Python
东方红海科技面试题软件测试方面
2012/02/08 面试题
用Python匹配HTML tag的时候,<.*>和<.*?>有什么区别
2012/11/04 面试题
常务副总经理岗位职责
2015/02/02 职场文书
北京导游词
2015/02/12 职场文书
幼儿园六一主持词开场白
2015/05/28 职场文书
小学数学国培研修日志
2015/11/13 职场文书
离婚协议书范文2016
2016/03/18 职场文书
python3+PyQt5+Qt Designer实现界面可视化
2021/06/10 Python