Python的正则表达式和爬虫
1、常用元字符
. 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串的开始 $ 匹配字符串的结束
2、常用限定符(量词)
* 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次
3、常用反义词
\W 匹配任意不是字母,数字,下划线,汉字的字符 \S 匹配任意不是空白符的字符 \D 匹配任意非数字的字符 \B 匹配不是单词开头或结束的位置 [^x] 匹配除了x以外的任意字符 [^aeiou] 匹配除了aeiou这几个字母以外的任意字符
4、单字符匹配
[]匹配单个字符,多个[]匹配多个字符 #0-9范围的数字 [0-9] #A-Z范围的字母 [A-Z] #a-z范围的字母 [a-z] #全部范围的数字和字母 [0-9a-zA-Z]
5、其他特殊字符
#^标识开始符,$表示结束符,加这两个表示限定边界 ^hello$ #|表示或者 ^alex|tom$ #非符号,表示除了当前字符 [^al] #.(除换行符外所有字符),一般和*连用(.*x)但他默认是贪婪模式,会尽量多的匹配x字符,直到匹配到最后一个x停止,非贪婪模式为:(.*?x)表示匹配到?后的字符x就停止匹配 a.
#分组,表示分组内的正则是一起生效的
(jd|taobao)
6、python中的正则使用
#查询所有匹配的字符,返回一个集合 ret = re.findall("[2a]","2babac2c") #查询第一个匹配到的字符,返回单个对象 ret = re.search("[2a]","2babac2c") #findall分组会优先显示分组内的内容,?:可以取消优先显示 ret = re.findall("www.(?:baidu|googole).com","www.baidu.com") print(ret) #search分组,通过group(n)拿到数据 ret = re.search("(\d)(\d\.\d{2})(\d)","1asda22.13123asdasd3") print(ret.group(1)) print(ret.group(2)) print(ret.group(3)) #分组命名?P=name和?P=name必须一致,否则报错 ret = re.search("<(?P<tag>\w+)>\w+</(?P=tag)>","<h1>hello</h1>") print(ret.group('tag'))
#当一个正则被多次使用的时候,需要提前编译,可以节省效率
ret = re.compile("正则表达式")
ret.findall("数据")
#当需要懒加载查询时,使用finditer可以节省空间,返回对象,通过group()方法获取数据
ret.finditer("数据")
7、爬虫练习
#爬虫练习 from urllib.request import urlopen import re #读取网页的数据 def readPageData(number): url = "https://movie.douban.com/top250?start=%s&filter=" % number url = urlopen(url) return url.read().decode("utf-8") def getFileData(ret,content): lst = ret.finditer(content) for s in lst: lst = { "id": s.group("id"), "name": s.group("title"), "evaluate": s.group("evaluate"), "introduction": s.group("introduction") } yield lst def main(ret): content = readPageData(count) lst = getFileData(ret,content) print(lst) #写入文件 f = open("E:\python_workspace\movie.txt","a+",encoding = "utf-8") for obj in lst: print(obj) data = str(obj) f.write(data + "\n") f.close() #re.S表示 .会匹配所有字符 ret = re.compile('<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?<div class="star">.*?<span property=".*?" content=".*?"></span>.*?<span>(?P<evaluate>.*?)</span>.*?<span class="inq">(?P<introduction>.*?)</span>', re.S) count = 0 for i in range(0,10): main(ret) count += 25