用 Python 写爬虫的新手是不是总在正则匹配上栽跟头?明明网页里有想要的内容,正则写了半天就是匹配不到;好不容易匹配到了,结果把无关内容也一起抓了进来;更头疼的是,同样的正则在在线工具里能用,放到 Python 代码里就报错,反复检查也找不到原因。别着急,兔子哥第一次用正则爬网页时,就因为没处理好 Python 的转义字符,对着 “\d” 匹配数字却总返回空结果,后来才发现要写成 “\d” 才行;还有一次爬商品价格,正则没控制贪婪模式,结果把 “¥99.90 包邮” 匹配成了 “¥99.90 包邮 ¥199.00”,多抓了一堆没用的内容。今天就带大家把 Python 正则的语法速查、爬虫实战案例和避坑技巧讲透,新手跟着学,爬虫匹配再也不踩坑,一起往下看吧!
一、Python 正则基础:re 模块必学 4 个函数,爬虫匹配全靠它
基础问题:Python 里用正则要先学啥?和普通正则有区别吗?
Python 里用正则得靠内置的
re模块,虽然核心语法和通用正则一样,但函数用法和转义处理有自己的特点。新手只要先掌握 4 个核心函数,爬虫匹配基本就够用了。re 模块核心函数,按场景选着用
- re.findall(pattern, string):找所有匹配的内容,返回列表
比如从网页文本里提取所有手机号,用这个函数最方便,返回的列表里会包含所有符合规则的号码。
示例:re.findall(r'\d{11}', '手机号1:13812345678,手机号2:13987654321'),结果是['13812345678', '13987654321']。 - re.search(pattern, string):找第一个匹配的内容,返回匹配对象
适合只要第一个结果的场景,比如爬取网页标题,找到第一个标签里的内容就够了。需要用.group()提取内容,没找到返回None。
示例:result = re.search(r'。(.*?) ', html_text); print(result.group(1)) - re.compile(pattern):编译正则表达式,重复使用更高效
爬大量页面时,先编译正则能节省时间,不用每次匹配都解析一次规则。
示例:pattern = re.compile(r'\w+@\w+\.\w+'); emails = pattern.findall(html_text)。 - re.sub(pattern, repl, string):替换匹配的内容,清洗数据用
爬取后的数据常有多余字符(比如空格、换行),用这个函数替换掉,示例:re.sub(r'\s+', ' ', 'hello world \npython'),结果是'hello world python'。
网友 “爬虫新手小张” 分享:“之前不知道
re.compile,爬 100 页网页每次都写一遍正则,速度特别慢,后来用编译后再匹配,速度快了一倍多,原来效率差距这么大!”二、语法速查:爬虫常用正则符号,一张表搞定
场景问题:记不住那么多符号?爬虫常用的就这几个
正则符号虽多,但爬虫里常用的也就十几个,记好这张表,遇到问题对着查就行。
| 符号 / 语法 | 作用 | 爬虫常用场景 | 示例 |
|---|---|---|---|
. | 匹配任意字符(除换行) | 模糊匹配未知字符 | a.b匹配acb、a1b |
\d | 匹配数字 | 提取手机号、价格 | \d{11}匹配 11 位手机号 |
\w | 匹配字母、数字、下划线 | 提取用户名、ID | user_\w+匹配user_123、user_admin |
* | 前面字符出现 0 次或多次 | 匹配可变长度内容 | ab*c匹配ac、abc、abbc |
+ | 前面字符出现 1 次或多次 | 匹配至少有一个的内容 | \d+匹配123、45 |
? | 非贪婪模式(默认贪婪) | 避免过度匹配 | (.*?)只匹配第一个前的内容 |
[] | 匹配括号内任意一个字符 | 限定字符范围 | [a-zA-Z0-9]匹配字母或数字 |
() | 分组提取 | 提取标签内的内容 | 提取标题文本 |
^ $ | 开头 / 结尾匹配 | 验证完整格式 | ^https://匹配以 https 开头的链接 |
兔子哥提醒:Python 里写正则要在字符串前加
r(原始字符串),比如r'\d{11}',这样不用额外转义反斜杠,不然得写成'\\d{11}',很容易出错。三、爬虫实战案例:3 个场景手把手教,从正则到代码
案例 1:爬取网页中的所有链接()
步骤:
- 分析链接格式:网页里的链接通常在
里,xxx就是要提取的链接。 - 写正则规则:用分组提取
href="和"之间的内容,规则是r'(?是非贪婪模式,避免匹配到多个链接)。 - Python 代码实现:
python
import reimport requests# 获取网页内容html = requests.get('https://www.example.com').text# 提取所有链接links = re.findall(r', html)# 打印结果for link in links[:5]: # 打印前5个链接print(link)案例 2:提取商品价格(格式:¥xx.xx 或 ¥xxx)
步骤:
- 分析价格格式:常见价格是
¥开头,后面跟数字和可能的小数点,比如¥99.90、¥199。 - 写正则规则:
r'¥(\d+\.?\d*)'(\d+匹配整数部分,\.?匹配可能的小数点,\d*匹配小数部分)。 - 代码实现:
python
import rehtml_text = '商品1:¥99.90,商品2:¥199,商品3:¥299.50'prices = re.findall(r'¥(\d+\.?\d*)', html_text)print(prices) # 结果:['99.90', '199', '299.50']案例 3:清洗爬取的文本,去除多余空格和换行
步骤:
- 问题:爬取的文本常有多个空格、换行符,比如
' 标题:Python正则 \n 作者:兔子哥 '。 - 正则规则:用
\s+匹配任意空白字符(空格、换行),替换成单个空格。 - 代码实现:
python
import redirty_text = ' 标题:Python正则 \n 作者:兔子哥 'clean_text = re.sub(r'\s+', ' ', dirty_text).strip() # strip()去除首尾空格print(clean_text) # 结果:'标题:Python正则 作者:兔子哥'四、避坑指南:爬虫正则最容易踩的 5 个坑,提前避开
- 忘记加
r前缀,转义字符失效
写成'\d{11}'而不是r'\d{11}',Python 会把\d当成转义字符,导致匹配失败。解决:永远在正则字符串前加r,比如r'\d{11}'。 - 贪婪模式导致过度匹配
用r'(.*)'匹配链接,结果把整个网页的到最后一个都匹配了。解决:在*后面加?启用非贪婪模式,r'(.*?)'。 - 忽略网页大小写问题
网页标签可能有大写(比如),正则r'匹配不到。解决:加re.IGNORECASE参数,re.findall(r'。 - 没考虑换行符,跨多行匹配失败
目标内容跨多行时(比如\n 内容 \n),.不匹配换行,导致匹配失败。解决:加re.DOTALL参数,让.匹配换行,re.search(r'(.*?)', html, re.DOTALL)。 - 正则太复杂,不如用解析库
复杂网页(比如嵌套标签多的 HTML)用正则很难精准匹配,还容易出错。解决:简单内容用正则,复杂结构用 BeautifulSoup、lxml 等解析库,两者结合效率更高。
网友 “数据分析小王” 分享:“之前爬取嵌套的 JSON 数据,用正则写了半天规则还是匹配错,后来发现用
json模块直接解析更简单,原来正则不是万能的!”五、自问自答:Python 正则爬虫常问的问题
“正则和 BeautifulSoup 哪个更好用?什么时候该用正则?”
没有绝对好坏!简单场景(提取手机号、价格、单标签内容)用正则更快;复杂场景(嵌套标签、动态加载内容)用 BeautifulSoup 更省心,它能直接定位标签,不用写复杂正则。新手可以两者结合,各取所长。
“爬取大量数据时,正则会不会很慢?怎么优化?”
正则本身很快,但频繁解析规则会耗时。优化方法:用
re.compile提前编译正则;尽量简化规则,避免过度复杂的匹配;数据量极大时,考虑先过滤文本再匹配(比如先提取标签内的内容,再在小范围内匹配)。“在线正则工具测试通过,Python 里却匹配不到,为啥?”
最常见原因是转义问题!在线工具里的
\d在 Python 里要写成r'\d',否则\会被转义;另外注意是否有换行符影响,在线工具可能默认忽略换行,Python 里需要加re.DOTALL参数。结尾心得
Python 正则在爬虫里是 “利器”,但用不好就成 “坑器”。兔子哥的经验是,新手别一开始就写复杂正则,从简单的提取手机号、链接练起,熟练后再挑战复杂场景;遇到匹配失败,先检查是否加了
r前缀、有没有启用非贪婪模式、参数是否正确(比如忽略大小写)。正则和解析库不是对立的,该用正则时别犹豫,该用解析库时别硬扛。多爬几个网页练手,把常见坑踩一遍,你会发现正则匹配越来越顺手,爬虫效率也会提高一大截。记住,工具是死的,人是活的,灵活运用才是王道,加油!标签: 正则表达式 pattern.findall
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~