【云驻共创】爬取某购物平台 "月饼" 数据,用Python做了一个可视化大屏!
朋友们,一年一度的中秋悄然而至,为了响应华为云
这次活动,特意写了这篇文章,希望能和大家一起学习。
中秋节介绍
中秋节,又称拜月节。中秋节自古便有祭月、赏月、吃月饼、玩花灯、赏桂花、饮桂花酒等民俗,流传至今,经久不息。中秋节以月之圆兆人之团圆,为寄托思念故乡,思念亲人之情,祈盼丰收、幸福,成为丰富多彩、弥足珍贵的文化遗产。
又是一年中秋节,你准备买一些什么月饼,去走亲戚了,赶紧看看这篇文章。
selenium模块的安装与配置
这次爬取某购物平台,采用的是最简单的方式:Selenium控制Chrome浏览器进行自动化操作,中途只需要扫码登陆一次,即可完成整个数据的爬取。
1)安装selenium库
pip install selenium
检验是否安装成功:
2)chromedriver驱动的配置
配置chromedriver驱动,一定要注意“驱动”和“谷歌浏览器”版本一定是要相匹配,否则不能使用。
① 检查谷歌浏览器的版本
这里首先提供一个详细的地址供大家查看:
https://jingyan.baidu.com/article/95c9d20d74a1e8ec4f756149.html
点击“右上角三个点” --> 点击“设置” --> 点击 “关于chrome”,出现如下界面。
② 下载chromedriver驱动
这里再次提供一个详细的地址,供大家选择各种版本驱动程序:
http://chromedriver.storage.googleapis.com/index.html
从上面的图中可以看出,谷歌浏览器的版本是【81.0.4044.138】,这里我们选择的对应版本的驱动,如下图所示。
点进该文件后,可以根据我们的操作系统,选择对应的驱动。
③ chromedriver驱动的配置
解压上述下载好的文件,并将解压后我们得到的chromedriver.exe文件,需要放到python的安装路径下(和python.exe放在一起)。
首先,你可以查看你的python解释器安装在哪里!
然后,将chromedriver.exe放置和python.exe在一起。
3)检验selenium是否可用
使用如下两行代码,如果谷歌浏览器成功被驱动打开,证明上述安装和配置没问题。
from selenium import webdriver
browser = webdriver.Chrome()
结果如下:
4)一个小案例展示selenium的操作效果
from selenium import webdriver
import time
# 创建浏览器对象,该操作会自动帮我们打开Google浏览器窗口
browser = webdriver.Chrome()
# 调用浏览器对象,向服务器发送请求。该操作会打开Google浏览器,并跳转到“百度”首页
browser.get("https://www.baidu.com/")
# 最大化窗口
browser.maximize_window()
# 定位“抗击肺炎”链接内容
element = browser.find_element_by_link_text("抗击肺炎")
# 为了更好的展示这个效果,我们等待3秒钟
time.sleep(3)
# 点击上述链接
element.click()
# 我们再让浏览器停留3秒钟后,再关闭浏览器
time.sleep(3)
# 操作会自动关闭浏览器
browser.close()
"""
效果这里就不展示了,大家自行下去尝试!
"""
爬虫完整带啊吗
from selenium import webdriver
import time
import csv
import re
# 搜索商品,获取商品页码
def search_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()
# 等待15秒,给足时间我们扫码
time.sleep(15)
# 定位这个“页码”,获取“共100页这个文本”
page_info = browser.find_element_by_xpath('//div[@class="total"]').text
# 需要注意的是:findall()返回的是一个列表,虽然此时只有一个元素它也是一个列表。
page = re.findall("(\d+)",page_info)[0]
return page
# 获取数据
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
#print(pro_desc, pro_price, buy_num, shop, address)
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])
def main():
browser.get('https://www.taobao.com/')
page = search_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("数据爬取完毕!")
if __name__ == '__main__':
key_word = input("请输入你要搜索的商品:")
browser = webdriver.Chrome()
main()
数据清洗
数据清洗很重要,这个对于我们后续做可视化展示,极其重要。因此我们需要根据后面要做的图形,然后进行对应的进行数据清洗。
爬取到的原始数据如下:
整个数据看上去算是比较干净,但是还是有几个地方指的我们处理一下。
- 1.爬取到的原始数据没有列名,我们需要添加一个新列名;
- 2.整个爬虫过程中,会出现重复数据,我们需要提前去重处理;
- 3.将购买人数为空的记录,替换成0人付款;
- 4.将购买人数转换为销量(注意部分单位为万);
- 5.删除无发货地址的商品,并提取其中的省份;
# 导包
import pandas as pd
import numpy as np
import re
# 导入爬取得到的数据
df = pd.read_csv("月饼.csv", engine='python', encoding='utf-8-sig', header=None)
df.columns = ["商品名", "价格", "付款人数", "店铺", "发货地址"]
df.head(10)
# 去除重复值
print(df.shape)
df.drop_duplicates(inplace=True)
print(df.shape)
# 处理购买人数为空的记录
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',encoding="gbk")
看看清洗后的数据:
数据可视化
可视化是整个文章的亮点所在,所谓“字不如表、表不如图”。整个可视化大屏我们基于以下五个问题开展而来。
- 1.月饼销量Top10的柱形图;
- 2.店铺月饼销量Top10的柱形图;
- 3.不同价格区间的月饼销量圆环图;
- 4.月饼销售关键字的词云图;
1)月饼销量Top10的柱形图
# 导入包
from pyecharts.charts import Bar
from pyecharts import options as opts
# 计算top10店铺
shop_top10 = df.groupby('商品名')['销量'].sum().sort_values(ascending=False).head(10)
# 绘制柱形图
bar0 = Bar(init_opts=opts.InitOpts(width='750px', height='350px'))
bar0.add_xaxis(shop_top10.index.tolist())
bar0.add_yaxis('sales_num', shop_top10.values.tolist())
bar0.set_global_opts(title_opts=opts.TitleOpts(title='月饼商品销量Top10'),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-30)))
#bar0.render("月饼商品销量Top10.html")
bar0.render_notebook()
结果如下:
2)店铺月饼销量Top10的柱形图
# 导入包
from pyecharts.charts import Bar
from pyecharts import options as opts
# 计算top10店铺
shop_top10 = df.groupby('店铺')['销量'].sum().sort_values(ascending=False).head(10)
# 绘制柱形图
bar1 = Bar(init_opts=opts.InitOpts(width='750px', height='350px'))
bar1.add_xaxis(shop_top10.index.tolist())
bar1.add_yaxis('sales_num', shop_top10.values.tolist())
bar1.set_global_opts(title_opts=opts.TitleOpts(title='月饼店铺销量Top10'),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-30)))
#bar1.render("月饼店铺销量Top10.html")
bar1.render_notebook()
结果如下:
3)不同价格区间的月饼销量圆环图
from pyecharts.charts import Pie
def price_range(x): #按照它们推荐划分价格区间
if x <= 22:
return '22元以下'
elif x <= 115:
return '22-115元'
elif x <= 633:
return '115-633元'
else:
return '633元以上'
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)]
print(data_pair)
# 饼图
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='不同价格区间的月饼销量占比'))
#pie1.render("不同价格区间的月饼销量占比.html")
pie1.render_notebook()
结果如下:
4)月饼销售关键字的词云图
import jieba
import jieba.analyse
txt = df['商品名'].str.cat(sep='。')
# 添加关键词
jieba.add_word('粽子', 999, '五芳斋')
# 读入停用词表
stop_words = []
with open('stop_words.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
for line in lines:
stop_words.append(line.strip())
# 添加停用词
stop_words.extend(['logo', '10', '100', '200g', '100g', '140g', '130g', '月饼', '礼盒装'])
# 评论字段分词处理
word_num = jieba.analyse.extract_tags(txt,
topK=100,
withWeight=True,
allowPOS=())
# 去停用词
word_num_selected = []
for i in word_num:
if i[0] not in stop_words:
word_num_selected.append(i)
key_words = pd.DataFrame(word_num_selected, columns=['words','num'])
结果如下:
- 点赞
- 收藏
- 关注作者
评论(0)