前言
唯品會是中國領先的在線特賣會電商平臺之一,它以“品牌特賣會”的模式運營,為會員提供品牌折扣商品。唯品會的商品包括服裝、鞋類、箱包、美妝、家居、母嬰、食品等各類品牌產(chǎn)品。
這就是今天的受害者,我們要拿取上面的泳衣數(shù)據(jù),然后可以做些數(shù)據(jù)可視化
數(shù)據(jù)來源分析
1. 明確需求
- 明確采集網(wǎng)站以及數(shù)據(jù)
網(wǎng)址: https://category.vip.com/suggest.php?keyword=%E6%B3%B3%E8%A1%A3&ff=235|12|1|1
數(shù)據(jù): 商品信息
2. 抓包分析:通過瀏覽器自帶工具: 開發(fā)者工具
- 打開開發(fā)者工具: F12 / 右鍵點擊檢查選擇network
- 刷新網(wǎng)頁: 讓網(wǎng)頁數(shù)據(jù)重新加載一遍
- 搜索關鍵字: 搜索數(shù)據(jù)在哪里
找到數(shù)據(jù)包: 50條商品數(shù)據(jù)信息
整頁數(shù)據(jù)內(nèi)容: 120條 --> 分成三個數(shù)據(jù)包
1. 前50條數(shù)據(jù) --> 前50個商品ID
2. 中50條數(shù)據(jù) --> 中50個商品ID
3. 后20條數(shù)據(jù) --> 后20個商品ID
已知: 數(shù)據(jù)分為三組 --> 對比三組數(shù)據(jù)包請求參數(shù)變化規(guī)律
請求參數(shù)變化規(guī)律: 商品ID
分析找一下 是否存在一個數(shù)據(jù)包, 包含所有商品ID
如果想要獲取商品信息 --> 先獲取所有商品ID --> ID存在數(shù)據(jù)包
代碼實現(xiàn)步驟: 發(fā)送請求 -> 獲取數(shù)據(jù) -> 解析數(shù)據(jù) -> 保存數(shù)據(jù)
發(fā)送請求
我們定義了要爬取的URL地址,并設置了User-Agent請求頭,以模擬瀏覽器發(fā)送請求。
使用requests.get方法發(fā)送GET請求,并將響應保存在response變量中。
headers = {
# 防盜鏈 告訴服務器請求鏈接地址從哪里跳轉過來
'Referer': 'https://category.vip.com/',
# 用戶代理, 表示瀏覽器基本身份信息
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
}
# 請求鏈接
url = 'https://mapi.vip.com/vips-mobile/rest/shopping/pc/search/product/rank'
data = {
# 回調(diào)函數(shù)
# 'callback': 'getMerchandiseIds',
'app_name': 'shop_pc',
'app_version': '4.0',
'warehouse': 'VIP_HZ',
'fdc_area_id': '104103101',
'client': 'pc',
'mobile_platform': '1',
'province_id': '104103',
'api_key': '70f71280d5d547b2a7bb370a529aeea1',
'user_id': '',
'mars_cid': '1689245318776_e2b4a7b51f99b3dd6a4e6d356e364148',
'wap_consumer': 'a',
'standby_id': 'nature',
'keyword': '泳衣',
'lv3CatIds': '',
'lv2CatIds': '',
'lv1CatIds': '',
'brandStoreSns': '',
'props': '',
'priceMin': '',
'priceMax': '',
'vipService': '',
'sort': '0',
'pageOffset': '0',
'channelId': '1',
'gPlatform': 'PC',
'batchSize': '120',
'_': '1689250387620',
}
# 發(fā)送請求 --> <Response [200]> 響應對象
response = requests.get(url=url, params=data, headers=headers)
解析數(shù)據(jù)
然后,我們定義了起始標簽和結束標簽,通過循環(huán)的方式遍歷文本,并提取每個商品的名稱和價格。
# 商品ID -> 120個
products = [i['pid'] for i in response.json()['data']['products']]
# 把120個商品ID 分組 --> 切片 起始:0 結束:50 步長:1
# 列表合并成字符串
product_id_1 = ','.join(products[:50]) # 提取前50個商品ID 0-49
product_id_2 = ','.join(products[50:100]) # 提取中50個商品ID 50-99
product_id_3 = ','.join(products[100:]) # 提取后20個商品ID 100到最后
product_id_list = [product_id_1, product_id_2, product_id_3]
for product_id in product_id_list:
# 請求鏈接
link = 'https://mapi.vip.com/vips-mobile/rest/shopping/pc/product/module/list/v2'
# 請求參數(shù)
params = {
# 'callback': 'getMerchandiseDroplets2',
'app_name': 'shop_pc',
'app_version': '4.0',
'warehouse': 'VIP_HZ',
'fdc_area_id': '104103101',
'client': 'pc',
'mobile_platform': '1',
'province_id': '104103',
'api_key': '70f71280d5d547b2a7bb370a529aeea1',
'user_id': '',
'mars_cid': '1689245318776_e2b4a7b51f99b3dd6a4e6d356e364148',
'wap_consumer': 'a',
'productIds': product_id,
'scene': 'search',
'standby_id': 'nature',
'extParams': '{"stdSizeVids":"","preheatTipsVer":"3","couponVer":"v2","exclusivePrice":"1","iconSpec":"2x","ic2label":1,"superHot":1,"bigBrand":"1"}',
'context': '',
'_': '1689250387628',
}
# 發(fā)送請求
json_data = requests.get(url=link, params=params, headers=headers).json()
for index in json_data['data']['products']:
# 商品信息
attr = ','.join([j['value'] for j in index['attrs']])
# 創(chuàng)建字典
dit = {
'標題': index['title'],
'品牌': index['brandShowName'],
'原價': index['price']['marketPrice'],
'售價': index['price']['salePrice'],
'折扣': index['price']['mixPriceLabel'],
'商品信息': attr,
'詳情頁': f'https://detail.vip.com/detail-{index["brandId"]}-{index["productId"]}.html',
}
csv_writer.writerow(dit)
print(dit)
保存數(shù)據(jù)
然后,我們使用open函數(shù)創(chuàng)建一個CSV文件,并指定文件名、寫入模式、編碼方式等參數(shù)。然后使用csv.DictWriter初始化一個寫入器對象,并指定表頭。
我們使用writer.writeheader()來寫入CSV文件的表頭,然后遍歷items列表,使用writer.writerow()將每個商品的數(shù)據(jù)寫入CSV文件中。
f = open('商品.csv', mode='a', encoding='utf-8', newline='')
csv_writer = csv.DictWriter(f, fieldnames=[
'標題',
'品牌',
'原價',
'售價',
'折扣',
'商品信息',
'詳情頁',
])
csv_writer.writeheader()
數(shù)據(jù)可視化
先讀取數(shù)據(jù)
df = pd.read_csv('商品.csv')
df.head()
泳衣商品性別占比
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.faker import Faker
c = (
Bar()
.add_xaxis(sex_type)
.add_yaxis("", sex_num)
.set_global_opts(
title_opts=opts.TitleOpts(title="泳衣商品性別占比", subtitle=""),
brush_opts=opts.BrushOpts(),
)
)
c.load_javascript()
from pyecharts import options as opts
from pyecharts.charts import Pie
c = (
Pie()
.add("", [list(z) for z in zip(sex_type, sex_num)])
.set_global_opts(title_opts=opts.TitleOpts(title="泳衣商品性別占比"))
.set_series_opts(label_opts=opts.LabelOpts(formatter=": {c}"))
)
c.render_notebook()
商品品牌分布占比
shop_num = df['品牌'].value_counts().to_list()
shop_type = df['品牌'].value_counts().index.to_list()
c = (
Pie()
.add(
"",
[
list(z)
for z in zip(shop_type, shop_num)
],
center=["40%", "50%"],
)
.set_global_opts(
title_opts=opts.TitleOpts(title="商品品牌分布占比"),
legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical"),
)
.set_series_opts(label_opts=opts.LabelOpts(formatter=": {c}"))
)
c.render_notebook()
各大品牌商品售價平均價格
# 按城市分組并計算平均薪資
avg_salary = df.groupby('品牌')['售價'].mean()
ShopType = avg_salary.index.tolist()
ShopNum = [int(a) for a in avg_salary.values.tolist()]
# 創(chuàng)建柱狀圖實例
c = (
Bar()
.add_xaxis(ShopType)
.add_yaxis("", ShopNum)
.set_global_opts(
title_opts=opts.TitleOpts(title="各大品牌商品售價平均價格"),
visualmap_opts=opts.VisualMapOpts(
dimension=1,
pos_right="5%",
max_=30,
is_inverse=True,
),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)) # 設置X軸標簽旋轉角度為45度
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(type_="min", name="最小值"),
opts.MarkLineItem(type_="max", name="最大值"),
opts.MarkLineItem(type_="average", name="平均值"),
]
),
)
)
c.render_notebook()
各大品牌商品原價平均價格
# 按城市分組并計算平均薪資
avg_salary = df.groupby('品牌')['原價'].mean()
ShopType_1 = avg_salary.index.tolist()
ShopNum_1 = [int(a) for a in avg_salary.values.tolist()]
# 創(chuàng)建柱狀圖實例
c = (
Bar()
.add_xaxis(ShopType_1)
.add_yaxis("", ShopNum_1)
.set_global_opts(
title_opts=opts.TitleOpts(title="各大品牌商品原價平均價格"),
visualmap_opts=opts.VisualMapOpts(
dimension=1,
pos_right="5%",
max_=30,
is_inverse=True,
),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)) # 設置X軸標簽旋轉角度為45度
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(type_="min", name="最小值"),
opts.MarkLineItem(type_="max", name="最大值"),
opts.MarkLineItem(type_="average", name="平均值"),
]
),
)
)
c.render_notebook()
文章來源:http://www.zghlxwxcb.cn/news/detail-609495.html
唯品會泳衣商品售價價格區(qū)間
pie1 = (
Pie(init_opts=opts.InitOpts(theme='dark',width='1000px',height='600px'))
.add('', datas_pair_2, radius=['35%', '60%'])
.set_series_opts(label_opts=opts.LabelOpts(formatter=":n5n3t3z%"))
.set_global_opts(
title_opts=opts.TitleOpts(
title="唯品會泳衣商品\n\n售價價格區(qū)間",
pos_left='center',
pos_top='center',
title_textstyle_opts=opts.TextStyleOpts(
color='#F0F8FF',
font_size=20,
font_weight='bold'
),
)
)
.set_colors(['#EF9050', '#3B7BA9', '#6FB27C', '#FFAF34', '#D8BFD8', '#00BFFF', '#7FFFAA'])
)
pie1.render_notebook()
文章來源地址http://www.zghlxwxcb.cn/news/detail-609495.html
??問題解答 · 源碼獲取 · 技術交流 · 抱團學習請聯(lián)系??
到了這里,關于Python爬蟲+數(shù)據(jù)可視化:分析唯品會商品數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!