嗨咯,读者们好,已经好久好久没有更新了呢(真诚地求原谅~)
今天给大家分享一个爬虫案例:爬取"下厨房"的"本周最受欢迎菜谱"
这次爬取的信息如下:
- url:http://www.xiachufang.com/explore/
- 目标:爬取前十页的标题、链接、配料、七天内做过这个菜的人数以及发布的作者等数据,并存储在excel表中
明确了我们的目标后,就要开始整理我们爬取数据的思路
首先在浏览器上打开这个网址url,可以看到这个页面
我们要提取的内容就在这个红色框框内
按"F12"打开开发者工具,按图示顺序操作,我们就能找到"标题"在HTML中的位置了,其他数据也是这样查找(先点击位置1,然后鼠标移到要查找的数据,就能在位置3处看到该数据在HTML中的位置)
要看懂HTML结构,需要了解一下前端的基础知识(这里不详细讲述)
通过对比多个菜谱对应信息存储的位置,我们观察到它们的共同点
1、"标题"都在class属性为"name"的标签<p>下的<a>标签中
2、"配料"都在class属性为"ing ellipsis"的标签<p>下的<span>标签和<a>标签中
3、"七天之内做过的人数"在class属性为"stats green-font"的<p>标签下的class属性为"bold"的<span>标签里
4、"发布的作者"在class属性为"author"的<p>标签里
知道这些信息分别在HTML中所处的位置后,我们就能通过代码提取这些元素,获取对应的文本信息,剩下就是存储到excel的问题了
不过按照我的习惯,我喜欢先找到这些标签共同的最小父级标签,然后再通过循环进行一一提取
我们再来看下HTML代码
<li>标签中包含了所有我们需要提取的标签,换句话说:每一道菜的相关信息都用<li>标签进行分隔,而所有的<li>标签又都被class为"list"的<ul>标签中,所以这个<ul>标签就是我要找的最小父级标签
分析完爬取思路后,接下来就是用代码代替我们自动去提取这些信息
这次案例主要使用到的库:
- requests:用于向服务器发送url,获取服务器响应
- BeautifulSoup:用于解析网页以及提取数据
- pandas:这里用于存储数据
这三个库都是第三方库,需要另行安装,安装方法(在终端/命令提示符上输入):
"pip3 install requests"安装requests库;
"pip3 install bs4"安装BeautifulSoup库;
"pip3 install pandas"安装pandas库
# 导入相关库
import requests
from bs4 import BeautifulSoup
# 爬取的网页地址
url = 'http://www.xiachufang.com/explore'
# 设置请求头信息,伪装成浏览器,避免被对方服务器识别
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'}
# 模拟浏览器向服务器发送请求
res = requests.get(url,headers=headers)
# 创建一个bs对象,用于解析网页和提取数据
# 括号内的第一个参数必须是字符串,第二个参数是网页解析器
# res.text是将响应的内容转化为文本形式
# html.parser是bs对象内置的解析器,也可以用lxml
bs = BeautifulSoup(res.text,'html.parser')
# 定位最小父级标签ul,返回一个Tag对象
parent = bs.find('ul',class_='list')
# 获取ul标签下的所有li标签,返回一个迭代器
lis = parent.find_all('li')
# 利用for循环遍历每个li标签,再向下精准提取数据
for item in lis:
# 获取标题
title = item.find('p',class_='name').find('a').text.strip()
# 获取标题链接
link = 'http://www.xiachufang.com'+item.find('p',class_='name').find('a')['href']
# 获取配料
ellipsis = item.find('p',class_='ing ellipsis').text.strip()
# 获取七天内做过的人数
people_num = item.find('p',class_='stats green-font').find('span',class_='bold').text
# 获取发布该信息的作者
author = item.find('p',class_='author').text.replace('\n','')
# 打印输出
print('标题:'+title)
print('详情链接:'+link)
print('配料:'+ellipsis)
print('人数:'+people_num)
print('作者:'+author)
print('*'*70+'\n')
"User-Agrnth"获取方式
先点击位置1处,在点击位置2处(其他行也可以)
然后点击位置1处,往下翻,找到位置2处,选中复制粘贴到代码中,修改其代码所示的形式即可
输出结果:
但是还没结束,这只是获取了第一页的信息,而我们的目标是获取十页的信息
这时不知道怎么做,先点击第二页、第三页,看看url是否有什么规律
点击第二页时,url为:http://www.xiachufang.com/explore/?page=2
点击第三页时,url为:http://www.xiachufang.com/explore/?page=3
由此可以观察出"page"的值就是代表页数
那我们只要稍稍改动一下刚才请求的网址,并用for循环模拟翻页,就可以获取到十页的数据了
# 导入相关库
from bs4 import BeautifulSoup
import requests
# 导入时间相关的库
import time
# 用循环模拟翻页
for num in range(1,11):
# 爬取的网页地址
url = 'http://www.xiachufang.com/explore?page='+str(num)
# 设置请求头信息,伪装成浏览器,避免被对方服务器识别
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'}
# 模拟浏览器向服务器发送请求
res = requests.get(url,headers=headers)
# 创建一个bs对象,用于解析网页和提取数据
# 括号内的第一个参数必须是字符串,第二个参数是网页解析器
# res.text是将响应的内容转化为文本形式
# html.parser是bs对象内置的解析器,也可以用lxml
bs = BeautifulSoup(res.text,'html.parser')
# 定位最小父级标签ul,返回一个Tag对象
parent = bs.find('ul',class_='list')
# 获取ul标签下的所有li标签,返回一个迭代器
lis = parent.find_all('li')
# 利用for循环遍历每个li标签,再向下精准提取数据
for item in lis:
# 获取标题
title = item.find('p',class_='name').find('a').text.strip()
# 获取标题链接
link = 'http://www.xiachufang.com'+item.find('p',class_='name').find('a')['href']
# 获取配料
ellipsis = item.find('p',class_='ing ellipsis').text.strip()
# 获取七天内做过的人数
people_num = item.find('p',class_='stats green-font').find('span',class_='bold').text
# 获取发布该信息的作者
author = item.find('p',class_='author').text.replace('\n','')
# 打印输出
print('标题:'+title)
print('详情链接:'+link)
print('配料:'+ellipsis)
print('人数:'+people_num)
print('作者:'+author)
print('*'*70+'\n')
# 每次循环结束,就让程序休眠2秒,防止访问服务器的频率够快而被屏蔽
time.sleep(2)
目前为止我们已经获取了十页的数据了,就差将其存储到excel中了
分别将提取的信息用列表进行保存
# 分别定义列表类型变量
titles = []
links = []
ellipsis_list = []
nums = []
authors = []
导入panda库
import pandas as pd
修改后的代码
import requests
import time
import pandas
from bs4 import BeautifulSoup
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'}
# 用于存储相关信息
titles = []
links = []
ellipsis_list = []
nums = []
authors = []
for num in range(1,11):
url = 'http://www.xiachufang.com/explore/?page='+str(num)
res = requests.get(url,headers=headers)
bs = BeautifulSoup(res.text,'html.parser')
parent = bs.find('div',class_='normal-recipe-list').find_all('li')
for item in parent:
# 获取标题
title = item.find('p',class_='name').find('a').text.strip()
titles.append(title)
# 获取标题链接
link = 'http://www.xiachufang.com'+item.find('p',class_='name').find('a')['href']
links.append(link)
# 获取配料
ellipsis = item.find('p',class_='ing ellipsis').text.strip()
ellipsis_list.append(ellipsis)
# 获取七天内做过的人数
people_num = item.find('p',class_='stats green-font').find('span',class_='bold').text
nums.append(people_num)
# 获取发布该信息的作者
author = item.find('p',class_='author').text.replace('\n','')
authors.append(author)
time.sleep(2)
# 将所有信息存储到excel里
content = {'标题':titles,'链接':links,'配料':ellipsis_list,'七天做过的人数':nums,'发布作者':authors}
df = pandas.DataFrame(content)
df.to_excel('下厨房最受欢迎的菜谱前十页.xlsx')
在当前目录下找到并打开创建的excel,看下里面是否有我们想要的内容
很棒,说明我们成功的将数据爬取了下来,并且保存到了本地
多亏了“开课吧”的一位可爱小姐姐冉冉老师的鼓励和指导,才有了今天的这个分享,希望大家看了之后有所收获