Python 爬虫项目实战:正则表达式筛选网页数字与标题字段 前言在爬虫数据解析体系中BeautifulSoup、XPath 依托 DOM 树形结构完成内容定位二者高度依赖 HTML 标签完整性一旦网页标签被混淆嵌套、前端页面采用无规范碎片化代码排版DOM 解析方案会出现大范围解析失效。正则表达式基于文本字符串的规律匹配逻辑脱离标签层级束缚依靠字符排布特征完成标题、数值类字段的精准捕获在混杂脚本、破碎标签的网页环境中具备不可替代的适配能力。数字与标题是网页最普遍的结构化字段标题拥有固定首尾字符边界价格、浏览量、排名、发布年份等数字字段具备阿拉伯数字、小数、正负值等统一字符特征二者恰好是正则爬虫最典型的落地场景。本文从正则底层匹配原理、元字符语法分类、Python 内置 re 库 API、标题模糊捕获、多格式数字筛选、脏数据剔除、本地文件存储全链路展开实战教学串联前文 requests 网页源码获取逻辑构建「请求获取源码 正则规则匹配 字段清洗 落地存储」完整爬虫工程。本文涉及依赖官方参考链接Python re 模块官方文档Python 内置正则库原生 API 说明requests 官方文档HTTP 请求依赖库文档PyPI-requests安装包资源地址一、环境配置与 re 模块基础概述1.1 环境依赖说明re 属于 Python 标准内置库随 Python 解释器原生安装无需额外 pip 安装仅需保留 requests 用于网页源码拉取若此前未安装 requests执行安装命令bash运行pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple通过import re导入即可调用全部正则接口是爬虫成本最低的解析组件。1.2 正则爬虫适用与受限场景正则依靠文本字符规律匹配在两类场景优先级高于 DOM 解析工具网页 HTML 标签残缺严重、标签被 JS 碎片化拼接BS 与 XPath 无法构建完整 DOM 树仅需提取零散数字、短标题等碎片化字段完整构建 DOM 树资源开销过大。受限场景页面字段排布无统一字符规律、字段穿插随机无规则符号正则编写成本会远超标签解析。二、正则核心元字符与匹配规则汇总元字符是正则表达式的语法基础不同符号对应不同字符匹配逻辑爬虫抓取标题、数字高频元字符整理如下表表格元字符功能释义爬虫使用场景.匹配除换行符之外任意单个字符标题中间不定长度文本匹配*匹配前一个字符出现 0 次或无限次字段首尾冗余字符不定长内容匹配前一个字符出现 1 次或无限次连续数字、连续标题文本捕获?非贪婪匹配尽可能少抓取字符限定标题终止边界避免跨字段抓取\d匹配任意阿拉伯数字 0~9浏览量、价格、排名、年份等数字提取\D匹配非数字字符剔除混杂在数字中的中文、符号()分组捕获括号内内容单独提取精准取出目标标题、目标数字[]字符集匹配括号内任意单个字符匹配中英文标点、特殊分隔符号或逻辑匹配左右任意一种表达式兼容两种格式标题与数字写法\s匹配空白字符空格、换行、制表符清洗标题字段多余空白占位符2.1 贪婪与非贪婪匹配核心原理爬虫开发中非贪婪匹配是标题提取关键默认.*为贪婪匹配会从第一个起始标识抓取至页面最后一个结束标识造成跨内容抓取.*?非贪婪匹配匹配到首个结束标识即终止抓取。python运行import re html h3星际宇宙科普/h3h3深海生物探秘/h3 # 贪婪匹配 res_greed re.findall(rh3(.*)/h3,html) # 非贪婪匹配 res_nogreed re.findall(rh3(.*?)/h3,html) print(贪婪结果,res_greed) print(非贪婪结果,res_nogreed)代码原理剖析贪婪表达式仅返回一条数据将两个标题合并为单字符串匹配逻辑失效.*?非贪婪逐个闭合标签逐条拆分两条标题是标题正则标准写法。三、re 库四大核心爬虫方法详解Python re 模块提供四类高频接口分别适配单次匹配、批量全量匹配、内容替换、预编译规则对应不同爬虫字段提取需求表格方法名返回数据使用场景re.search()单个匹配对象匹配首个符合规则内容单标题、单数值定点提取re.findall()列表格式所有匹配分组内容批量提取全页标题、批量数字爬虫最常用re.sub()替换完成后的完整字符串标题字段脏符号、冗余标签清洗re.compile()正则规则编译对象重复调用同一规则海量页面抓取优化效率3.1 re.findall 分组捕获实战标题提取基础findall 遇到表达式内()分组时仅返回分组内部捕获内容外围匹配规则仅做边界限定是爬虫精准提取字段的核心机制python运行import re raw_html div classnews span classtitle【天文科普】银河系星云演化规律/spanspan浏览1256/span span classtitle【地理科普】板块漂移学说详解/spanspan浏览3689/span /div # 括号分组捕获标题正文前后标签作为匹配边界 pattern rspan classtitle(.*?)/span title_list re.findall(pattern,raw_html) print(批量提取标题,title_list)代码原理剖析表达式外层span classtitle和/span用于锁定标题起止边界(.*?)分组单独存储标题文本findall 自动过滤边界标签仅输出分组内数据。3.2 re.compile 预编译优化同一正则规则循环多页面抓取时compile 提前编译正则表达式避免循环内重复编译消耗算力python运行import re # 预编译正则规则 title_pat re.compile(rspan classtitle(.*?)/span) html_list [raw_html,raw_html,raw_html] all_title [] for html in html_list: all_title.extend(title_pat.findall(html))原理剖析compile 将正则字符串转为编译对象循环调用直接复用编译结果海量分页爬虫场景有效缩短解析耗时。3.3 re.sub 脏数据清洗网页标题常混杂多余 HTML 标签、特殊符号sub 方法实现字符替换清洗python运行raw_title b【生物科普】nbsp;昆虫变态发育全解析/b # 清除所有标签与空格占位符 clean_title re.sub(r.*?|nbsp;,,raw_title) print(clean_title)四、分场景实战一各类标题字段正则筛选网页标题分为带固定前后缀标题、无固定标签零散标题两种场景分别对应两套正则方案。4.1 带固定首尾标签的标题批量抓取沿用 requests 获取在线页面源码结合正则批量提取栏目标题python运行import requests,re HEADERS {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36} def get_page_html(url): try: resp requests.get(url,headersHEADERS,timeout5) resp.encoding resp.apparent_encoding return resp.text except: return def extract_title(html): # 预编译标题正则 pat re.compile(rh2 classart_title(.*?)/h2) title_arr pat.findall(html) # 标题基础清洗 clean_arr [re.sub(r\s,,i) for i in title_arr] return clean_arr if __name__ __main__: page_html get_page_html(https://demo-kepu.com/list) res_title extract_title(page_html) print(提取有效标题数量,len(res_title))代码原理剖析re.sub(r\s,,i)统一清除标题内部各类空白字符标准化标题格式函数拆分请求与解析逻辑代码解耦便于后续批量分页调用。4.2 无固定标签、依靠关键词边界的标题捕获部分页面标题无统一包裹标签仅统一带有【科普】关键词前缀依靠关键词做匹配边界python运行raw_text 随机文本111【科普】火山喷发的地质成因随机字符222【科普】极地冰川融化研究多余符号 pat r【科普】(.*?)随机 title_list re.findall(pat,raw_text)五、分场景实战二多格式数字正则筛选网页数字分为整数浏览量、评论数、小数评分、价格、带单位混合数字589 次、9.6 分三类分规格编写正则表达式。5.1 纯整数提取浏览量、点击量使用\d匹配连续多位阿拉伯数字适用于全整数类字段python运行import re content 文章1浏览3562次文章2浏览1289次文章3浏览96次 num_list re.findall(r(\d),content) # 字符串转数字 num_int [int(x) for x in num_list] print(num_int)5.2 小数 整数混合提取科普文章评分正则\d\.?\d*兼容整数、一位小数、多位小数三种格式适配评分字段python运行score_text 文章评分9.5、8、9.75、7.2 score_list re.findall(r(\d\.?\d*),score_text)5.3 带中文单位的数字剥离数字和汉字绑定325 阅读、12.9 元分组单独取出数字部分python运行unit_str 325阅读量9.8分评分68收藏 num_pat re.findall(r(\d\.?\d)[阅读收藏分],unit_str)5.4 标题 数字联动提取单条数据封装页面单条目同时包含标题与对应浏览数字一条正则双分组同步抓取两个字段python运行html_frag p宇宙星云探究 | 阅读1563/p p热带雨林生态 | 阅读2891/p # 第一分组标题第二分组浏览数字 res re.findall(rp(.*?)\|阅读(\d)/p,html_frag) data_dict [{标题:k,浏览量:int(v)} for k,v in res] print(data_dict)原理剖析正则设置两组()分组findall 会以元组形式返回每组捕获内容一键完成标题、数字配对省去二次字段关联操作。六、完整项目正则爬虫全流程请求 - 正则提取 - 清洗 - TXT/CSV 存储整合全模块实现从网页拉取、标题 数字联合提取、脏数据清洗、本地双格式存储一体化项目代码python运行import requests,re,csv HEADERS { User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36 } # 1.网页请求函数 def fetch_html(url): try: res requests.get(url,headersHEADERS,timeout6) res.encoding res.apparent_encoding return res.text except Exception as e: print(f请求异常:{e}) return # 2.正则提取数据清洗函数 def parse_by_re(html): # 预编译正则同时捕获标题、阅读数字 rule re.compile(rdiv classitem_title(.*?)/div.*?阅读(\d),re.S) raw_data rule.findall(html) clean_data [] for title,view in raw_data: # 清洗标题剔除标签、空白、特殊符号 clear_title re.sub(r.*?|\s|nbsp;,,title).strip() view_num int(view) clean_data.append({文章标题:clear_title,浏览数量:view_num}) return clean_data # 3.数据存储函数 def save_data(data_list): # CSV结构化存储 with open(科普标题数字汇总.csv,w,encodingutf-8-sig,newline) as f_csv: writer csv.DictWriter(f_csv,fieldnames[文章标题,浏览数量]) writer.writeheader() writer.writerows(data_list) # TXT备份存储 with open(科普数据备份.txt,w,encodingutf-8) as f_txt: f_txt.write(文章标题|浏览数量\n-*50\n) for item in data_list: f_txt.write(f{item[文章标题]}|{item[浏览数量]}\n) print(数据已保存至本地CSV与TXT文件) # 主程序入口 if __name__ __main__: target_url https://demo-kepu.com/regex_list page_html fetch_html(target_url) final_data parse_by_re(page_html) save_data(final_data) print(f本次采集有效数据条数{len(final_data)})代码原理剖析re.S参数使.符号匹配换行符适配标题跨换行排布的页面分函数模块化开发请求、解析、存储相互独立便于后续扩展分页循环标题使用多级替换规则一次性剔除 HTML 标签、空格、占位符三类脏数据。七、分页批量正则爬虫拓展实现多数资讯站点分页展示数据通过页码参数循环请求批量全栏目采集python运行import time def crawl_multi_page(start,end,base_url): all_info [] for page in range(start,end1): real_url base_url.format(pagepage) print(f正在抓取第{page}页{real_url}) html fetch_html(real_url) page_data parse_by_re(html) if not page_data: print(当前页面无数据终止分页抓取) break all_info.extend(page_data) time.sleep(1) save_data(all_info) print(f全部分页抓取完成累计采集{len(all_info)}条数据) # 调用 if __name__ __main__: base https://demo-kepu.com/regex?page{page} crawl_multi_page(1,4,base)八、正则爬虫高频异常与排错方案表格异常问题形成原因处理方案匹配结果为空列表正则边界写错、贪婪匹配、页面源码编码错乱切换非贪婪.*?、核对前后匹配标识、使用 apparent_encoding 修正编码字段混入多余符号页面标题内嵌随机特殊字符re.sub 批量替换指定无用字符数字无法转 int提取的数字混杂中文符号优化正则仅分组捕获纯数字内容跨条目抓取多条内容未使用非贪婪匹配全部标题正则统一替换.为.?九、正则、BS、XPath 三种解析技术选型对比结合标题与数字抓取场景做选型参考表格解析方式开发难度解析速度适用场景正则中等需要熟记元字符最快纯文本检索标签破碎、零散数字标题提取BeautifulSoup简单语法贴近 Python中等标签规整少量字段抓取XPath中等路径语法记忆较快标签规范大批量列表结构化数据十、本章节总结与下一章节预告10.1 本章核心知识点总结正则核心元字符含义、贪婪 / 非贪婪匹配区别与爬虫使用规范re 四大常用函数 findall/search/sub/compile 的工程落地用法分组捕获是字段提取关键标题、整数、小数、带单位数字四类场景正则编写思路正则爬虫全链路封装、分页批量采集与本地文件存储实现。10.2 下一章节内容预告下一章节进入 urllib 请求封装与网页编码异常处理梳理 Python 原生 urllib 标准库架构对比 requests 与 urllib 底层差异系统化解决网页 gbk、gb2312、utf-8 多编码乱码、请求头封装、异常捕获等底层问题补齐 Python 爬虫原生请求技术栈。