zoukankan      html  css  js  c++  java
  • 爬某果美食八大菜系的菜谱 Python

    本文仅用于学习和交流,不具有任何商业价值,如有问题,请与我联系,我会即时处理。--Python逐梦人。

    网址分析

    通过分析,没有json,只能用html解析获取数据,抓几个页面看看规律。因为要爬八大菜系,所以有横向和纵向比较。

    横向:

    https://www.douguo.com/caipu/%E7%B2%A4%E8%8F%9C/0/0  第一页
    https://www.douguo.com/caipu/%E7%B2%A4%E8%8F%9C/0/20 第二页

    纵向:

    https://www.douguo.com/caipu/%E7%B2%A4%E8%8F%9C/0/20
    https://www.douguo.com/caipu/%E5%B7%9D%E8%8F%9C/0/20
    https://www.douguo.com/caipu/%E6%B9%98%E8%8F%9C/0/20

    数据爬取与保存

    然后发现,url的规律为:https://www.douguo.com/caipu/{菜系}/0/{页码},然后手动翻了下各菜系页码都是10页。开干:

     1 """
     2     爬豆果美食的菜谱
     3     url规律。
     4     横向:
     5     https://www.douguo.com/caipu/%E7%B2%A4%E8%8F%9C/0/0  第一页
     6     https://www.douguo.com/caipu/%E7%B2%A4%E8%8F%9C/0/20 第二页
     7     纵向(某一菜系的第二页):
     8     https://www.douguo.com/caipu/%E7%B2%A4%E8%8F%9C/0/20
     9     https://www.douguo.com/caipu/%E5%B7%9D%E8%8F%9C/0/20
    10     https://www.douguo.com/caipu/%E6%B9%98%E8%8F%9C/0/20
    11     爬取菜谱名,发布人,用料,评分,收藏人数,链接,图片。
    12 """
    13 
    14 # 程序开始时间
    15 import random
    16 import time
    17 import openpyxl
    18 import parsel
    19 import requests
    20 import re
    21 
    22 # 打开excel文档
    23 wb = openpyxl.Workbook()
    24 ws = wb.create_sheet(index=0)
    25 # 写入表头
    26 ws.cell(row=1,column=1,value='菜系')
    27 ws.cell(row=1,column=2,value='菜名')
    28 ws.cell(row=1,column=3,value='发布人')
    29 ws.cell(row=1,column=4,value='用料')
    30 ws.cell(row=1,column=5,value='评分')
    31 ws.cell(row=1,column=6,value='详情页')
    32 ws.cell(row=1,column=7,value='图片链接')
    33 
    34 
    35 startTime = time.time() # 时间戳
    36 headers = {
    37     'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36',
    38 }
    39 caixiList = ['川菜', '湘菜','粤菜','东北菜','鲁菜','浙菜','湖北菜','清真菜'] #中国菜系
    40 for caixi in caixiList: # 循环读取菜系列表
    41     print(f'=====================正在爬取{caixi}=====================')
    42     time.sleep(random.uniform(2, 5)) # 随机生成一个实数,也就是浮点数
    43     # 进行翻页
    44     for page in range(0, 10+1):
    45         print(f'==============开始爬取{caixi}的第{page+1}页==============')
    46         url = f'https://www.douguo.com/caipu/{caixi}/0/{page*20}'
    47         response = requests.get(url=url, headers=headers)
    48         # print(response.text)
    49         selector = parsel.Selector(response.text) # 解析selector
    50         # 选取页面中所有的li标签
    51         lis = selector.css('#left .mt25 ul li')
    52         # print(lis)
    53         for item in lis:
    54             # print(item)
    55             title = item.css('a::attr(title)').get() # 标题
    56             sender = item.css('div .headicon img::attr(alt)').get() # 分享人
    57             majorMaterial = item.css('.cook-info p::text').get() # 主要用料
    58             try:
    59                 rate = item.css('.score span:nth-child(2)::text').get() # 评分
    60             except:
    61                 rate = ''
    62             # try:
    63             #     bookmarks = item.css('.score span').re('[收藏人数]\d+') # 收藏人数
    64             # except:
    65             #     bookmarks = '无'
    66             detailPage = 'https://www.douguo.com' + item.css('a::attr(href)').get() # 详情页
    67             imgLink = item.css('.cook-img img::attr(src)').get() #图片链接
    68             # print(title, sender, majorMaterial, rate, detailPage, imgLink, sep=' | ')
    69             ws.append([caixi, title, sender, majorMaterial, rate, detailPage, imgLink])
    70         print(f'==========={caixi}第{str(page+1)}页提取完成->>>>>>>>>>')
    71         time.sleep(2)
    72 
    73 endTime = time.time()
    74 wb.save('豆果美食菜谱.xlsx')
    75 print('共用时:', round((endTime-startTime)/60, 2), '分钟!')

    数据清洗

    按照自己习惯清洗数据。

     1 import pandas as pd
     2 
     3 df = pd.read_excel('豆果美食菜谱.xlsx')
     4 # 去重
     5 df = df.drop_duplicates()
     6 # 按行去空值
     7 df = df.dropna(how='any', axis=0)
     8 # 评分字段清洗,把分去掉
     9 df['评分'] = df['评分'].str.replace('', '').astype('float') # 将分去掉并转换成浮点型
    10 # 用料字段
    11 df['用料'] = df['用料'].str.replace('', ',') # 将中文逗号替换成西文逗号

    数据清洗完后就可以可视化了。

    数据可视化

    可视化一下评分分布:

     1 # 菜谱评分分布
     2 from pyecharts.charts import Page, Pie
     3 import pyecharts.options as opts
     4 from pyecharts.globals import ThemeType
     5 
     6 cut = lambda x : '4分以下' if x < 4 else ('4.1-4.5分' if x <= 4.5 else('4.6-4.9分' if x <= 4.9 else '5分'))
     7 print(cut)
     8 df['评分分布'] = df['评分'].map(cut)
     9 # print(df['评分分布'])
    10 df2 = df.groupby('评分分布')['评分'].count()
    11 df2 = round(df2, 2)
    12 print(df2)
    13 
    14 pie = (
    15     Pie()
    16     .add('', [list(z) for z in zip(df2.index.tolist(), df2.tolist())], radius=['20%', '80%'], rosetype='area')
    17     .set_global_opts(
    18         title_opts=opts.TitleOpts('菜谱评分分布'),
    19         legend_opts=opts.LegendOpts(
    20             pos_left='10%', pos_top='10%',
    21             orient='vertical',
    22             textstyle_opts=opts.TextStyleOpts(font_size=14),
    23         ),
    24     )
    25     .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%",font_size=18),)
    26 ).render('菜谱评分分布.html')

    运行后结果:

     

    各系菜系数量对比:

     1 # 各菜系菜谱数量对比
     2 from pyecharts import options as opts
     3 from pyecharts.charts import Page, Pie
     4 df3 = df.groupby('菜系')['评分'].count() #按菜系分组,对评分统计
     5 df3 = df3.sort_values(ascending=False) # 降序
     6 print(df3)
     7 
     8 p = (
     9     Pie(init_opts=opts.InitOpts(width='1080px', height='500px', theme=ThemeType.VINTAGE))
    10     .add(series_name='', center =[560, 270],data_pair= [list(z) for z in zip(df3.index.tolist(), df3.tolist())])
    11     .set_global_opts(
    12         title_opts=opts.TitleOpts(
    13             title='各菜系菜谱数量对比',
    14             title_textstyle_opts=opts.TextStyleOpts(font_size=35),
    15         subtitle='数据来源,豆果美食!'
    16         ),
    17         legend_opts=opts.LegendOpts(
    18             orient='vertical',
    19             pos_left='15%',
    20             pos_top='15%',
    21             textstyle_opts=opts.TextStyleOpts(font_size=14),
    22         ),
    23     )
    24     .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%", font_size=18))
    25 ).render('各菜系菜谱数量分布图.html')

    运行结果如下:

     

    各菜系评分均值对比:

     1 df4 = df.groupby('菜系')['评分'].mean() #计算平均值
     2 df4 = df4.sort_values(ascending=False) #降序
     3 df4 = df4.round(2) # 保留两位小数
     4 
     5 c = (
     6     Pie(init_opts=opts.InitOpts(width='1080px', height='500px', theme=ThemeType.VINTAGE))
     7     .add(series_name='', center=[560, 280], data_pair=[list(z) for z in zip(df4.index.tolist(), df4.tolist())], radius=['20%','80%'])
     8     .set_global_opts(
     9         title_opts=opts.TitleOpts(
    10             title='各菜系评分均值',
    11             title_textstyle_opts=opts.TextStyleOpts(font_size=35),
    12             subtitle='数据来源:豆果美食!',
    13         ),
    14         legend_opts=opts.LegendOpts(
    15             orient='vertical',
    16             pos_left='15%',
    17             pos_top='15%',
    18             textstyle_opts=opts.TextStyleOpts(font_size=15),
    19         ),
    20     )
    21     .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}"))
    22 ).render('各菜系评分均值.html')

    运行结果展示:

     

  • 相关阅读:
    高中数学常见角的范围及其表示
    立体几何习题
    常见的建系类型汇总
    双曲线
    分式不等式习题
    廓清集合中的几个问题
    二次函数
    随机变量的期望和方差
    不等式选讲习题
    JS中every()和some()的用法
  • 原文地址:https://www.cnblogs.com/mafu/p/15576421.html
Copyright © 2011-2022 走看看