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查询Mysql时返回字典结构的代码
Jun 18 Python
python使用urllib2模块获取gravatar头像实例
Dec 18 Python
Python中使用PIL库实现图片高斯模糊实例
Feb 08 Python
Python编写一个优美的下载器
Apr 15 Python
Pycharm无法使用已经安装Selenium的解决方法
Oct 13 Python
使用 Visual Studio Code(VSCode)搭建简单的Python+Django开发环境的方法步骤
Dec 17 Python
在python中使用with打开多个文件的方法
Jan 07 Python
使用PyQtGraph绘制精美的股票行情K线图的示例代码
Mar 14 Python
python 随机森林算法及其优化详解
Jul 11 Python
Python+OpenCV实现实时眼动追踪的示例代码
Nov 11 Python
在django中form的label和verbose name的区别说明
May 20 Python
详解python os.path.exists判断文件或文件夹是否存在
Nov 16 Python
python 离散点图画法的实现
Python学习之迭代器详解
Python实战之大鱼吃小鱼游戏的实现
OpenCV实现常见的四种图像几何变换
关于Python使用turtle库画任意图的问题
Apr 01 #Python
python套接字socket通信
python文件与路径操作神器 pathlib
You might like
PHP n个不重复的随机数生成代码
2009/06/23 PHP
php读取EXCEL文件 php excelreader读取excel文件
2012/12/06 PHP
一些php项目中比较通用的php自建函数的详解
2013/06/06 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
JavaScript 实现模态对话框 源代码大全
2009/05/02 Javascript
extjs 学习笔记 四 带分页的grid
2009/10/20 Javascript
JavaScript(js)设置默认输入焦点(focus)
2012/12/28 Javascript
JavaScript中的运算符种类及其规则介绍
2013/09/26 Javascript
JS实现模仿微博发布效果实例代码
2013/12/16 Javascript
分享33个jQuery与CSS3实现的绚丽鼠标悬停效果
2014/12/15 Javascript
完美兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面js代码
2014/12/17 Javascript
JavaScript地理位置信息API
2016/06/11 Javascript
原生js验证简洁注册登录页面
2016/12/17 Javascript
JavaScript 数组的进化与性能分析
2017/09/18 Javascript
ES6 javascript中class静态方法、属性与实例属性用法示例
2017/10/30 Javascript
Vue.js实现表格渲染的方法
2018/09/07 Javascript
jQuery 点击获取验证码按钮及倒计时功能
2018/09/20 jQuery
electron 安装,调试,打包的具体使用
2019/11/06 Javascript
[04:02]DOTA2上海特锦赛小组赛第二日recap精彩回顾
2016/02/28 DOTA
Python中if elif else及缩进的使用简述
2018/05/31 Python
python解析命令行参数的三种方法详解
2019/11/29 Python
基于Python生成个性二维码过程详解
2020/03/05 Python
pandas 强制类型转换 df.astype实例
2020/04/09 Python
Python 微信公众号文章爬取的示例代码
2020/11/30 Python
西雅图的买手店:Totokaelo
2019/10/19 全球购物
哥德堡通行证:Gothenburg Pass
2019/12/09 全球购物
精彩的大学生自我评价
2013/11/17 职场文书
会计职业生涯规划范文
2014/01/04 职场文书
妈妈的账单教学反思
2014/02/06 职场文书
会计求职信
2014/05/29 职场文书
元旦趣味活动方案
2014/08/22 职场文书
2014年党员自我评议总结
2014/09/23 职场文书
群众路线党员个人剖析材料
2014/10/08 职场文书
社会实践活动报告
2015/02/05 职场文书
骆驼祥子读书笔记
2015/06/26 职场文书
vue-router中hash模式与history模式的区别
2021/06/23 Vue.js