Regular Expression, 正则表达式, 种使 表达式的 式对字符串进 匹配的语法规则。 我们抓取到的 源代码本质上就是 个超 的字符串, 想从 提取内容。 正则再合适不过了。 正则的优点: 速度快, 效率 , 准确性 正则的缺点: 新 上 难度有点 。 不过只要掌握了正则编写的逻辑关系, 写出 个提取 内容的正则其实并不复杂 正则的语法: 使 元字符进 排列组合 来匹配字符串 在线测试正则表达式网址: https://tool.oschina.net/regex/ 元字符: 具有固定含义的特殊符号 常 元字符: . 匹配除换 符以外的任意字符 w 匹配字 或数字或下划线 s 匹配任意的空 符 d 匹配数字 匹配 个换 符 匹配 个制表符 ^ 匹配字符串的开始 $ 匹配字符串的结尾 W 匹配 字 或数字或下划线 D 匹配 数字 S 匹配 空 符 a|b 匹配字符a或字符b () 匹配括号内的表达式,也表示 个组 [...] 匹配字符组中的字符 [^...] 匹配除了字符组中字符的所有字符 量词: 控制前 的元字符出现的次数 * 重复零次或更多次 + 重复 次或更多次 ? 重复零次或 次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次 贪婪匹配和惰性匹配 .* 贪婪匹配 .*? 惰性匹配 这两个要着重的说 下,因为我们写爬 的最多的就是这个惰性匹配。 先看案例 str: 玩 吃鸡游戏, 晚上 起上游戏, 嘛呢? 打游戏啊 reg: 玩 .*?游戏 此时匹配的是: 玩 吃鸡游戏 reg: 玩 .*游戏 此时匹配的是: 玩 吃鸡游戏, 晚上 起上游戏, 嘛呢? 打游戏 str: 胡辣汤 reg: <.*> 结果: 胡辣汤 str: 胡辣汤 reg: <.*?> 结果: str: 胡辣汤饭团 reg: .*? 结果: 胡辣汤 那么接下来的问题是, 正则我会写了, 怎么在python程序中使 正则呢?答案是re模块 re模块中我们只需要记住这么 个功能就 够我们使 了。 1. findall 查找所有,返回listimport re lst = re.findall("m"," mai le for len,mai ni mei!") print(lst) # ["m", "m", "m"] lst = re.findall(r"d+","5点之前. 你要给我5000万") print(lst) # ["5", "5000"] 匹配5开头的所有的数字2. search 会进 匹配, 但是如果匹配到了第 个结果,就会返回这个结果。如果匹配不上search返回的则是Noneret = re.search(r"d","5点之前. 你要给我5000万").group() print(ret) #匹配结果为 53. match 只能从字符串的开头进 匹配ret = re.match("a","abc").group() print(ret) #结果为a,如果为babc 报错4. finditer, 和findall差不多. 只不过这时返回的是迭代器(重点)it = re.finditer("m"," mai le for len,mai ni mei!") for el in it: print(el.group()) # 不分组则返回迭代器5. compile() 可以将 个 的正则进 预加载. 便后 的使 # 将正则表达式编译成为 个正则表达式对象, 规则要匹配的是3个数字 obj = re.compile(r"d{3}") # 正则表达式对象调 search, 参数为待匹配的字符串 ret = obj.search("abc123eeee") print(ret.group()) # 结果: 1236. 正则中的内容如何单独提取?这 可以看到我们可以通过使 分组。来对正则匹配到的内容进 步的进 筛选。s = """ 中国联通 """ obj = re.compile(r"d+)">(?Pw+) ",re.S) obj = re.compile(r"d+)">(?Pw+) ",re.S) # ?P的意思就是命名一个名字为value的组,匹配规则符合后面的/d+ # 如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。 # 而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。 result = obj.search(s) # print(result.group()) print(result.group()) print(result.group("id")) print(result.group("name"))7.正式练习 下面一个案例,是练习用正则表达式提取豆瓣电影top250的数据并保存,一起来学一下吧。 # 拿到页面源代码. requests # 通过re来提取想要的有效信息 re import requests import re import csv url = "https://movie.douban.com/top250" headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36" } resp = requests.get(url, headers=headers) page_content = resp.text # 解析数据 obj = re.compile(r" .*?.*?(?P .*?)" r" .*?.*? (?P
.*?) .*?(?P .*?) .*?" r"(?P.*?)人评价 ", re.S) # 开始匹配 result = obj.finditer(page_content) f = open("data.csv", mode="w") csvwriter = csv.writer(f) for it in result: # print(it.group("name")) # print(it.group("score")) # print(it.group("num")) # print(it.group("year").strip()) dic = it.groupdict() dic["year"] = dic["year"].strip() csvwriter.writerow(dic.values()) f.close() print("over!")