正则表达式爬取网页

正则表达式

文章目录

  • 正则表达式
    • 什么是正则表达式?
    • 单字符匹配:
    • 多字符匹配:
    • 小案例
    • 开始 结束 贪婪 非贪婪
    • 转义字符和原生字符串
    • 分组
  • re模块常用函数
    • 案例爬取赶集网

什么是正则表达式?

  通俗理解:按照一定的规则,从某个字符串匹配出想要的数据。这个规则就是正则表达式。

单字符匹配:

. 匹配任意除了换行符
\d 匹配任意数字
\D 匹配任意非数字
\s 匹配任意空白字符
\S 匹配任意非任意字符
\w 匹配a-z以及 A-Z以及数字和下划线
\W 与小写相反 匹配非a-z以及 A-Z以及数字和下划线
[] 组合的方式满足中括号里的某一项 都算匹配成功

代码示例:

import re
 #匹配某个字符
text='abc'
ret=re.match('a',text)#从text中匹配
print(ret.group())#打印得到的分组 只能匹配到第一个
#打印结果: a
# 点 匹配任意字符 除了换行符\n
text='abc'
ret=re.match('.',text)#从text中匹配
print(ret.group())#打印得到的分组 只能匹配到第一个
#打印结果: a
# \d 匹配任意数字
text='1bc'
ret=re.match('\d',text)#从text中匹配
print(ret.group())#打印得到的分组 只能匹配到第一个
#打印结果:1
#\D 匹配非任意数字
text='hbc'
ret=re.match('\D',text)#从text中匹配
print(ret.group())#打印得到的分组 只能匹配到第一个
#打印结果 :h

#匹配空白字符\s (小写)  包括 \n \t \r 和空格
text='\n1bc'
ret=re.match('\s',text)#从text中匹配
print(ret.group())#打印得到的分组 只能匹配到第一个
#打印结果 空白

#匹配非空白字符 \S(大写)

# \w 匹配a-z以及 A-Z以及数字和下划线
text='_bc'
ret=re.match('\w',text)#从text中匹配
print(ret.group())#打印得到的分组 只能匹配到第一个
#打印结果  _

#\W 与小写相反 匹配非a-z以及 A-Z以及数字和下划线

#[] 组合的方式, 之哟啊满足中括号里的某一项 都算匹配成功
print('//')
text='bc'
ret=re.match('[1b]',text)#从text中匹配
print(ret.group())#打印得到的分组 只能匹配到第一个
#打印结果: b

多字符匹配:

* 匹配多个字符
+ 匹配多个字符
匹配1个或者0个
{m} 匹配m个字符
{m,n} 匹配m-n之间的个数的字符

代码示例:

import re
#  匹配多个字符
text='abc'
result=re.match('\w*',text)
print(result.group())
# 打印结果:abc

# + 匹配一个或者多个字符
text="1abc"
result=re.match('\w+',text)
print(result.group())
# 打印结果:1abc

# ?匹配前一个字符0个或者1个
text='abd'
result=re.match('\w?',text)
print(result.group())
# 打印结果:a

# {m} 匹配m个字符
text='fhgvkjdfhgv'
result=re.match('\w{2}',text)
print(result.group())
# 打印结果:fh
#{m,n} 匹配m-n之间的个数的字符
text='fhgvkjdfhgv'
result=re.match('\w{2,3}',text)
print(result.group())
# 打印结果:fhg

小案例

代码示例:

import re

#1、验证手机号码: 手机号码的规则是以1开头第二位可以是34587 后面随意

text='18677889900'
result=re.match('1[34587]\d{9}',text)
print(result.group())
#打印结果:18677889900

#2、验证邮箱:邮箱的规则是邮箱的名称是用数字、英文下滑组成的、然后是@ 后面就是域名了
text='[email protected]'
result=re.match("\w+@[a-z0-9]+\.[a-z]+",text)
print(result.group())

# 3、验证url url规则是前面的http或者https或者说ftp然后加上一个冒号,再加上一个斜杠,在后面就是可出现任意的非空白字符了
text="https://nav.guidebook.top/wp-admin/admin-ajax.php?action=io_postviews&postviews_id=3499&_=1648191085924"
result=re.match("(https|http|ftp)://\S+",text)
print(result.group())

#4、验证身份规则:总共18位,前面17位可以是数字,后面以为可以是数字也可以说小写x或者大写的x

text="41142419990930096X"
result=re.match("\d{17}[\dxX]",text)
print(result.group())

开始 结束 贪婪 非贪婪

^ 以什么开头
$ 以什么结尾
+? 非贪婪
+ 贪婪

代码示例:

import re

# ^:以...开头
text="hello world"
result=re.search('world',text) #表示寻找world 打印结果world
print(result.group())
#result=re.search('^world',text)# 表示寻找以world 开头 打印结果none
print(result.group())
#  以...结尾

text="hello world"
result=re.search('world$',text) #表示寻找以world结尾
print(result.group())
result=re.search('world',text)
print(result.group())

text="hello world"
result=re.search('^$',text) #表示寻找以world结尾
print(result.group())#打印空白字符

#|:表示匹配多个字符串或者表达式
#贪婪和非贪婪
text="12345"
result=re.search('\d+',text)#贪婪模式 打印数字
print(result.group())
result=re.search('\d+?',text) #非贪婪模式 打印数字
print(result.group())#打印结果 1

# 提取一个html标签
text="

这是一个标题

"
result=re.search("<.+?>",text) #非贪婪 print(result.group())#结果是:

result=re.search("<.+>",text)#贪婪 print(result.group())#结果是:

这是一个标题

#案例 验证一个字符是不是0-100之间的数字 #0,1,99,100 text='100' result=re.match("0$|[1-9]\d?$|100$",text) print(result.group())#打印结果 100

转义字符和原生字符串

加上r即可避免多个
代码示例:

import re
# python中的转义字符:
#raw
text="hello\\nworld"
print(text)#打印结果 hello\nworld
text=r"hello\nworld"
print(text) #打印结果 hello\nworld

#正则表达式的转义字符:
text="apple price is $99,range is $88"
result=re.findall("\$\d+",text)
print(result)#打印结果['$99', '$88']
#原生字符串和正则表达式:
# 正则表达式的字符串解析规则
#   首先把字符串放在python语言层面来解析
#   把python语言层面解析的结果再放到正则表达式层间进行解析
text="\cba c"
result=re.match("\\\\c",text)
print(result.group())#打印结果:\c
result=re.match(r"\\c",text)
print(result.group()) #打印结果:\c

分组

加上()可以表示分组

group(m) 获取第m个分组
groups() 获取到所有分组

代码示例:

import re
#分组:
text="apple price is $99,orange price is $88"
result=re.search('.+\$\d+.+\$\d+',text)
print(result.group())#打印结果 apple price is $99,orange price is $88
result=re.search('.+(\$\d+).+(\$\d+)',text)
print(result.group(0))#结果:apple price is $99,orange price is $88
print(result.group(1))#结果:$99 匹配到第一个分组
print(result.group(2))#结果:$88 匹配到第二个分组
print(result.groups())#结果:('$99', '$88') 获取所有分组

re模块常用函数

findall 查找所有满足条件的
sub 根据规则替换其他字符
split 根据规则分割字符
compile 编译正则表达式

代码示例:

import re
#findall():查找所有满足条件的
#search 只会找到第一个满足条件的
text="apple price is $99,orange price is $88"
result=re.findall(r"\$\d+",text)
print(result) #打印结果: ['$99', '$88']
#sub: 根据规则替换其他字符
text="hello world! hello world!"
new_text=text.replace(" ","\n")
print(new_text)
new_text1=re.sub(" ","\n",text)
print(new_text1)
#两者打印结果一样
#split:根据规则分割字符
text="nihao zhongguo hello world"
result=re.split(r' ',text)
print(result)# 打印结果:['nihao', 'zhongguo', 'hello', 'world']

#compile: 编译正则表达式
text="apple price is $99.9"
r=re.compile(r"""
\d+  #整数部分
\.?  #小数点
\d   #小数部分
""",re.VERBOSE)  #给正则表达式加个注释 re.VERBOSE
result=re.search(r,text)
print(result.group())
#打印结果99.9

案例爬取赶集网

import  requests
import  re

def parse_page(base_url):
    headers={
        'user-agent':''
    }
    resp=requests.get(base_url,headers=headers)
    text=resp.content.decode('utf-8')
    new_text=re.sub("\n| |\r","",text) #注意这里对于空白字符和换行符放入替换
    houses=re.findall(r"""

(.+?)

#获取标题 (.+?)

#获取到信息 """
,new_text,re.VERBOSE|re.DOTALL) print(houses) def main(): base_url="https://cs.58.com/pinpaigongyu/?PGTID=0d200001-0019-eceb-d6eb-04175633b670&ClickID=1" parse_page(base_url) if __name__ == '__main__': main()

你可能感兴趣的:(小白学爬虫,正则表达式,python)