中秋节月饼不知道买哪种?Python爬取4000种月饼类别告诉你答案!

Posted Dragon少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中秋节月饼不知道买哪种?Python爬取4000种月饼类别告诉你答案!相关的知识,希望对你有一定的参考价值。

前言

马上临近中秋了,月饼的销量持续增长,也推出了各个不同口味类别的月饼,价格差异也较大。我们究竟应该买哪种月饼呢?今天就一起用Python爬取某宝月饼信息,并对爬取的数据进行可视化分析,一起来看看哪种月饼最受欢迎,哪家店铺月饼销量最高吧~

直接跳到文末获取粉丝专属福利。

一、核心功能设计

总体来说,我们需要先从网站爬虫获取月饼数据,并将这些数据进行清洗,最后可视化分析展示。拆解需求,大致可以整理出我们需要分为以下几步完成:

  1. 通过爬虫获取月饼数据,主要包括月饼名称、销量、店铺、省份城市等。
  2. 对获取的数据进行预处理清洗,统一销量数据单位、省份城市等,获取清洗后的各个月饼数量。
  3. 对清洗的数据进行可视化展示,主要包括热销月饼口味TOP10、热销月饼店铺Top10、月饼价格区间分布、各省份城市月饼销量分布情况等。

二、实现步骤

1. 爬取数据

本文我们通过selenium模块进行月饼数据爬取。为了保证数据爬取顺利,首先我们需要安装selenium模块,通过pip指令即可安装。

pip install selenium

如果第一次安装使用selenium,不少人有可能会出现以下异常,那该怎么解决呢?

出现的主要原因是因为selenium模拟的客户端对浏览器的操作,但相应浏览器的驱动版本不匹配导致的。所以我们需要先了解我们当前浏览器的版本,可以打开浏览器,地址栏输入chrome://version/查看到谷歌当前的版本号。

这样我们就可以到谷歌浏览器驱动找到对应版本下载驱动就可以了。下载解压之后,可以看到chromedriver.exe。

我们需要把它拷贝到Python路径下面,至此我们就可以正常使用selenium模拟客户端浏览器操作了。
接下来我们进行网页分析,获取对应的月饼名称、店铺名、销售量、价格、地区。根据对数据分析,可以发现:

  • 各个月饼信息都在item的class=“item J_MouserOnverReq”
  • 月饼名称对应的class=“row row-2 title”
  • 价格对应的strong标签
  • 付款人数对应class=“deal-cnt”
  • 店铺信息在class="shop"中
  • 发货地区对应class=“location”


网页结构我们上面已经分析好了,那么我们就可以来动手爬取我们所需要的数据了,获取到所有的数据资源之后,可以把这些数据保存下来。

获取商品:

# author:Dragon少年
# 获取商品
def get_product(key_word):
    # 定位输入框
    browser.find_element_by_id("q").send_keys(key_word)
    # 定义点击按钮,并点击
    browser.find_element_by_class_name('btn-search').click()
    browser.maximize_window()
    # 等待20秒,方便手动登录
    time.sleep(20)
    # 定位这个“页码”,获取“共100页这个文本”
    page_info = browser.find_element_by_xpath('//div[@class="total"]').text
    # findall()返回的是一个列表
    page = re.findall("(\\d+)", page_info)[0]
    return page

获取数据:

# author:Dragon少年
# 获取数据
def get_data():
    # 所有的信息都在items节点下
    items = browser.find_elements_by_xpath('//div[@class="items"]/div[@class="item J_MouserOnverReq  "]')
    for item in items:
        pro_desc = item.find_element_by_xpath('.//div[@class="row row-2 title"]/a').text
        # 价格
        pro_price = item.find_element_by_xpath('.//strong').text
        # 付款人数
        buy_num = item.find_element_by_xpath('.//div[@class="deal-cnt"]').text
        # 店铺
        shop = item.find_element_by_xpath('.//div[@class="shop"]/a').text
        # 发货地
        address = item.find_element_by_xpath('.//div[@class="location"]').text
        with open('{}.csv'.format(key_word), mode='a', newline='', encoding='utf-8-sig') as f:
            csv_writer = csv.writer(f, delimiter=',')
            csv_writer.writerow([pro_desc, pro_price, buy_num, shop, address])

selenium模拟爬取:

# author:Dragon少年
key_word = input("请输入您要搜索的商品:")
    browser = webdriver.Chrome()
    browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {

        "source": """
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
        })
      """
    })
    browser.get('https://www.taobao.com/')
    page = get_product(key_word)
    print(page)
    get_data()
    page_num = 1
    while int(page) != page_num:
        print("=" * 100)
        print("正在爬取第{}页".format(page_num + 1))
        browser.get('https://s.taobao.com/search?q={}&s={}'.format(key_word, page_num * 44))
        browser.implicitly_wait(15)
        get_data()
        page_num += 1
    print("爬取结束!")

至此我们就可以爬取月饼的数据并保存下来,如下图所示。

2. 数据清洗

接下来我们需要把爬虫获取的数据进行清洗,首先可以去除重复数据,删除没有人购买的记录。核心代码如下:

# author:Dragon少年
# 读取爬虫数据
df = pd.read_csv("月饼.csv", encoding='utf-8-sig', header=None)
df.columns = ["商品名", "价格", "购买人数", "店铺", "地址"]
# 去除重复的数据
df.drop_duplicates(inplace=True)
print(df.shape)
# 删除购买人数0的记录
df['购买人数'] = df['购买人数'].replace(np.nan,'0人付款')

对于购买人数,有些是按照万为单位显示,我们需要将销售量进行统一,并将发货地区进行整理出各个省份信息,最后将这些清洗的数据保存下来。核心代码如下:

df['num'] = [re.findall(r'(\\d+\\.{0,1}\\d*)', i)[0] for i in df['购买人数']]  # 提取数值
df['num'] = df['num'].astype('float')  # 转化数值型
# 提取单位(万)
df['unit'] = [''.join(re.findall(r'(万)', i)) for i in df['购买人数']]  # 提取单位(万)
df['unit'] = df['unit'].apply(lambda x:10000 if x=='万' else 1)
# 计算销量
df['销量'] = df['num'] * df['unit']

# 删除没有发货地址的店铺数据 获取省份
df = df[df['地址'].notna()]
df['省份'] = df['地址'].str.split(' ').apply(lambda x:x[0])
# 删除多余的列
df.drop(['购买人数', '地址', 'num', 'unit'], axis=1, inplace=True)
# 重置索引
df = df.reset_index(drop=True)
df.to_csv('月饼清洗数据.csv')

至此我们就可以把爬取的月饼数据整理清洗完毕,如下图所示。

3. 可视化分析

接下来我们就需要对数据进行可视化显示, 这里使用的是pyecharts,是一个用于生成Echarts图表的类库,便于在Python中根据数据生成可视化的图表。

之前博主有写过一篇关于pyecharts的文章,里面很详细的介绍了各类图表的使用方法和案例,不会的可以先去学习下pyecharts相关的内容。【一文学会炫酷图表利器pyecharts】

销量Top10店铺:

下面我们可以读取清洗结束的数据,通过对店铺分组获取各个店铺的月饼销量数据,统计出销量前十的店铺,通过柱状图显示。核心代码如下:

# 计算月饼总销量Top10的店铺
shop_top10 = df.groupby('店铺')['销量'].sum().sort_values(ascending=False).head(10)
# 绘制柱形图
bar1 = Bar(init_opts=opts.InitOpts(width='600px', height='450px')) 
bar1.add_xaxis(shop_top10.index.tolist())
bar1.add_yaxis('销量', shop_top10.values.tolist()) 
bar1.set_global_opts(title_opts=opts.TitleOpts(title='销量Top10店铺-Dragon少年'),
                     xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-30))) 
bar1.render("销量Top10店铺-Dragon少年.html")
bar1.render_notebook()


我们可以看到稻香村食品店、天猫超市、华美食品、臻味食品等销量居前,其中销量最好的是稻香村,总销量遥遥领先。

销量Top10月饼:

我们还可以通过对月饼名称进行月饼分组获取销量最好的月饼,统计出销量前十的月饼,通过柱状图显示。核心代码如下:

# 计算销量top10月饼
shop_top10 = df.groupby('商品名')['销量'].sum().sort_values(ascending=False).head(10)

# 绘制柱形图
bar0 = Bar(init_opts=opts.InitOpts(width='750px', height='450px')) 
bar0.add_xaxis(shop_top10.index.tolist())
bar0.add_yaxis('销量', shop_top10.values.tolist()) 
bar0.set_global_opts(title_opts=opts.TitleOpts(title='销量Top10月饼-Dragon少年'),
                     xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-30))) 
bar0.render("销量Top10月饼-Dragon少年.html")
bar0.render_notebook()


我们可以看到最受欢迎的10种月饼,其中的稻香村月饼礼盒装最受欢迎,销量达到了50w份。

不同价格月饼销量占比:

我们接下来还可以根据月饼的价格区间进行划分,统计50元以下,50-150元,150-500元,500元以上的各个价格区间月饼的销量分布,并通过饼图进行可视化显示。核心代码如下:

def price_range(x): #按照淘宝推荐划分价格区间
    if x <= 50:
        return '50元以下'
    elif x <= 150:
        return '50-150元'
    elif x <= 500:
        return '150-500元'
    else:
        return '500元以上'
df['price_range'] = df['价格'].apply(lambda x: price_range(x)) 
price_cut_num = df.groupby('price_range')['销量'].sum() 
data_pair = [list(z) for z in zip(price_cut_num.index, price_cut_num.values)]
# 饼图
pie1 = Pie(init_opts=opts.InitOpts(width='750px', height='350px'))
# 内置富文本
pie1.add( 
        series_name="销量",
        radius=["35%", "55%"],
        data_pair=data_pair,
        label_opts=opts.LabelOpts(formatter='{b}—占比{d}%'),
)
pie1.set_global_opts(legend_opts=opts.LegendOpts(pos_left="left", pos_top='30%', orient="vertical"), 
                     title_opts=opts.TitleOpts(title='不同价格月饼销量占比-Dragon少年'))
pie1.render("不同价格月饼销量占比-Dragon少年.html")
pie1.render_notebook()


可以看出来,月饼的销售价格主要分布在≤150元之间,占据了销量的84%左右,单份月饼价格超过500元的购买的人较少。

各省月饼销量分布:

最好我们在统计下,月饼的产地销量分布省份地区,并通过地图可视化显示。核心代码如下:

# 计算销量
province_num = df.groupby('省份')['销量'].sum().sort_values(ascending=False) 
# 绘制地图
map1 = Map(init_opts=opts.InitOpts(width='750px', height='350px'))
map1.add("", [list(z) for z in zip(province_num.index.tolist(), province_num.values.tolist())],
         maptype='china'
        ) 
map1.set_global_opts(title_opts=opts.TitleOpts(title='各省月饼销量分布-Dragon少年'),
                     visualmap_opts=opts.VisualMapOpts(max_=300000)
                    )
map1.render("各省月饼销量分布-Dragon少年.html")
map1.render_notebook()


可以看到月饼的销售地分布最多的是广东和浙江省,这两个省月饼销量最受欢迎。至此,月饼数据爬虫及分析可视化就完成啦~ 大家看完分析想好买什么月饼了吗?

源码及数据已上传,关注文末公众号回复【月饼源码】即可获取完整源码

Python往期精彩:

以上是关于中秋节月饼不知道买哪种?Python爬取4000种月饼类别告诉你答案!的主要内容,如果未能解决你的问题,请参考以下文章

爬取淘宝上4000条月饼数据,制作了一个酷炫的可视化大屏!

最好吃的月饼!用Python爬取了某宝1166家月饼进行可视化分析!

中秋节快到了,别学Python了,进来排队领块月饼吧纯手工哪种!

万万没想到 一盒月饼火了!这款秘制Python月饼,拿走不谢!

中秋征文使用Python创意中秋节画月饼《花好月圆》

新手学stm32学f1还是f4,stm32初学者最好买哪种开发板?