爬虫系列总目录
本章节介绍爬虫中使用的基础库用于选择,过滤页面信息。包括requests,bs4等。
第二章 爬虫基础库-requests/bs4
第二章 正则表达式
一、正则表达式
正则表达式,⼜称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或
RE)计算机科学的⼀个概念。正则表达式通常被⽤来检索、替换那些符合某个模式(规则)的⽂本。
二、Python中的正则模块re
2.1 re模块操作
在Python中需要通过正则表达式对字符串进⾏匹配的时候,可以使⽤re模块
re.match()必须从字符串的开头进⾏匹配,如果字符串的开头不匹配,整个匹配就失败了
import re
string = 'baidu.com'
result = re.match('baidu', string)
print(result.group())
2.2 匹配单个字符
字符:对应功能
.
匹配任意1个字符(除了\n)【匹配\n时会报错】[ ]
匹配[ ]中列举的字符 【匹配[ ]中的任何⼀个字符】- \d 匹配数字,即0-9; \D 匹配⾮数字,即不是数字
- \s 匹配空⽩,即 空格,tab键 【都是空⽩】; \S 匹配⾮空⽩
- \w 匹配单词字符,即a-z、A-Z、0-9、_;\W 匹配⾮单词字符 【⾮下划线】
.
匹配除换行符 \n 之外的任何单字符。要匹配.
,请使用\.
2.3 匹配多个字符
? * 都有匹配0次的情况,未匹配时返回空字符串。
*
匹配前⼀个字符出现0次或者⽆限次,即可有可无+
匹配前⼀个字符出现1次或者⽆限次,即⾄少有1次- ?匹配前⼀个字符出现1次或者0次,即要么有1次,要么没有
- {m} 匹配前⼀个字符出现m次
- {m,n} 匹配前⼀个字符出现从m到n次
# 判断能不能作为python变量名
result = re.match('[a-zA-Z_]+[\w]*', 'li_1')
# 练习:匹配邮箱(邮箱需要以字⺟开头,可以使⽤数字、字⺟、下划线,⻓度为6-8 -- ⽹易邮箱要求)
mail = "a1234567@163.com"
result = re.match('[a-zA-Z]{1}\w{5,7}@163\.com', mail)
2.4 匹配开头和结尾
^
1.匹配字符串开头 (写在最前面是开头) 2. 取反 (其他地方是取反)$
匹配字符串结尾
2.5 匹配分组
- | 匹配左右任意⼀个表达式
- (ab) 将括号中字符作为⼀个分组
- \num 引⽤分组num匹配到的字符串, \1 复用第一个的内容(数字从1开始)
- (?P) 分组起别名
- (?P=name) 引⽤别名为name分组匹配到的字符串
注意点:(?P)和(?P=name)中的字⺟P⼤写
# 匹配0-100的数字
result = re.match("[1-9]?\d$|100", "87")
# 检查html 标签是否成对出现
result = re.match(r"<([a-zA-Z]*)>\w*</\1>","<html>p</html>")
print(result.group())
labels = ["<p><span>www.baidu.com</span></p>", "<p><span>www.baidu.com</p></p>"]
for label in labels:
result = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", label)
# 引⽤()分组规则复⽤
# result = re.match(r"<(?P<p1>\w*)><(?P<span1>\w*)>.*</(?P=span1)></(?P=p1)>",label)
if result:
print("{}是符合要求的标签".format(result.group()))
else:
print("{}不符合要求".format(label))
2.6 其他re函数
- re.findall() :在字符串中找到正则表达式所匹配的所有⼦串,并返回⼀个列表,如果没有找到匹配的,则返回空列表。
- re.search() 扫描整个字符串,并返回第⼀个成功的匹配。如果匹配失败,则返回None,不要求必须从字符串的开头进⾏匹配。用group获取的分组信息,result.group(0) 是全部,
- re.sub() 某一个内容进行替换
- re.split()按照能够匹配的⼦串将字符串分割后返回列表。
content = '字数:1057 阅读:6618'
result = re.split('\s|:', content)
print(result)
2.7 贪婪与非贪婪
通过在 *、+ 或 ? 限定符之后放置 ?,该表达式从"贪婪"表达式转换为"非贪婪"表达式或者最小匹配。
正则表达式式中在使⽤通配符匹配(* + ?
)时,是从左到右进⾏匹配,会尽可能的获取满⾜匹配条件的最⻓字符串,也就是默认为贪婪模式,⽽⾮贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。
这两种模式都必须满⾜匹配次数的要求才能匹配上
- 贪婪模式,简单说就是尽可能进⾏最⻓匹配, 匹配上从第⼀个 " 到最后⼀个 " 之间的所有内容
- ⾮贪婪模式,则会尽可能进⾏最短匹配,⾮贪婪匹配:找到符合要求的结果
content = "abc12345"
result = re.match('\D+?', content)
print(result.group())
result = re.findall('\D+', content)
print(result)