Regular Expression正则表达式

作者:落寞红颜玉玫瑰

本文使用软件及版本:python 3.11

更多 re 信息请查看官方文档:https://docs.python.org/3/library/re.html

本文使用素材:王者荣耀英雄信息获取,网址https://pvp.qq.com/web201605/herolist.shtml

正则表达式:是用来简洁表达一组字符串的表达式

操作符


操作符说明示例
.除换行符外任意单个字符任意单个字符
[ ]单字符取值集合[abc] 表示a或b或c
[^ ]排除所列字符集合[^abc] 表示取值不能是a,b,c
^匹配字符串开头^a 字符串·需要以a开头
$匹配字符串结尾a$ 字符串·需要以a结尾
*重复前面字符0次或n次abd* 重复"d" 0次或者n次
+重复前面字符1次或n次abd+ 重复"d" 1次或者n次
?重复前面字符0次或1次abd? 重复"d" 0次或者1次,结果为 ”ab“ 或 "abd"
|匹配左边字符集或者右边字符集 abc | def 表示 abc 或者 def
{m,n}重复前面字符n次到m次 abc{1,3} 表示abc或abcc或abccc
\d表示数字0-9任意一个,等价于[0-9]\d{1,3} 可以是1,12,123,155等
\w单词字符(包含下划线),等价于[a-zA-Z0-9_]\w* 可以是”“,”A“,"a3"等

匹配中文字符:[\u4e00-\u9fa5],上表有些操作符没有列出来,后面用到会介绍。


贪婪匹配与非贪婪匹配


re 中默认匹配模式是贪婪匹配,即尽可能多的匹配字符。

贪婪非贪婪举例说明
**?a[c]*?贪婪匹配:匹配尽可能多的c; 非贪婪匹配:尽可能匹配少的c
++?a[c]+?
???a[c]??
{m,n}{m,n}?a[c]{1,3}?
贪婪匹配
match_str="acccccccc"

result=re.search("a[c]*",match_str)

if result:
    
    print(result.group(0))
#贪婪匹配下输出结果为:acccccccc
非贪婪匹配
match_str="acccccccc"

result=re.search("a[c]*?",match_str)

if result:
    
    print(result.group(0))
#非贪婪匹配下输出结果为:a

下面来提取王者英雄名称,网页链接,及图片

因为只需要获取一次网站数据,加上需要熟悉正则表达式,所以我们选择用 requests 库和 re 库。

导入需要用到的模块

import os
import re
import requests

import openpyxl
url="https://pvp.qq.com/web201605/herolist.shtml"

r=requests.get(url)

r.encoding=r.apparent_encoding #gbk

if r.status_code == 200:
    
    print(r.text[:2000])

else:

    print("未获取到网页")

获取到的网页文本如下:

王者荣耀英雄页

<li><a href="herodetail/506.shtml" target="_blank"><img src="//game.gtimg.cn/images/yxzj/img201606/heroimg/506/506.jpg" width="91" height="91" alt="云中君">云中君</a></li>

根据上面提取的一条英雄信息,写正则表达式:

  match_str=r.text
  
    #英雄链接提取正则表达式
    hero_str=r'<li><a href="(herodetail/(\d{3}).shtml)"'
    
    hero_match=re.compile(hero_str)
    
    #找到所有英雄链接网址
    result=hero_match.finditer(match_str)
    
    if result:
    
        for match in result:
        
            print(match.group(1))

注:观察到英雄图片和英雄链接有同一个id,可以直接拼接英雄图片链接。

image_url="https://game.gtimg.cn/images/yxzj/img201606/heroimg/{0}/{0}.jpg".format(match.group(2))

用同样方法,写出抓取英雄名字的正则表达式:
这里用到了非贪婪匹配 “.*?” ,我们需要得到每一条<li>,所以要尽可能少的匹配中间的字符,如果是贪婪匹配,则得到是整个<ul>,因为其对应关系如下:
<ul>
<li></li>
<li></li>
<li></li>
</ul>
一个<ul>中包含多个<li>,贪婪匹配就会选中整个<ul>。
“[\u4e00-\u9fa5]{1,5}” 用来定位英雄名字,英雄名字为汉字,长度在1-5个字之间。

 match_str=r.text
    
    #英雄名字提取正则表达式,
    hero_name_str=r'<li><a .*?([\u4e00-\u9fa5]{1,5})</a></li>'
    
	#因为字符串中有换行符“\n”,所以加入re.S
    hero_name_match=re.compile(hero_name_str,re.S)
    
    #找到所有英雄链接网址
    result=hero_match.finditer(match_str)
    
    if result:
    
        for match in result:
        
            print(match.group(1))

整合两个正则表达式,最后的结果如下:

url="https://pvp.qq.com/web201605/herolist.shtml"

r=requests.get(url)

r.encoding=r.apparent_encoding #gbk

if r.status_code == 200:

    match_str="".join(r.text)

    print(match_str)

    hero_extract=r'<li><a href="(herodetail/(\d{3}).shtml)".*?([\u4e00-\u9fa5]{1,5})</a></li>'

    hero_extract_pat=re.compile(hero_extract,re.S)
    
    result=hero_extract_pat.finditer(match_str)

    if result:

        wb=gen_wb()

        ws=wb["hero_info"]

        start_row=2

        ws.cell(1,1).value="hero_name"
        ws.cell(1,2).value="hero_url"
        ws.cell(1,3).value="hero_image_url"
        
		#re.finditer 返回的是迭代的 match 对象,可以遍历输出,关于 match 对象,下篇文章会介绍。
        for match in result:

            ws.cell(start_row,2).value="https://pvp.qq.com/web201605/"+match.group(1)
    
            ws.cell(start_row,3).value="https://game.gtimg.cn/images/yxzj/img201606/heroimg/{0}/{0}.jpg".format(match.group(2))

            ws.cell(start_row,1).value=match.group(3)

            print(start_row)

            start_row += 1

        wb.save(save_path)
            
    print("英雄信息抓取下载完毕,下载路径:{}".format(save_path))

else:

    print("未获取到网页")

创建写入Excel函数:

def gen_wb():

    os.chdir("../Desktop")

    global save_path

    save_path=os.getcwd()+"\hero_info.xlsx"

    if os.path.exists(save_path):

        os.remove(save_path)

    wb=openpyxl.Workbook()

    ws=wb.create_sheet("hero_info",0)

    wb.save(save_path)

    return openpyxl.load_workbook(save_path)
   

成功抓取到信息:
抓取下载成功
验证结果:文件对应正确。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落寞红颜玉玫瑰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值