学会正则表达式后,使用requests里的re模块就可以轻松应用到爬虫中。
首先引入re,然后介绍re模块的3个常用函数和1个常用操作:
import re
【1】findall
result= re.findall(r“\d+”,"我今天买了2个榴莲,花了200元。")
print(result)
使用正则表达式,对句子中的两个数字进行提取:\d+
正则表达式前面的r用于消除反斜杠的影响
使用findall后,拿到的结果是列表:
['2', '200']
【2】search
result = re.search(r"\d+","我今天买了2个榴莲,花了200元。")
print(result.group())
使用search后,只返回第一个命中的结果。
注意,这时result是match object,如果直接打印是这样的:
<re.Match object; span=(5, 8), match='2'>
想要从match对象中拿到数据的话,要使用group():
['2', '200']
【3】finditer
如果需要处理的数据是巨型字符串,可以使用finditer,把结果放在迭代器里——通过遍历同样可以正常拿到目标结果,而且可以节省内存资源。
result = re.finditer(r"\d+","我今天买了2个榴莲,花了200元。")
for item in result:
print(item.group())
打印结果:
2
200
【4】compile预加载
提前加载好一个正则,用来把正则表达式与业务代码分开,后续可以直接调用。代码逻辑会更加清晰,易于阅读。
obj = re.compile(r"\d+")
result = obj.findall("我今天买了2个榴莲,花了200元。")
print(result)
【5】实战栗子来一个
现在有一个长字符串,类似网页爬取的原始数据:
s = """
<div class="abc">
<div><a href="baidu.com">我是百度</a></div>
<div><a href="163.com">我是neteasy</a></div>
<div><a href="qq.com">我是qq</a></div>
</div>
"""
下面要把链接和文字单独提取出来。
首先使用预加载,定义正则表达式:
obj = re.compile(r'<div><a href=".*?">.*?</a></div>')
其中,.*?是上一篇讲过的惰性匹配,找到最短距离命中的内容。
result = obj.finditer(s)
for item in result:
print(item.group())
输出的结果是:
<div><a href="baidu.com">我是百度</a></div>
<div><a href="163.com">我是neteasy</a></div>
<div><a href="qq.com">我是qq</a></div>
内容所在的行找到了!怎么把想要的东西抠出来呢?
大招:(?P<代号>.*?),用于提取惰性匹配.*?命中的内容,并存放到“代号”命名的分组里。
obj = re.compile(r'<div><a href="(?P<url>.*?)">(?P<txt>.*?)</a></div>')
result = obj.finditer(s)
for item in result:
url = item.group("url")
txt = item.group("txt")
print(url,txt)
打印结果:
baidu.com 我是百度
163.com 我是neteasy
qq.com 我是qq
for循环中的处理还可以写为:
for item in result:
print(item.groupdict())
结果以键值对形式进行展示:
{'url': 'baidu.com', 'txt': '我是百度'}
{'url': '163.com', 'txt': '我是neteasy'}
{'url': 'qq.com', 'txt': '我是qq'}