正则表达式基础

  1. 什么是正则表达式
    正则表达式是对字符串操作的一种逻辑公式,就是用实现定义好的一些特定的字符、及这些特定的字符的组合,组成一个“规则字符串“,这个“规则字符串“用来表达对字符串的一种过滤逻辑。
    注意: 正则表达式并不是Python独有的,Python中使用re模块实现。

    元字符描述
    \w匹配字母数字及下划线
    \W匹配非字母数字下划线
    \s匹配任意的空白符
    \S匹配任意非空白符
    \d匹配数字
    \D匹配任意非数字的字符
    .匹配除换行符以外的任意字符
    ^匹配字符串的开始
    $匹配字符串的结束
    *重复零次或更多次
    +重复一次或更多次
    ?重复零次或一次
    {n}重复n次
    {n,}重复n次或更多次
    {n,m}重复n到m次
    ab
    ()匹配括号内的表达式,也表示一个组

在这里插入图片描述
3. re.match()
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配的话,match()就会返回None
语法: re.match(正则表达式,要匹配的字符串,匹配方式)
常用匹配方式: re.I 使匹配对大小写不敏感 re.S 使 . 匹配包括换行在内的所有字符

   import re
   str='www.kaikeba'
   result=re.match('www',str)
   #获取匹配的结果
   print(result.group())
   #获取匹配字符串的长度范围
   print(result.span())
   #re.match() 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配的话,match()就会返回None
   #不在起始位置匹配,返回None
   print(re.match('kaikeba',str))
   #默认大小写是敏感的
   print(re.match('WWW',str))
   #设置匹配模式,忽略大小写
   print(re.match('WWW',str,re.I))
  
   #多种匹配方式
   str2='abc 123 def'
    #常规匹配
    print(re.match('^abc\s\d\d\d\sdef$',str2).group())
    print(re.match('^abc\s\d+\sdef$',str2).group())
    print(re.match('^abc\s\d{3}\sdef$',str2).group())
    #范式匹配
    print(re.match('^abc\s.*\sdef$',str2).group())
    
    print(re.match('^.*$',str2).group())
    #获取指定的字符
    print(re.match('^abc\s(.*)\s(def)$',str2).group(1)) #正则表达式中出现括号就表示你取你想取得内容
    # 通过re.group()获得结果后,如果正则表达式中有括号,则re.group(1)获取的就是第一个括号中匹配的结果
abc 123 def
abc 123 def
abc 123 def
abc 123 def
abc 123 def
('123', 'def')
#贪婪匹配和非贪婪匹配
#贪婪匹配
str3='hello 1234567 world Demo'
result=re.match('^hello.*(\d+).*Demo',str3)#首先满足前面的.*
print(result)
print(result.group(1))
# 这种情况的原因是前面的.*给匹配掉了,前面的.*在这里会尽可能的匹配多的内容,也就是我们所说的贪婪匹配
result=re.match('^hello.*?(\d+).*Demo',str3)#首先满足括号中的(\d+)
print(result)
print(result.group(1))
<re.Match object; span=(0, 24), match='hello 1234567 world Demo'>
7
<re.Match object; span=(0, 24), match='hello 1234567 world Demo'>
1234567
#匹配模式  re.S   re.I (严格大写S、I)
# 很多时候匹配的内容是存在换行的问题的,这个时候的就需要用到匹配模式re.S来匹配换行的内容
content = """hello 123456 world
demo
"""
result =re.match('^he.*?(\d+).*?demo$',content,re.S)
print(result)
print(result.group())
print(result.group(1))
<re.Match object; span=(0, 23), match='hello 123456 world\ndemo'>
hello 123456 world
demo
123456
#转义字符\  (严格'\',不是'/')
# 当我们要匹配的内容中存在特殊字符的时候,就需要用到转义符号\
content= "price is $5.00"
result = re.match('price is \$5\.00',content)
print(result)
print(result.group())
<re.Match object; span=(0, 14), match='price is $5.00'>
price is $5.00
  1. re.search()
    re.search扫描整个字符串返回第一个成功匹配的结果
#re.search()
#re.search扫描整个字符串返回第一个成功匹配的结果,只返回一个结果。
# 所以为了匹配方便,我们会更多的用search,不用match,match必须匹配头部,所以很多时候不是特别方便
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
result = re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>',html,re.S)
print(result)
print(result.group())
# print(result.group(1))
# print(result.group(2))
<re.Match object; span=(121, 286), match='<li data-view="2">一路上有你</li>\n<li data-view="7">\>
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
result = re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>',html,re.S)
print(result)
print(result.groups())
print(result.group(1))
print(result.group(2))
<re.Match object; span=(121, 286), match='<li data-view="2">一路上有你</li>\n<li data-view="7">\>
('齐秦', '往事随风')
齐秦
往事随风
  1. re.findall()
    搜索字符串,以列表的形式返回全部匹配的子串
#re.findall()
#搜索字符串,以列表的形式返回全部能匹配的字符串
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
results=re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>',html,re.S)
print(results)
print(type(results))
# print(results.group())  错误,列表没有group()P
# print(results.group(1))
# print(results.group(2))
print(results[0])
for value in results:
    print(value)#输出了元组
    print(value[0], value[1], value[2])
[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')]
<class 'list'>
('/2.mp3', '任贤齐', '沧海一声笑')
('/2.mp3', '任贤齐', '沧海一声笑')
/2.mp3 任贤齐 沧海一声笑
('/3.mp3', '齐秦', '往事随风')
/3.mp3 齐秦 往事随风
('/4.mp3', 'beyond', '光辉岁月')
/4.mp3 beyond 光辉岁月
('/5.mp3', '陈慧琳', '记事本')
/5.mp3 陈慧琳 记事本
('/6.mp3', '邓丽君', '但愿人长久')
/6.mp3 邓丽君 但愿人长久
  1. re.compile()
    将正则字符串编译成正则表达式对象,以便于复用该匹配模式。
# re.compile()
# 将正则字符串编译成正则表达式对象,以便于复用该匹配模式
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''

pattern = re.compile('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>',re.S)#将正则字符串编译成正则表达式对象
results=re.findall(pattern,html)

print(results)
print(type(results))
for result in results:
    print(result)
    print(result[0], result[1],result[2])
[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')]
<class 'list'>
('/2.mp3', '任贤齐', '沧海一声笑')
/2.mp3 任贤齐 沧海一声笑
('/3.mp3', '齐秦', '往事随风')
/3.mp3 齐秦 往事随风
('/4.mp3', 'beyond', '光辉岁月')
/4.mp3 beyond 光辉岁月
('/5.mp3', '陈慧琳', '记事本')
/5.mp3 陈慧琳 记事本
('/6.mp3', '邓丽君', '但愿人长久')
/6.mp3 邓丽君 但愿人长久
  1. re.sub
    替换字符串中每一个匹配的子串后返回替换后的字符串
    语法:re.sub(正则表达式,替换成的字符串,原字符串)
#re.sub
# 替换字符串中每一个匹配的子串后返回替换后的字符串
# 语法:re.sub(正则表达式,替换成的字符串,原字符串)
import re
content='hello 123466 world'
content=re.sub('\d+','',content)
print(content)
hello  world
#有些情况下我们替换字符的时候,还想获取我们匹配的字符串,然后在后面添加一些内容
#需要注意的一个问题是\1是获取第一个匹配的结果,为了防止转义字符的问题,我们需要在前面加上r
import re
content='hello 123466 world'
# content = re.sub('(\d+)','\1 7890',content)
# content = re.sub('(\d+)',r' 7890',content)
content = re.sub('(\d+)',r'\1 7890',content)
print(content)
hello 123466 7890 world

在这里插入图片描述

#贴吧爬虫
#tiebaSpider
import requests
import re
import csv
import pymysql
class TiebaSpider(object):
    def __init__(self,tibaName):
        self.tibaName=tibaName
        self.base_url='https://tieba.baidu.com/f?kw='+tibaName+'&ie=utf-8&pn={}'
        self.headers={
           'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36'
        }
        
    #构建请求链接实现翻页
    def get_url_list(self):
        url_list=[]
        for i in range(1):
            url_list.append(self.base_url.format(i*50)) #format
        return url_list
    #请求页面信息
    def get_pageInfo(self,url):
        response=requests.get(url=url,headers=self.headers)
        #print(response.content.decode('utf-8'))
        return self.parse_pageInfo(response.content.decode('utf-8'))
    
    #解析界面
    def parse_pageInfo(self,html):
        pattern=re.compile('<li class=" j_thread_list clearfix".*?<a.*? href="(.*?)".*?title="(.*?)".*?</a>',re.S)
       # print(re.findall(pattern,html))
        return (re.findall(pattern,html))
    #存储到txt中
    def save_to_txt(selfself,info):
        for tuple_value in info:
            info_str='贴子的信息:'+tuple_value[1]+'贴子的链接:https://tieba.baidu.com'+tuple_value[0]+'\n'
            #print(info_str)
            #
            with open('./tieba.txt','a',encoding='utf-8') as f:
                f.write(info_str)
    '''      
    #写入到csv中,导入import csv
    def save_to_csv(self,info): 
        for tuple_value in info:
            #newline默认会有'\r\n'换行符
            #encoding='utf-8-sig,解决中文乱码
            with open('./tieba.csv','a',newline='',encoding='utf-8-sig') as f:
                writer=csv.writer(f)
                writer.writerow(list(tuple_value)) #writerow一行一行去写
         #写入到数据库,导入pymysql
    def save_to_database(self,info):
        #链接数据库
        conn=pymysql.connect(host='localhost',user='root',passwd='123',db='tieba',port=3306,charset='utf8mb4')
        #游标对象(内部包含了很多操作数据库的方法)
        cursor=conn.cursor() 
        #info={('链接'),(文字)...}
        for tuple_value in info:
            #插入数据,构造SQL语句
            sql="insert into tieba_info (info,url) values('{}','{}')".format(tuple_value[1])
            #执行SQL
            cursor.execute(sql)
            #提交事务
            conn.commit()
        
        #关闭游标
        cursor.close()
        #关闭数据库连接
        conn.close()
   '''
    
    #所有的逻辑结构都放在这里面,封装及调用
    def run(self):
        #1.获取链接
        url_list=self.get_url_list()#
        #2.发送请求
        for url in url_list:
            info=self.get_pageInfo(url) 
            #self.save_to_txt(info)
            self.save_to_csv(info)
            #self.save_to_database(info)
if __name__=="__main__":
    tiebaspider=TiebaSpider('lol')
    tiebaspider.run()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值