Python爬虫+数据可视化:分析唯品会商品数据
目录
- 前言
- 数据来源分析
- 1. 明确需求
- 2. 抓包分析:通过浏览器自带工具: 开发者工具
- 代码实现步骤: 发送请求 -> 获取数据 -> 解析数据 -> 保存数据
- 发送请求
- 解析数据
- 保存数据
- 数据可视化
- 先读取数据
- 泳衣商品性别占比
- 商品品牌分布占比
- 各大品牌商品售价平均价格
- 各大品牌商品原价平均价格
- 唯品会泳衣商品售价价格区间
前言
唯品会是中国领先的在线特卖会电商平台之一,它以“品牌特卖会”的模式运营,为会员提供品牌折扣商品。唯品会的商品包括服装、鞋类、箱包、美妆、家居、母婴、食品等各类品牌产品。
这就是今天的受害者,我们要拿取上面的泳衣数据,然后可以做些数据可视化
数据来源分析
1. 明确需求
- 明确采集网站以及数据
网址: https://category.vip.com/suggest.php?keyword=%E6%B3%B3%E8%A1%A3&ff=235|12|1|1
数据: 商品信息
2. 抓包分析:通过浏览器自带工具: 开发者工具
- 打开开发者工具: F12 / 右键点击检查选择network
- 刷新网页: 让网页数据重新加载一遍
- 搜索关键字: 搜索数据在哪里
找到数据包: 50条商品数据信息
整页数据内容: 120条 --> 分成三个数据包
1. 前50条数据 --> 前50个商品ID
2. 中50条数据 --> 中50个商品ID
3. 后20条数据 --> 后20个商品ID
已知: 数据分为三组 --> 对比三组数据包请求参数变化规律
请求参数变化规律: 商品ID
分析找一下 是否存在一个数据包, 包含所有商品ID
如果想要获取商品信息 --> 先获取所有商品ID --> ID存在数据包
代码实现步骤: 发送请求 -> 获取数据 -> 解析数据 -> 保存数据
发送请求
我们定义了要爬取的URL地址,并设置了User-Agent请求头,以模拟浏览器发送请求。
使用requests.get方法发送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 = {# 回调函数# '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',
}
# 发送请求 --> <Response [200]> 响应对象
response = requests.get(url=url, params=data, headers=headers)
解析数据
然后,我们定义了起始标签和结束标签,通过循环的方式遍历文本,并提取每个商品的名称和价格。
# 商品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'# 请求参数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',}# 发送请求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']])# 创建字典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)
保存数据
然后,我们使用open函数创建一个CSV文件,并指定文件名、写入模式、编码方式等参数。然后使用csv.DictWriter初始化一个写入器对象,并指定表头。
我们使用writer.writeheader()来写入CSV文件的表头,然后遍历items列表,使用writer.writerow()将每个商品的数据写入CSV文件中。
f = open('商品.csv', mode='a', encoding='utf-8', newline='')
csv_writer = csv.DictWriter(f, fieldnames=['标题','品牌','原价','售价','折扣','商品信息','详情页',
])
csv_writer.writeheader()
数据可视化
先读取数据
df = pd.read_csv('商品.csv')
df.head()
泳衣商品性别占比
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.faker import Fakerc = (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 Piec = (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="{b}: {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="{b}: {c}"))
)
c.render_notebook()
各大品牌商品售价平均价格
# 按城市分组并计算平均薪资
avg_salary = df.groupby('品牌')['售价'].mean()
ShopType = avg_salary.index.tolist()
ShopNum = [int(a) for a in avg_salary.values.tolist()]
# 创建柱状图实例
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()]
# 创建柱状图实例
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()
唯品会泳衣商品售价价格区间
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="{b}:{d}%")).set_global_opts(title_opts=opts.TitleOpts(title="唯品会泳衣商品\n\n售价价格区间", 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()
👇问题解答 · 源码获取 · 技术交流 · 抱团学习请联系👇
相关文章:

Python爬虫+数据可视化:分析唯品会商品数据
目录 前言数据来源分析1. 明确需求2. 抓包分析:通过浏览器自带工具: 开发者工具 代码实现步骤: 发送请求 -> 获取数据 -> 解析数据 -> 保存数据发送请求解析数据保存数据 数据可视化先读取数据泳衣商品性别占比商品品牌分布占比各大品牌商品售价平均价格各…...

el-tree数据渲染超出省略
el-tree数据渲染超出省略 问题 <el-tree:data"deptOptions":props"defaultProps":expand-on-click-node"false":filter-node-method"filterNode"ref"tree"default-expand-allhighlight-currentnode-click"handleNo…...

若依vue -【 44】
44 服务监控讲解 1 需求 显示CPU、内存、服务器信息、Java虚拟机信息、磁盘状态的信息 2 前端 RuoYi-Vue\ruoyi-ui\src\views\monitor\server\index.vue <script> import { getServer } from "/api/monitor/server";export default {name: "Server&quo…...
React 基础篇(一)
💻 React 基础篇(一)🏠专栏:React 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向:目前主攻…...

Bean 的作用域和生命周期
目录 什么是 Bean 的作用域 ?Bean 的六种作用域Spring 的执行流程Bean 的生命周期 什么是 Bean 的作用域 ? Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份,…...
STP和MTP(第二十二课)
2、如何实现 1)在MSTP网络种,引入了域的概念,称为MST域 2)每一个MST域中包含一个或多个“生成树”称为“实例” 3)每个“实例生成树”都可以绑定vlan,实现vlan数据流的负载分担/负载均衡 4)默认情况下,所有的vlan都属于“实例树0:即:instance 0” 5)不同的“实例…...

Java-WebSocket
请点击下面工程名称,跳转到代码的仓库页面,将工程 下载下来 Demo Code 里有详细的注释 TestWebSocket...
elementui的el-date-picker选择日期范围第二个不能早于第一个
选择日期范围第二个不能早于第一个 <el-form-item label"预计施工时间:" required><el-form:model"form":rules"constructionDateRules"ref"constructionRef"inline:hide-required-asterisk"false"><el-form…...

【NLP】无服务器问答系统
一、说明 在NLP的眼见的应用,就是在“ 当你在谷歌上提出一个问题并立即得到答案时会发生什么?例如,如果我们在谷歌搜索中询问谁是美国总统,我们会得到以下回答:Joe Biden;这是一个搜索问题,同时…...

Dubbo
Dubbo 简介Dubbo的快速入门Dubbo的基本架构安装DubboAdmin入门案例Dubbo的最佳实践 Dubbo的高级特性启动检查多版本超时与重试负载均衡SpringCloud整合Dubbo案例 简介 Dubbo是阿里巴巴公司开源的一个高性能、轻量级的Java RPC框架。 致力于提高性能和透明化的RPC远程服务调用方…...
Java设计模式之策略(Strategy)模式
策略(Strategy)设计模式定义了一系列算法,将它们封装起来,并且可以相互替换使用,从而使得算法可以独立于使用它的客户而变化。 什么是策略模式 策略(Strategy)设计模式是一种行为型设计模式&a…...
Vue引入CDN JS或本地JS文件之后 使用报错
加载问题 正常情况 在public引入script - js文件加载 - 写入内存 - 使用 但使用之前 有可能这个文件还没执行写入内存或者还未加载完毕 此时 需要一个promiss解决 1. 引入script 在 public / index.html 文件内引入你的script标签 <script type"text/javascript"…...
NRF52832-扩展广播
nordic论坛 我想要设置广播名称为 “一二三四五”,当广播名称为FULL_NAME时,但是广播显示还是“一?”,“?”是乱码,后来打开nrf connect观察广播,在没连接的时候,点击一下࿰…...

springboot项目新增子module
1. 拉取项目 2. file-new-module 3. 选择版本 4. 1-2-3-4 5. 注释请求统一前缀 (SwaggerConfig.java)...

Python Web 开发及 Django 总结
title: Python Web 开发及 Django 总结 date: 2023-07-24 17:26:26 tags: PythonWeb categories:Python cover: https://cover.png feature: false Python 基础部分见:Python 基础总结 1. 创建项目 1.1 命令行 1、下载安装 Django 在终端输入 pip install djan…...
《向量数据库指南》:向量数据库Pinecone故障排除
目录 无法pip安装 空闲后索引丢失 上传缓慢或延迟高 批处理带来的高查询延迟 使用gRPC客户端进行Upsert限流 Pods已满 安全问题 CORS错误 本节介绍常见问题以及如何解决它们。需要帮助吗?在我们的支持论坛中提问。标准、企业和专用客户还可以联系支持人员寻求帮助。...
[86] 分割链表
题目链接:86. 分隔链表 - 力扣(LeetCode) 第一种方法:类似双指针 自己想的,不知道读者是否能看懂,参考注释 ListNode* partition(ListNode* head, int x) {ListNode* bigpos nullptr;ListNode* littlep…...
【python】 清空socket缓冲区
在Python中使用Socket进行网络通信时,可以通过调用socket.recv()函数来接收数据,数据会被存储在缓冲区中。有时候,可能想要先清空缓冲区,以便后续的数据不会被之前的数据影响。以下是一种清空Python Socket缓冲区的方法࿱…...

108、RocketMQ的底层实现原理(不需要长篇大论)
RocketMQ的底层实现原理 RocketMQ由NameServer集群、Producer集群、Consumer集群、Broker集群组成,消息生产和消费的大致原理如下: Broker在启动的时候向所有的NameServer注册,并保持长连接,每30s发送一次心跳Producer在发送消息的时候从Na…...

怎么把PDF转为word?1分钟解决难题
PDF文件在我们的电脑上应用非常广泛,由于其较高的安全性和兼容性,得到了广泛的认可。然而,对于一些人来说,PDF文件不能直接进行编辑和修改可能是一个问题。因此,通常我们需要将其转换为Word格式,以便在Word…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...