Python 爬虫项目:正则表达式高阶提取数据
前言在爬虫数据解析场景中除 BeautifulSoup、lxml 等标签解析库外正则表达式是处理非标准文本、混杂字符串、内嵌脚本内容、不规则页面的核心手段。HTML 源码、JS 变量、接口原始报文、富文本内容中大量数据并不规整在标准标签内标签解析工具难以精准提取而正则凭借灵活的字符匹配规则可从杂乱文本中快速定位目标内容。正则适用于三大典型场景HTML 内嵌 JS 变量提取、不规则标签文本截取、批量匹配固定格式字符串、清洗页面冗余内容。本文从正则基础语法、爬虫常用元字符、分组提取、贪婪 / 非贪婪匹配、多行匹配、实战案例、性能优化、避坑要点逐层讲解结合爬虫真实业务代码覆盖单条数据提取、列表数据批量抓取、复杂嵌套内容解析、数据清洗等全场景同时对比标签解析与正则的选型策略形成可直接复用的正则爬虫解决方案。本文使用 Python 内置re模块无需额外安装第三方库全版本 Python 原生支持官方文档参考https://docs.python.org/3/library/re.html一、正则核心基础与爬虫专用语法1.1 re 模块核心常用方法Pythonre模块是正则功能的载体爬虫日常仅需掌握 4 个核心方法区分单次匹配与批量匹配、从头匹配与全局搜索。表格方法作用爬虫使用场景re.search()全文搜索匹配第一个符合规则的内容提取页面唯一数据、单个变量、标题、编号re.findall()全局搜索返回所有匹配结果列表批量提取链接、列表数据、多条变量re.match()仅从字符串开头匹配极少用于爬虫基本不推荐re.sub()正则替换、内容清洗过滤 HTML 标签、删除空白、替换特殊字符爬虫优先级findallsearchsubmatch几乎不用。1.2 爬虫高频元字符精简版无需记忆全部正则语法仅掌握爬虫刚需元字符即可满足 99% 采集需求.匹配任意单个字符默认不匹配换行符*匹配前面字符0 次或多次匹配前面字符1 次或多次至少出现一次?两个作用① 匹配前面字符 0/1 次② 开启非贪婪模式()分组只提取括号内的内容爬虫核心精准截取字段[]字符集匹配括号内任意一个字符[0-9]数字、[a-zA-Z]字母\d等价[0-9]匹配数字\w匹配字母、数字、下划线\s匹配空白符空格、制表符、换行\转义符匹配. * ? ( ) 等特殊符号必须加转义\1.3 贪婪匹配 vs 非贪婪匹配爬虫重中之重贪婪匹配.*.默认尽可能匹配最长内容容易抓取多余文本非贪婪匹配.*?.?尽可能匹配最短内容爬虫首选示例规则 原始文本name张三 age20贪婪name.*→ 匹配整串name张三 age20非贪婪name.*?→ 仅匹配name张三所有爬虫截取字段场景一律使用非贪婪.*?。二、re 模块基础代码实战2.1 re.search 提取单个目标数据用于页面中唯一字段文章标题、发布时间、作者、ID、单个 JS 变量。python运行import re html 发布时间2026-06-12 作者爬虫测试 # 正则规则匹配「发布时间」后面的内容 pattern r发布时间(.*?) result re.search(pattern, html) if result: # 取分组1内容 print(提取时间, result.group(1))原理()划定提取区域.*?非贪婪截取group(1)获取第一个分组数据。2.2 re.findall 批量提取多条数据用于列表页、多条链接、多条标题、数组型数据返回列表。python运行import re html a hrefhttps://a.com/1新闻1/a a hrefhttps://a.com/2新闻2/a a hrefhttps://a.com/3新闻3/a # 提取所有 href 链接 pattern rhref(.*?) url_list re.findall(pattern, html) print(所有链接, url_list)原理findall全局遍历文本自动收集所有分组内容直接得到结果列表。2.3 re.sub 内容清洗与替换用于去除 HTML 标签、清理多余空格、过滤广告文本、替换特殊符号。python运行import re # 原始带标签文本 content div这是正文内容nbsp;nbsp;多余空格/div # 1. 去除所有 HTML 标签 content1 re.sub(r.*?, , content) # 2. 去除连续空白符 content2 re.sub(r\s, , content1) print(content2)三、爬虫高频实战场景行业通用案例3.1 场景一提取 HTML 内嵌 JS 变量最常用现代网页大量数据写在script标签的 JS 变量中BeautifulSoup 难以解析正则是最优方案。案例提取 JS 中的标题、ID、图片地址python运行import re html script var article_id 10086; var title Python正则爬虫实战; var img_url https://test.com/1.jpg; /script # 1. 提取文章ID数字 id_pattern rvar article_id (\d); article_id re.search(id_pattern, html).group(1) print(文章ID, article_id) # 2. 提取标题引号内文本 title_pattern rvar title (.*?); title re.search(title_pattern, html).group(1) print(标题, title) # 3. 提取图片链接 img_pattern rvar img_url (.*?); img_url re.search(img_pattern, html).group(1) print(图片链接, img_url)3.2 场景二批量提取页面所有图片链接适配无规律、混杂在文本、标签中的图片地址统一匹配http/https图片 URL。python运行import re import requests url https://www.example.com headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36} resp requests.get(url, headersheaders) html resp.text # 通用图片链接正则匹配 https/http 开头jpg/png/gif/webp 结尾 img_pattern rhttps?://.*?\.(jpg|png|gif|webp) img_list re.findall(img_pattern, html) # 去重 img_unique list(set(img_list)) print(提取图片数量, len(img_unique))3.3 场景三提取手机号、日期、数字类结构化数据针对页面中固定格式的手机号、身份证、日期、价格、编号等标准化内容。python运行import re text 客服电话13800138000 价格99.9元 日期2026-06-12 # 提取手机号 phone_pat r1[3-9]\d{9} phone re.search(phone_pat, text).group() print(手机号, phone) # 提取价格小数 price_pat r价格(\d\.\d) price re.search(price_pat, text).group(1) print(价格, price) # 提取日期 date_pat r(\d{4}-\d{2}-\d{2}) date re.search(date_pat, text).group(1) print(日期, date)3.4 场景四多行文本匹配跨行内容提取当目标内容跨越多行默认正则无法匹配需添加修饰符re.S让.匹配换行符。python运行import re # 内容跨行 html div classcontent 第一行正文 第二行正文 /div # re.S 开启单行模式. 匹配换行 pattern rdiv classcontent(.*?)/div result re.search(pattern, html, re.S) if result: print(跨行正文, result.group(1).strip())关键参数re.S爬虫跨行匹配必备。3.5 场景五多分组同时提取多条字段一条正则设置多个分组一次性提取多个关联字段标题 链接 时间。python运行import re html li标题1 a hrefurl12026-06-12/a/li li标题2 a hrefurl22026-06-11/a/li # 三个分组标题、链接、时间 pattern rli(.*?) a href(.*?)(.*?)/a/li data_list re.findall(pattern, html) for title, url, time in data_list: print(f标题{title} 链接{url} 时间{time})findall遇到多分组每一条结果为元组按分组顺序取值。四、正则表达式编写流程爬虫标准步骤新手编写正则容易出错遵循固定流程可大幅降低失误率复制目标原始文本从网页源码、抓包内容复制完整片段定位前后固定特征找到目标内容左侧固定字符串、右侧固定字符串中间使用(.*?)包裹左右特征 (.*?)组成完整规则特殊符号转义. ( ) * ?前面加\判断是否跨行跨行则添加re.S优先使用 findall/search测试结果是否正常通用模板左侧固定文本(.*?)右侧固定文本五、正则与 BeautifulSoup 选型对比工程化选择两种解析方式各有优劣根据页面结构选择不要盲目只用一种表格场景推荐方案原因标准 HTML 标签、结构规整BeautifulSoup / lxml语法简单、可读性强、容错高、易维护JS 变量、内嵌脚本、无标签文本正则表达式标签解析器无法解析 JS正则效率最高不规则页面、标签混乱、标签缺失正则表达式标签错乱导致解析器定位失败纯文本、日志、接口原始报文正则表达式无 HTML 结构只能用正则数据清洗、过滤标签、删冗余内容re.sub专门做替换清洗最佳实践标签规整用解析库内嵌 JS / 不规则文本用正则两者组合使用。六、正则爬虫高频错误与排错方案6.1 匹配结果为空最常见原因 1左右特征文本复制错误、空格 / 换行不一致 解决严格对照源码保留原始空格、符号原因 2内容跨行未加re.S解决匹配参数追加re.S原因 3特殊符号未转义. ( ) 解决特殊符号前加\6.2 匹配内容过长抓取到多余文本原因使用贪婪.*未加?解决统一改为非贪婪.*?6.3 分组取值报错AttributeError原因search未匹配到内容直接调用group()解决先判断if result:再取值6.4 中文乱码 / 空白过多原因源码编码问题、匹配到大量\s解决请求页面后统一resp.encodingutf-8配合re.sub(r\s, )清理空白七、综合实战完整正则采集案例结合请求、正则提取、数据整理实现一套完整可运行爬虫python运行import re import requests class ReCrawlSpider: def __init__(self): self.headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def get_html(self, url): 请求页面 resp requests.get(url, headersself.headers, timeout10) resp.encoding utf-8 return resp.text def extract_data(self, html): 正则批量提取数据 # 规则提取标题、链接、发布时间 pattern rdiv classitem标题(.*?)a href(.*?)发布时间(.*?)/a/div result re.findall(pattern, html, re.S) return result def run(self, target_url): html self.get_html(target_url) data self.extract_data(html) for idx, (title, link, pub_time) in enumerate(data, 1): print(f第{idx}条 | 标题{title} | 链接{link} | 时间{pub_time}) if __name__ __main__: spider ReCrawlSpider() spider.run(https://www.example.com/list)八、总结与拓展方向正则表达式是爬虫解析体系里补充性核心能力和标签解析库形成互补。核心要点总结爬虫只需要掌握search、findall、sub三个方法优先使用非贪婪.*?跨行内容必须添加re.S修饰符特殊符号记得转义标准 HTML 用解析库JS 变量、不规则文本、纯文本用正则编写正则遵循「左右固定特征 中间分组」模板降低出错概率拓展学习方向正则预编译re.compile()批量多次匹配场景提升运行速度复杂嵌套内容、JSON 片段截取正则结合解析库混合解析打造高容错爬虫正则过滤敏感词、数据脱敏等衍生用法掌握正则后面对结构混乱、JS 渲染前置的页面解析能力会大幅提升能够覆盖绝大多数常规静态页面解析场景。