p.s.高产量博主,点个关注不迷路!
目录
I.实战目标确定
II.分析与准备工作
III.代码的编写步骤
IV.完整源码
首先,我们确定一下本次实战的目标:获取Starbucks菜单页中的部分图片,下面是Starbucks的菜单页的展示图:
由于出于复习巩固bs4语法的目的,我们不爬取过多的图片,以免给Starbucks网站造成太多的访问资源浪费(学习爬虫要讲武德!)。这是爬取的部分图片的展示:
上面是我们本次实战的目标确定,如果对bs4的安装和基础语法不了解的朋友,可以先看一下这篇bs4基础博客。
接下来,按照传统的步骤,我们开始抓接口、分析解析的逻辑:
1️⃣ 首先,我们进入Starbucks菜单页:
接下来,按F12,开启网页的检查模式(右键选择检查也可以):
2️⃣ 之后,我们在Network项中的最左侧Name一栏进行粗略的查找,经过一些对比,真正的接口在这个menu/文件中:
选中menu/,之后在Headers中复制URL项,作为获取响应的url地址,同时注意到它是一个get请求,因此我们无需额外传递参数:
3️⃣ 接口获取后,我们开始分析如何解析我们需要的内容。首先我们拆分一下任务:我们需要解析两项内容:图片和图片对应的名称。前者是图片的地址,后者是一个字符串。我们首先先考虑解析图片对应的名称,于是点击menu/中的Response,这个Response代表了返回给我们的response的内容:
通过上图,我们以第一个图片的名称为例,可以看到名称被放在标签中,这个标签本身没有其他的属性值,因此我们需要借助其他的标签定位到strong:此时优先考虑它的父标签:ul > li > strong,也即这个strong标签是在ul标签内部的一个li标签内。由于li标签也没有属性值,我们考虑用它的“爷爷”标签ul辅助定位,因此bs4解析的语句应该是:
ul[class = "grid padded-3 product"] strong
4️⃣ 最后我们尝试解析一下图片的路径,它的思路与上面的图片名称类似,我们观察后发现:
可以看出,此时图片并不是用一个img标签,而是通过background-image属性作为背景图放在网站上的。于是我们的目的变成了提取ul标签下每一个li标签中的div标签中style属性的属性值:
ul[class = "grid padded-3 product"] div
之后我们需要对获取的style属性值做一些基础的字符串处理,以裁剪出需要的链接部分。
另外补充一点:此时在background-image属性中的url值,并不是图像的完整url,我们可以通过分析Starbucks网站上的任意一张图片,获取完整的url:
鼠标点击一下任意一种图片的background-image的url属性上,右侧的style中能够看到一个url,此时我们把鼠标放在右侧style的url的值上面,会出现它的完整url:
再把路径敲出来,发现完整链接是这样的:
https://www.starbucks.com.cn/images/products/affogato.jpg
对比一下前面我们获取的图片的url,发现它需要拼接这样的一段内容:
https://www.starbucks.com.cn
到此为止,所有准备工作均已完成,我们可以进行代码的书写。
接下来,我们开始编写代码:
1️⃣ 首先,我们先学习一下如何用bs4处理服务器响应文件:
from bs4 import BeautifulSoup
soup = BeautifulSoup(content,'lxml')
上一篇笔记中仅了解了如何处理本地的html文件,服务器的响应应当用上述的格式进行书写:使用Beautifulsoup()函数,传入两个参数,第一个参数是服务器的响应的内容,第二个参数是'lxml’这个固定的参数。
2️⃣ 书写基础爬虫语句,获取服务器的响应:
import urllib.request
url = "https://www.starbucks.com.cn/menu/"
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
}
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
这部分是我们比较熟悉的流程,因此不做解释,不了解的朋友可以查看之前的博客!其中url是我们前面准备工作抓取的接口url。
3️⃣ 定义bs4语句:
from bs4 import BeautifulSoup
soup = BeautifulSoup(content,'lxml')
basic_url = "https://www.starbucks.com.cn"
name_list = soup.select('ul[class = "grid padded-3 product"] strong')
img_url_list = soup.select('ul[class = "grid padded-3 product"] div')
通过之前分析的bs4语句,我们拿到了所有的图片名称和图片部分路径的列表,同时我们定义了图片路径的前一部分,作为basic_url,两部分拼接后,我们就可以访问和下载图片了!
4️⃣ 循环下载图片:
for i in range(0,5):
current_style = img_url_list[i].attrs.get("style")
current_url_link = basic_url + current_style.split('(')[1].split(')')[0].replace('"','')
urllib.request.urlretrieve(url = current_url_link, filename = '.\\Starbucks\\' + name_list[i].get_text() + '.jpg')
最后,我们循环去下载图片:
首先,我们获取当前的style属性的属性值,前面提到了style属性的属性值是这样的:
background-image: url("/images/products/affogato.jpg")
我们只需要 /images/products/affogato.jpg 这部分,因此我们需要进行字符串的裁剪,裁剪的思路是通过 "(" 和 ")" 进行切割。
两段链接拼接后,得到了最终的链接,放在current_url_link中,于是我们调用urllib.request.urlretrieve()函数,下载图片。
最后的最后,强调我们学习的目的,只下载前五张就好,请勿过多获取资料!
下面是本次实战的完整源码,仅供参考学习:
# # 解析服务器响应文件:bs4的实战之Starbucks数据爬取与图片下载
import urllib.request
url = "https://www.starbucks.com.cn/menu/"
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
}
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
from bs4 import BeautifulSoup
soup = BeautifulSoup(content,'lxml')
basic_url = "https://www.starbucks.com.cn"
name_list = soup.select('ul[class = "grid padded-3 product"] strong')
img_url_list = soup.select('ul[class = "grid padded-3 product"] div')
for i in range(0,5):
current_style = img_url_list[i].attrs.get("style")
current_url_link = basic_url + current_style.split('(')[1].split(')')[0].replace('"','')
urllib.request.urlretrieve(url = current_url_link, filename = '.\\Starbucks\\' + name_list[i].get_text() + '.jpg')
【温馨提示】:运行之前,请先在与该python文件同级的文件夹下创建名为 Starbucks 文件夹,后续图片会下载到该文件夹内!