正则表达式爬取网页

正则表达式

什么是正则表达式?

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

单字符匹配:

.匹配任意除了换行符
\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='teng@qq.com'
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="<h1>这是一个标题</h1>"
result=re.search("<.+?>",text) #非贪婪
print(result.group())#结果是:<h1>
result=re.search("<.+>",text)#贪婪
print(result.group())#结果是:<h1>这是一个标题</h1>

#案例 验证一个字符是不是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"""
<div.+?strongbox"><h2>(.+?)</h2>  #获取标题
<p.+?room">(.+?)</p>   #获取到信息
    """,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()
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值