python 爬虫(二) re & 正则表达式

既然百度的源代码这么多,我们怎么找到自己需要的内容呢?

正则表达式

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),可以用来描述和匹配字符串的特定模式。

正则表达式是一种用于模式匹配和搜索文本的工具。

正则表达式提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据。

我们可以用re的findall来匹配文本,举个例子

import re

ret = re.findall(r'\d', '123啦啦啦') #(r'正则匹配符号', '要匹配的字符串')

print(ret)
#输出['1', '2', '3']

正则匹配常用元字符

\d匹配数字
\D匹配非数字
\s匹配空白符
\S匹配非空白符
\w匹配数字&字母下&划线
\W匹配非数字&字母下&划线
\$匹配字符串的结尾
\^匹配字符串的开始
.匹配除了换行符外的所有字符

常用量词(控制前面的元字符的出现次数)

量词
*重复零次或多次
+重复一次或多次
?重复零次或一次
{n}重复n次,n为变量

re常用方法

re.findall返回形式为列表
re.finditer迭代
re.complie设置正则

1.re.findall

在Pycharm或Vscode中,按住ctrl,再点击findall,就会出现该函数的用法

def findall(pattern: str | Pattern[str], string: str, flags: _FlagsType = 0) -> list[Any]: ...

def findall(pattern: bytes | Pattern[bytes], string: ReadableBuffer, flags: _FlagsType = 0) -> list[Any]: ...

def finditer(pattern: str | Pattern[str], string: str, flags: _FlagsType = 0) -> Iterator[Match[str]]: ...

可以发现,在解释中,findall输出的是列表

用法:

re.findall(r'\d', '123哈哈哈') #匹配字符串中的数字

因为findall输出的是列表,所以推荐使用finditer迭代输出,这样输出会比较美观

2.re.finditer

finditer是以迭代的形式输出的,解释如下

def finditer(self: Pattern[str], string: str, pos: int = 0, endpos: int = sys.maxsize) -> Iterator[Match[str]]: ...

def finditer(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Iterator[Match[bytes]]: ...  # type: ignore[overload-overlap]

def finditer(self, string: AnyStr, pos: int = 0, endpos: int = sys.maxsize) -> Iterator[Match[AnyStr]]: ...

如果直接输出finditer,

re.finditer(r'\d', '123哈哈哈') #匹配字符串中的数字

则会输出:

<callable_iterator object at 0x000002BF6D93E530>

正确的输出finditer方式:

import re

ret = re.finditer(r'\d', '123啦啦啦')

for iter in ret:
    print(iter.group())

#输出:
1
2
3

3.re.complie

可以通过re.complie设置正则

例如:

import re

obj_ = re.complie(r'\d', re.S)
ret = obj.finditer('123哈哈哈')

for iter in ret:
    print(iter.group())

.*?  匹配除了换行符以外的所有字符一次或多次

前面说了,(.)匹配除了换行符以外的所有字符,而(*)和(?)则是量词, 这三个合起来,就组成了我们常用的(.*?)

除此之外,还有很多组合,如(.*) (+?)等等,感兴趣可以去专门搜搜看

用?P<name>给正则取名字

如果我们相匹配多个内容,就可以用?P<name>来进行分类,如下:

import re

obj = re.compile(r'<h1>(?P<name1>.*?)</h1><span>(?P<name2>.*?)</span>', re.S)

ret = obj.finditer('<h1>内容1</h1><span>内容2</span>')

for iter in ret:
    print(iter.group('name1'))
    print(iter.group('name2'))

运行后会输出内容1和内容2

接下来,用re在爬取的源代码中找到想要的内容

我们举个例子,把百度的热搜榜爬下来练练手先

先到百度页面之后右键,点击查看源代码,随后ctrl+F,找到其中一个热搜

b7245731ff014c4c8db57e582e30a70c.png

找到这些热搜之后,我们不难发现这些热搜的格式都是

"card_title": "热搜的内容"

根据这个发现,我们把热搜的内容匹配,就能得到百度的热搜

"card_title": "(?P<name>.*?)"

源代码如下

import requests
import re

url = 'https://www.baidu.com' #要爬取的url

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36'
}

res = requests.get(url, headers=headers) #请求url

obj = re.compile(r'"card_title": "(?P<name>.*?)"', re.S)
ret = obj.finditer(res.text)


for iter in ret:
    print(iter.group('name'))

输出的结果为:

以人口高质量发展支撑东北全面振兴
罗永浩:“真还传”共还了8.24亿
黄子韬求婚徐艺洋
各地采取多种措施保民生保安全
13岁男孩血尿医生取出20多颗磁力珠
4名奥运冠军代言“好客山东”
10年来结婚登记数腰斩
男子每天1斤花生米配可乐引发脑梗死
水果太甜是打了甜蜜素?谣言
男生开学打开行李箱天塌了:粉色被褥
国家一级演员王霙逝世
山东一女生军训时死亡 疑中暑导致
女子被榴莲咬脚杀伤力满级
网贷60万做榜1大哥后送外卖还债
陈梦回应佩戴定制首饰参赛
1天花掉一万五中产家长的迪士尼苦旅
清华大学新生军训 凌晨20公里拉练
记者暗访“疯狂的烟卡”
《康熙》造型师Enzo因癫痫去世
陈梦收到山东花饽饽版金牌
爷爷卖南瓜饼1元1个被顾客劝涨价
中国队巴黎残奥开幕式旗手公布
罕见大暴雨闯入北方
泰国被辱骂的中国女子拒绝和解
网红穿霸王茶姬工服热舞被指擦边
全红婵去盘真乌龟了
日本民众抗议核污染水排放
住建部官媒:房屋养老金不是房地产税
张豆豆牵走哭泣的孙杨
解放军在中缅边境组织实兵实弹演习
莫迪首次回应女实习医生遭奸杀案
今年中秋放假3天需调休
专家称鼓励生育问题还是得问年轻人
泽连斯基:又拿下库尔斯克两个村庄
IBM关闭中国研发部门
四川阿坝一驻村女书记下乡时失联
表兄妹结婚10年育一女被判婚姻无效
房屋养老金业主需要直接出钱吗?
乌全境多地发生爆炸
北京全市降雨量已达暴雨量级
吴艳妮:邪不胜正 感恩我大国公安
通关黑神话 这些景区都免费
优步非法传输隐私数据被罚2.9亿欧元
美国发现致命东方马脑炎病例
小孩飞机上被陌生人关厕所 警方回应
我国目前没有西尼罗病毒感染病例
孙颖莎回应王楚钦看自己脸色
驴友徒步玉龙雪山失联9天遇难
PS C:\Users\weihaiyan2\Documents\python> & C:/Users/weihaiyan2/AppData/Local/Microsoft/WindowsApps/python3.12.exe c:/Users/weihaiyan2/Documents/python/学习python/草稿纸2.py
以人口高质量发展支撑东北全面振兴
罗永浩:“真还传”共还了8.24亿
黄子韬求婚徐艺洋
各地采取多种措施保民生保安全
13岁男孩血尿医生取出20多颗磁力珠
国家一级演员王霙逝世
10年来结婚登记数腰斩
男子每天1斤花生米配可乐引发脑梗死
水果太甜是打了甜蜜素?谣言
男生开学打开行李箱天塌了:粉色被褥
女子被榴莲咬脚杀伤力满级
山东一女生军训时死亡 疑中暑导致
网贷60万做榜1大哥后送外卖还债
陈梦回应佩戴定制首饰参赛
清华大学新生军训 凌晨20公里拉练
1天花掉一万五中产家长的迪士尼苦旅
罕见大暴雨闯入北方
陈梦收到山东花饽饽版金牌
记者暗访“疯狂的烟卡”
乌克兰全境实施紧急停电
《康熙》造型师Enzo因癫痫去世
爷爷卖南瓜饼1元1个被顾客劝涨价
网红穿霸王茶姬工服热舞被指擦边
全红婵去盘真乌龟了
张豆豆牵走哭泣的孙杨
住建部官媒:房屋养老金不是房地产税
解放军在中缅边境组织实兵实弹演习
今年中秋放假3天需调休
专家称鼓励生育问题还是得问年轻人
莫迪首次回应女实习医生遭奸杀案
泽连斯基:又拿下库尔斯克两个村庄
IBM关闭中国研发部门
4名奥运冠军代言“好客山东”
表兄妹结婚10年育一女被判婚姻无效
四川阿坝一驻村女书记下乡时失联
乌全境多地发生爆炸
房屋养老金业主需要直接出钱吗?
北京全市降雨量已达暴雨量级
中国队巴黎残奥开幕式旗手公布
吴艳妮:邪不胜正 感恩我大国公安
通关黑神话 这些景区都免费
优步非法传输隐私数据被罚2.9亿欧元
美国发现致命东方马脑炎病例
小孩飞机上被陌生人关厕所 警方回应
我国目前没有西尼罗病毒感染病例
驴友徒步玉龙雪山失联9天遇难
看邓紫棋演唱会旁边是鹿晗
孙杨提前伸脖子等待金牌
吴彦姝卡点发文给刘亦菲庆生

还可以在热搜前加上数字排序

import requests
import re

numbers = 0
url = 'https://www.baidu.com' #要爬取的url

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36'
}

res = requests.get(url, headers=headers) #请求url

obj = re.compile(r'"card_title": "(?P<name>.*?)"', re.S)
ret = obj.finditer(res.text)


for iter in ret:
    numbers += 1
    text = numbers, iter.group('name')
    print(text[0], text[1])

输出结果:

1 以人口高质量发展支撑东北全面振兴
2 罗永浩:“真还传”共还了8.24亿
3 黄子韬求婚徐艺洋
4 各地采取多种措施保民生保安全
5 13岁男孩血尿医生取出20多颗磁力珠
6 男子仅退款被拒后起诉网店被驳回
7 以色列水兵遭自家导弹误炸身亡
8 10年来结婚登记数腰斩
9 水果太甜是打了甜蜜素?谣言
10 陈梦回应佩戴定制首饰参赛
11 女子被榴莲咬脚杀伤力满级
12 男生开学打开行李箱天塌了:粉色被褥
13 国家一级演员王霙逝世
14 山东一女生军训时死亡 疑中暑导致
15 爷爷卖南瓜饼1元1个被顾客劝涨价
16 男子每天1斤花生米配可乐引发脑梗死
18 22城试点房屋养老金 对财政有何影响
19 乌克兰全境实施紧急停电
20 陈梦收到山东花饽饽版金牌
21 小孩飞机上被陌生人关厕所 警方回应
22 全红婵去盘真乌龟了
23 网贷60万做榜1大哥后送外卖还债
24 张豆豆牵走哭泣的孙杨
25 清华大学新生军训 凌晨20公里拉练
26 记者暗访“疯狂的烟卡”
27 《康熙》造型师Enzo因癫痫去世
28 网红穿霸王茶姬工服热舞被指擦边
29 罕见大暴雨闯入北方
30 专家称鼓励生育问题还是得问年轻人
31 住建部官媒:房屋养老金不是房地产税
32 莫迪首次回应女实习医生遭奸杀案
33 解放军在中缅边境组织实兵实弹演习
34 美国发现致命东方马脑炎病例
35 今年中秋放假3天需调休
36 IBM关闭中国研发部门
37 表兄妹结婚10年育一女被判婚姻无效
38 泽连斯基:又拿下库尔斯克两个村庄
39 北京全市降雨量已达暴雨量级
40 女子飞机上吸电子烟被行拘
41 驴友徒步玉龙雪山失联9天遇难
42 房屋养老金业主需要直接出钱吗?
43 杭州多起半夜骑行党相撞事故
44 四川阿坝一驻村女书记下乡时失联
45 伊拉克武装袭击以色列
46 吴艳妮:邪不胜正 感恩我大国公安
47 乌全境多地发生爆炸
48 吴彦姝卡点发文给刘亦菲庆生
49 涉嫌骗保3.3亿 两医院全流程造假
PS C:\Users\weihaiyan2\Documents\python> & C:/Users/weihaiyan2/AppData/Local/Microsoft/WindowsApps/python3.12.exe c:/Users/weihaiyan2/Documents/python/学习python/草稿纸2.py
1 以人口高质量发展支撑东北全面振兴
2 罗永浩:“真还传”共还了8.24亿
3 黄子韬求婚徐艺洋
4 各地采取多种措施保民生保安全
5 13岁男孩血尿医生取出20多颗磁力珠
6 4名奥运冠军代言“好客山东”
7 10年来结婚登记数腰斩
8 男生开学打开行李箱天塌了:粉色被褥
9 水果太甜是打了甜蜜素?谣言
10 男子每天1斤花生米配可乐引发脑梗死
11 国家一级演员王霙逝世
12 山东一女生军训时死亡 疑中暑导致
13 陈梦回应佩戴定制首饰参赛
14 女子被榴莲咬脚杀伤力满级
15 网贷60万做榜1大哥后送外卖还债
16 1天花掉一万五中产家长的迪士尼苦旅
17 乌克兰全境实施紧急停电
18 记者暗访“疯狂的烟卡”
19 陈梦收到山东花饽饽版金牌
20 清华大学新生军训 凌晨20公里拉练
21 爷爷卖南瓜饼1元1个被顾客劝涨价
22 《康熙》造型师Enzo因癫痫去世
23 网红穿霸王茶姬工服热舞被指擦边
24 泰国被辱骂的中国女子拒绝和解
25 全红婵去盘真乌龟了
26 罕见大暴雨闯入北方
27 日本民众抗议核污染水排放
28 住建部官媒:房屋养老金不是房地产税
29 张豆豆牵走哭泣的孙杨
30 今年中秋放假3天需调休
31 莫迪首次回应女实习医生遭奸杀案
32 解放军在中缅边境组织实兵实弹演习
33 专家称鼓励生育问题还是得问年轻人
34 泽连斯基:又拿下库尔斯克两个村庄
35 IBM关闭中国研发部门
36 女子飞机上吸电子烟被行拘
37 表兄妹结婚10年育一女被判婚姻无效
38 四川阿坝一驻村女书记下乡时失联
39 房屋养老金业主需要直接出钱吗?
40 北京全市降雨量已达暴雨量级
41 乌全境多地发生爆炸
42 吴艳妮:邪不胜正 感恩我大国公安
43 小孩飞机上被陌生人关厕所 警方回应
44 孙颖莎回应王楚钦看自己脸色
45 杭州多起半夜骑行党相撞事故
46 中国队巴黎残奥开幕式旗手公布
47 南部战区赴边境一线空地联合警巡
48 通关黑神话 这些景区都免费
49 驴友徒步玉龙雪山失联9天遇难

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值