数据分析正式篇之第六节


欢迎来到煊煊周末小课堂!蹭了非常善良的热心学长的网课,九次感谢!让我们一起祝福他飞黄腾达!
现在学习基础爬虫部分

爬虫基础知识

爬虫是请求网站并提取数据的自动化程序,流程如下:
发起请求–>获取相应内容–>解析内容–>保存数据
一些基础知识大概了解一下:
首先打开一个页面,右键检查或者直接F12,点击network
在这里插入图片描述
此时刷新页面,就可以看到所有的请求,点击右侧的所有文件,查看自己想要爬取的页面文件,response是响应内容,这里面可以看到是否是想要的页面,request是请求,里面有我们爬虫需要的参数
在这里插入图片描述
下面我们根据目前了解到的内容学习爬虫的基础代码

#导入网络请求模块
import requests
#创建请求头,这个User-Agent里面的参数是根据自己浏览器里面的,在上图的requests里面可以找到
headers={"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'}
#发送网络请求,headers里面有请求方式,我们这个是get,多数登录注册界面会用到post
response=requests.get(url='https://www.baidu.com/',headers=headers)
#获取请求内容
print(response.content.decode('utf-8'))
#查看状态码,如果请求成功会返回200
print(response.status_code)
#获取响应头
#print(response.headers)

当运行成功的时候,结果如下:
在这里插入图片描述
类似这种,后面还有返回的状态码200,懒得放图了,此时我们已经学会爬取整个页面的内容了。
现在来学习爬取已知的一部分,举一个爬取百度logo的例子

import requests
#创建请求头
headers={"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'}
#发送请求
reponse=requests.get(url='https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',headers=headers)
#将获取的二进制文件保存
with open('./bdlogo.png','wb') as f:
    f.write(reponse.content)

运行后,发现bdlogo.png的图片就在目录下面了。

正则表达式

正则表达式的匹配模式我们不必都把它记住,熟练即可,当遇到不了解的再查就行,这里放入一个正则表达式的学习链接:https://deerchao.cn/tutorials/regex/regex.htm

re.match()

只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None
语法:
re.match(正则表达式,要匹配的字符串,匹配方式)

import re
str1='www.baidu.com'
#匹配www,第三个匹配方式的参数可以不写
result=re.match('www',str1)
#获取匹配结果
print(result.group())
#获取匹配字符串的长度范围
print(result.span())
#如果字符串开始匹配不到字符串,就返回none
print(re.match('baidu',str1))

输出结果:

www
(0,3)
None

多种匹配方式

import re
str2='abc 123 def'
#常规匹配,^代表字符串的起始,$代表字符串的结尾
print(re.match('^abc\s\d\d\d\sdef$',str2).group())
print(re.match('^abc\s\d{3}\sdef$',str2).group())
#范匹配,不必都写出来,里面的.代表换行符以外的内容,*代表重复0次或更多次
print(re.match('^abc\s.*\sdef$',str2).group())
#获取指定字符串,把想要获取的内容用括号括起来,同时group(1)代表想要获取第一个括号里的内容
# 如果有第二个括号并且想获取第二个括号里内容,就写group(2)即可,此处想获取到123
print(re.match('^abc\s(.*)\sdef$',str2).group(1))

输出:

abc 123 def
abc 123 def
abc 123 def
123

贪婪与非贪婪

import re
#贪婪匹配
str3='hello 1234567 world Demo'
result=re.match('^hello.*(\d+).*Demo$',str3)
#此时下面的语句输出7,而不是1234567
print(result.group(1))
#出现上述情况的原因前面的123456被前面的.*给匹配掉了,它会尽可能的匹配多的内容
#这就是我们所说的贪婪匹配
#下面我们来看看非贪婪匹配:
result2=re.match('^hello.*?(\d+).*Demo$',str3)
print(result2.group(1))
#此时输出的结果就是1234567,因为在.*后面加了一个?
#在能满足后面的要求就满足后面,即为非贪婪

匹配模式

很多时候要匹配的内容都存在换行符,而我们常用的’.'是匹配所有非换行符的,这个时候就不太方便,此时我们就可以采用re.S的匹配模式

import re
str4='''hello 123
        demo
     '''
#此时的匹配模式是re.S,代表着我们的'.'什么都可以匹配了
result=re.match('^he.*?(\d+)demo$',str4,re.S)
print(result.group(1))

输出123

转义

#当要匹配的内容存在特殊字符,需要转义字符\
str5='price is $5'
result=re.match('price is\$5',str5)
print(result.group())

re.search()

扫描整个字符串返回第一个成功匹配的结果,因此缺点就是只能找一个


import re
html1='''<li data-view='5' class="active">
           <a href="/6.mp3" singer="邓丽君">千里共婵娟</a>
        </li>
        <li data-view='5' class="active">
           <a href="/5.mp3" singer="任齐贤">沧海一声笑</a>
        </li>
      '''
result=re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>',html1,re.S)
print(result.group(1))
print(result.group(2))

输出只有一个:

邓丽君
千里共婵娟

如果想把所有的歌手和歌名都输出,就要用到下面学的re.findall

re.findall()

搜索字符串,以列表形式返回全部能匹配的字符串

import re
html1='''<li data-view='5' class="active">
           <a href="/6.mp3" singer="邓丽君">千里共婵娟</a>
        </li>
        <li data-view='5' class="active">
           <a href="/5.mp3" singer="任齐贤">沧海一声笑</a>
        </li>
      '''
result2=re.findall('<li.*?active.*?singer="(.*?)">(.*?)</a>',html1,re.S)
for result in result2:
    print(result[0],result[1])

输出:

邓丽君 千里共婵娟
任齐贤 沧海一声笑

re.compile()

将正则字符串编译成正则表达式对象,以便于复用该匹配模式
还是刚刚的例子:

import re
html1='''<li data-view='5' class="active">
           <a href="/6.mp3" singer="邓丽君">千里共婵娟</a>
        </li>
        <li data-view='5' class="active">
           <a href="/5.mp3" singer="任齐贤">沧海一声笑</a>
        </li>
      '''
pattern=re.compile('<li.*?active.*?singer="(.*?)">(.*?)</a>',re.S)
#把正则表达式换成pattern,匹配模式也包含在其中了,提高效率
result2=re.findall(pattern,html1)
for result in result2:
    print(result[0],result[1])

re.sub()

替换字符串中每一个匹配的子串后返回替换后的字符串
语法:
re.sub(正则表达式,替换的字符串,原字符串)

content='hello 12345 world'
#匹配数字12345,然后将数字换成7890
content=re.sub('(\d+)','7890',content)
print(content)

输出:

hello 7890 world
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值