正则表达式不是抓取网页的最佳工具但它是理解网页结构最快的方式。掌握正则后你能在不依赖任何第三方库的情况下快速定位和提取页面中的关键信息。一、先搞懂5个核心元字符抓取网页只需要记住这几个符号含义网页场景举例.匹配任意单个字符匹配任意标签内容*匹配前面的字符0次或多次匹配可有可无的属性匹配前面的字符1次或多次匹配必有的内容?匹配前面的字符0次或1次匹配可选的斜杠()分组提取内容提取链接地址量词补充{n,m} 表示匹配n到m次。比如 \d{11} 就是匹配11位数字正好用来匹配手机号。二、匹配HTML标签从最简单的开始HTML标签的基本结构是标签名 属性值内容/标签名。匹配任意HTML标签importre htmldiv classcontentHello/divpWorld/p# 匹配所有标签patternr[^]resultre.findall(pattern,html)print(result)# 输出: [div classcontent, /div, p, /p]解释[^]的意思是匹配除了 之外的一个或多个字符。因为HTML标签的结束标志是 所以这个写法能准确捕获从 开始到 结束的完整标签。匹配指定标签比如只想拿到所有的链接htmla hrefhttps://example.com点击/aa href/about关于/apatternra\shref([^])linksre.findall(pattern,html)print(links)# 输出: [https://example.com, /about]这里用了()括号做分组re.findall会自动返回括号内匹配到的内容也就是链接地址本身而不是整个a标签。三、提取网页内容三个高频场景场景1提取所有图片地址htmlimg src/static/logo.png altlogoimg srcbanner.jpgpatternrimg\s[^]*src([^])imagesre.findall(pattern,html)print(images)# 输出: [/static/logo.png, banner.jpg]注意[^]*用来跳过src前面可能存在的其他属性比如alt、class等这是实战中最容易踩坑的地方。很多教程只写img src但真实网页的属性顺序是不固定的。场景2提取标题和正文htmlh1Python正则表达式教程/h1p这是第一段内容。/pp这是第二段。/ptitlere.search(rh1(.*?)/h1,html).group(1)paragraphsre.findall(rp(.*?)/p,html)print(title)# Python正则表达式教程print(paragraphs)# [这是第一段内容。, 这是第二段。]关键点用.*?而不是.*。?让匹配变成非贪婪模式即遇到第一个/h1就停止而不是一直匹配到最后一个/h1。场景3清洗HTML标签只留文本htmldiv保留这个span还有这个/span/divscript删除这个/script# 移除所有标签textre.sub(r[^],,html)print(text)# 输出: 保留这个还有这个删除这个re.sub是替换函数把所有匹配到的标签替换为空字符串剩下的就是纯文本。四、一个完整的实战抓取豆瓣电影Top250的电影名和评分importre# 假设这是从网页获取到的HTML片段page_html div classitem span classtitle肖申克的救赎/span span classrating_num propertyv:average9.7/span /div div classitem span classtitle霸王别姬/span span classrating_num propertyv:average9.6/span /div # 提取电影名和评分patternrspan classtitle(.*?)/span.*?span classrating_num[^]*(.*?)/spanresultsre.findall(pattern,page_html,re.DOTALL)forname,ratinginresults:print(f{name}:{rating}分)输出肖申克的救赎: 9.7分 霸王别姬: 9.6分re.DOTALL让.可以匹配换行符否则中间的换行会导致匹配失败。这是处理多行HTML时必须加的参数。五、正则的局限性什么时候该放弃它正则能处理简单的HTML提取但遇到以下情况会很痛苦标签嵌套超过2层比如div里面套div再套div属性值里包含引号或特殊字符HTML格式不规范浏览器能渲染但正则匹配不了这些情况下请直接用BeautifulSoup或lxml。正则的定位是快速处理简单场景不是万能解析器。推荐切换时机当你发现正则写到第三层嵌套还匹配不对的时候就是该换工具的时候。六、速查表需求正则表达式匹配任意标签[^]提取a标签链接a\shref([^])提取img的srcimg\s[^]*src([^])提取标签内文本非贪婪tag(.*?)/tag移除所有HTML标签re.sub(r[^], , html)匹配11位手机号1[3-9]\d{9}把这张表存下来够用80%的网页抓取场景。
Python正则表达式入门:从匹配HTML标签到网页内容抓取
正则表达式不是抓取网页的最佳工具但它是理解网页结构最快的方式。掌握正则后你能在不依赖任何第三方库的情况下快速定位和提取页面中的关键信息。一、先搞懂5个核心元字符抓取网页只需要记住这几个符号含义网页场景举例.匹配任意单个字符匹配任意标签内容*匹配前面的字符0次或多次匹配可有可无的属性匹配前面的字符1次或多次匹配必有的内容?匹配前面的字符0次或1次匹配可选的斜杠()分组提取内容提取链接地址量词补充{n,m} 表示匹配n到m次。比如 \d{11} 就是匹配11位数字正好用来匹配手机号。二、匹配HTML标签从最简单的开始HTML标签的基本结构是标签名 属性值内容/标签名。匹配任意HTML标签importre htmldiv classcontentHello/divpWorld/p# 匹配所有标签patternr[^]resultre.findall(pattern,html)print(result)# 输出: [div classcontent, /div, p, /p]解释[^]的意思是匹配除了 之外的一个或多个字符。因为HTML标签的结束标志是 所以这个写法能准确捕获从 开始到 结束的完整标签。匹配指定标签比如只想拿到所有的链接htmla hrefhttps://example.com点击/aa href/about关于/apatternra\shref([^])linksre.findall(pattern,html)print(links)# 输出: [https://example.com, /about]这里用了()括号做分组re.findall会自动返回括号内匹配到的内容也就是链接地址本身而不是整个a标签。三、提取网页内容三个高频场景场景1提取所有图片地址htmlimg src/static/logo.png altlogoimg srcbanner.jpgpatternrimg\s[^]*src([^])imagesre.findall(pattern,html)print(images)# 输出: [/static/logo.png, banner.jpg]注意[^]*用来跳过src前面可能存在的其他属性比如alt、class等这是实战中最容易踩坑的地方。很多教程只写img src但真实网页的属性顺序是不固定的。场景2提取标题和正文htmlh1Python正则表达式教程/h1p这是第一段内容。/pp这是第二段。/ptitlere.search(rh1(.*?)/h1,html).group(1)paragraphsre.findall(rp(.*?)/p,html)print(title)# Python正则表达式教程print(paragraphs)# [这是第一段内容。, 这是第二段。]关键点用.*?而不是.*。?让匹配变成非贪婪模式即遇到第一个/h1就停止而不是一直匹配到最后一个/h1。场景3清洗HTML标签只留文本htmldiv保留这个span还有这个/span/divscript删除这个/script# 移除所有标签textre.sub(r[^],,html)print(text)# 输出: 保留这个还有这个删除这个re.sub是替换函数把所有匹配到的标签替换为空字符串剩下的就是纯文本。四、一个完整的实战抓取豆瓣电影Top250的电影名和评分importre# 假设这是从网页获取到的HTML片段page_html div classitem span classtitle肖申克的救赎/span span classrating_num propertyv:average9.7/span /div div classitem span classtitle霸王别姬/span span classrating_num propertyv:average9.6/span /div # 提取电影名和评分patternrspan classtitle(.*?)/span.*?span classrating_num[^]*(.*?)/spanresultsre.findall(pattern,page_html,re.DOTALL)forname,ratinginresults:print(f{name}:{rating}分)输出肖申克的救赎: 9.7分 霸王别姬: 9.6分re.DOTALL让.可以匹配换行符否则中间的换行会导致匹配失败。这是处理多行HTML时必须加的参数。五、正则的局限性什么时候该放弃它正则能处理简单的HTML提取但遇到以下情况会很痛苦标签嵌套超过2层比如div里面套div再套div属性值里包含引号或特殊字符HTML格式不规范浏览器能渲染但正则匹配不了这些情况下请直接用BeautifulSoup或lxml。正则的定位是快速处理简单场景不是万能解析器。推荐切换时机当你发现正则写到第三层嵌套还匹配不对的时候就是该换工具的时候。六、速查表需求正则表达式匹配任意标签[^]提取a标签链接a\shref([^])提取img的srcimg\s[^]*src([^])提取标签内文本非贪婪tag(.*?)/tag移除所有HTML标签re.sub(r[^], , html)匹配11位手机号1[3-9]\d{9}把这张表存下来够用80%的网页抓取场景。