做 Python 爬虫的新手是不是常遇到这种情况?爬下来的网页源码一大段,满屏都是标签和杂乱文本,想提取里面的文章标题、链接、价格却无从下手;用 BeautifulSoup 定位标签总出错,尤其是遇到不规则的 HTML 结构;好不容易写个正则表达式,要么匹配不到内容,要么把无关字符全抓进来,调试半天找不到问题。别着急,兔子哥刚开始用爬虫爬电商数据时,光是提取商品价格就改了五遍正则,要么把 “¥199.9” 里的符号也抓进来,要么漏了带小数的价格,踩了不少坑。今天就带大家搞懂 Python 正则在爬虫中的常用语法,通过实战案例解析数据提取技巧,新手跟着学,轻松用正则搞定爬虫数据提取!
一、基础问题:爬虫为啥非得用正则?它能解决啥问题?
可能有朋友会问:“Python 爬虫有 BeautifulSoup、XPath 这些工具,为啥还要学正则?” 其实正则在爬虫里有它不可替代的优势:
正则表达式是一套文本匹配规则,能根据内容规律精准提取数据,尤其适合这几种场景:
- 网页标签混乱,没有固定结构,比如 JavaScript 代码里藏着的链接、杂乱文本中的手机号
- 提取无标签包裹的内容,比如 “价格:199 元” 中的数字 “199”,用正则找 “价格:(\d+) 元” 就能轻松提取
- 快速清洗爬取的脏数据,比如去掉多余空格、换行、特殊符号,比手动处理高效 10 倍
简单说,当标签定位不好用时,正则就是爬虫的 “救命稻草”,学会它,再乱的网页数据都能提取出来。
二、爬虫常用正则语法:5 类符号吃透,提取数据不发愁
正则符号不用全记,这几类在爬虫里高频使用,结合例子讲明白,你会发现规律很简单。
- 匹配字符的 “基础符号”:\d、\w、. 最实用
\d:匹配任意数字(0-9),爬价格、页码、ID 时必用。比如提取 “¥299.9” 中的数字,用\d+\.\d+就能匹配 “299.9”;提取整数价格 “399 元”,用\d+就行。\w:匹配字母、数字、下划线,提取用户名、链接中的关键部分常用。比如\w+\.html能匹配 “article123.html” 这类网页链接。.:匹配任意单个字符(除换行),万能替补,遇到不确定的字符用它。比如提取中的链接,用,.会匹配引号里的任意内容。
- 控制次数的 “限定符号”:*、+、? 别记混
这些符号规定 “前面的字符出现多少次”,是爬虫提取的核心:
*:出现 0 次或多次,适合匹配可选内容。比如链接里的 “https” 或 “http”,用https*://能同时匹配两种写法(s 可有可无)。+:出现 1 次或多次,确保内容不为空。比如提取邮箱\w+@\w+\.\w+,+保证用户名和域名至少有一个字符,避免无效数据。?:让匹配 “非贪婪”,这在爬虫里超重要!默认正则会尽可能多匹配内容,加?后会尽可能少匹配。比如提取中的标题,用xxx ,.*? .*?只会匹配到第一个结束,不会把后面的标签也抓进来。兔子哥第一次爬标题时就没加?,结果把大段 HTML 都匹配进来了,教训啊!
- 分组提取的 “括号符号”:() 精准抓内容
用()把想要提取的部分括起来,Python 的re.findall()会只返回括号里的内容。比如爬商品价格 “价格:¥159 元”,正则写价格:¥(\d+)元,findall()就会返回['159'],直接拿到数字,不用再处理多余字符。 - 定位边界的 “锚点符号”:^、$ 少用但关键
^匹配开头,$匹配结尾,在爬虫里常用于验证提取的内容是否完整。比如确认提取的手机号是 11 位数字,用^\d{11}$,避免提取到带字母的 “假手机号”。
| 符号类型 | 常用符号 | 爬虫场景作用 | 例子 |
|---|---|---|---|
| 基础符号 | \d | 提取数字(价格、ID) | \d+.\d+ 提取带小数的价格 |
| 限定符号 | ? | 非贪婪匹配,避免多抓 | .*? 匹配标签内的内容 |
| 分组符号 | () | 提取目标内容 | 价格:(\d+) 提取价格数字 |
| 锚点符号 | ^$ | 验证内容完整性 | ^\d {11}$ 验证手机号 |
三、场景问题:爬虫实战案例,3 类数据提取一步到位
结合实际爬虫场景,这三个案例几乎每天都会遇到,代码直接抄着用。
- 案例 1:提取网页中的所有链接()
爬网页时经常需要提取所有跳转链接,正则比标签定位更灵活。
需求:从 HTML 中提取所有中的链接地址。
正则表达式:href="(.*?)"
Python 实现:
python
import reimport requests# 爬取网页源码url = "https://example.com"response = requests.get(url)html = response.text# 提取所有链接links = re.findall(r'href="(.*?)"', html)for link in links[:5]: # 打印前5个链接print(link)关键点:用
(.*?)分组提取href="和"之间的内容,findall()直接返回链接列表,简单高效。- 案例 2:提取文章标题(
xxx )
标题通常在标签里,用正则能精准提取,不怕标签嵌套问题。
需求:从 HTML 中提取中的标题文本。网站标题
正则表达式:(.*?)
Python 实现:
python
# 假设html是爬取的网页源码title = re.findall(r'(.*?) ', html)if title: # 判断是否提取到内容print("文章标题:", title[0])else:print("未找到标题")关键点:
.*?非贪婪匹配,确保只提取到前的内容,避免匹配过多。- 案例 3:提取商品价格(含人民币符号和小数)
电商网站的价格格式通常是 “¥199.9”“¥299”,用正则能统一提取数字。
需求:从文本中提取 “¥199.9”“原价:¥299 元” 中的价格数字。
正则表达式:[¥¥](\d+\.?\d*)
Python 实现:
python
# 假设goods_text是爬取的商品信息文本prices = re.findall(r'[¥¥](\d+\.?\d*)', goods_text)print("提取的价格:", prices) # 输出:['199.9', '299']关键点:
[¥¥]匹配两种人民币符号,\d+\.?\d*匹配整数或小数价格,灵活应对不同格式。四、解决方案:爬虫正则最容易踩的 4 个坑,这样避开
- 坑 1:匹配不到内容,正则写对了却返回空列表
大概率是没考虑换行符!网页源码里有很多\n,而.默认不匹配换行,导致跨多行的内容匹配不到。解决方法:在re.findall()里加re.DOTALL参数,让.匹配换行,比如re.findall(r'内容(.*?)结束', html, re.DOTALL)。兔子哥爬跨多行的文本时,就因为没加这个参数,折腾了半小时才找到原因。 - 坑 2:提取内容太多,把无关字符也抓进来
这是贪婪匹配在搞鬼!比如用.*提取内容,会匹配到最后一个,中间可能夹杂其他 div。解决方法:加?用非贪婪匹配,.*?改成.*?,只匹配到第一个结束标签。
正则里的
. * + ( ) [ ]是特殊符号,想匹配它们本身必须加\转义。比如爬取包含(的内容 “价格 (元):199”,正则得写价格\(\元\):(\d+),不然()会被当成分组符号,导致匹配失败。Python 字符串里
\是转义符,正则里的\d需要写成\\d,但加r前缀后r'\d+'就不用转义了,更方便。很多新手忘加r,导致\d变成d,匹配不到数字,一定要注意!结尾心得
Python 正则在爬虫里真的超实用,尤其是遇到不规则网页时,比标签定位靠谱多了。新手入门别贪多,先把
\d \w . * + ? ()这些核心符号练熟,结合实际场景多写案例。兔子哥的经验是,爬一个网站前,先把源码保存到本地,用记事本找内容前后的 “标志性字符”(比如标题前的、价格前的 “¥”),这就是写正则的关键。遇到问题别慌,用在线工具 “regex101” 测试正则,慢慢调试总能解决。记住,正则和爬虫一样,都是 “练会的” 不是 “看会的”,多爬几个网站,你很快就能用正则轻松提取各种数据!标签: 正则表达式 article123.html
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~