>今天闲暇之余写了一个爬虫例子。通过爬虫去爬取京东的用户评价,通过分析爬取的数据能得到很多结果,比如,哪一种颜色的胸罩最受女性欢迎,以及中国女性的平均size(仅供参考哦~)

打开开发者工具-network,在用户评价页面我们发现浏览器有这样一个请求

![图片描述](//img.mukewang.com/5d39d4460001791f10720493.png)

通过分析我们发现主要用的参数有三个productId,page,pageSize。后两个为分页参数,productId是每个商品的id,通过这个id去获取商品的评价记录,所以我们只需要知道每个商品的productId就轻而易举的获取评价了。再来分析搜索页面的网页源代码

![图片描述](//img.mukewang.com/5d39d49800017bf010800170.png)

通过分析我们发现每个商品都在li标签中,而li标签又有一个data-pid属性,这个对应的值就是商品的productId了。

大概了解了整个流程,就可以开始我们的爬虫工作了。

---
首先我们需要在搜索页面获取商品的id,为下面爬取用户评价提供productId。key_word为搜索的关键字,这里就是【胸罩】

```python
import requests
import re

"""
查询商品id
"""
def find_product_id(key_word):
jd_url = 'https://search.jd.com/Search'
product_ids = []
# 爬前3页的商品
for i in range(1,4):
param = {'keyword': key_word, 'enc': 'utf-8', 'page': i}
response = requests.get(jd_url, params=param)
# 商品id
ids = re.findall('data-pid="(.*?)"', response.text, re.S)
product_ids += ids
return product_ids
```

将前三页的商品id放入列表中,接下来我们就可以爬取评价了

我们通过分析preview发现获取用户评价这个请求响应的格式是一个字符串后面拼接了一个json(如下图),所以我们只要将无用的字符删除掉,就可以获取到我们想要的json对象了。

而在json对象中的comments的内容就是我们最终想要的评价记录

![图片描述](//img.mukewang.com/5d39d4f70001335c10800312.png)

```python
"""
获取评论内容
"""
def get_comment_message(product_id):
urls = ['https://sclub.jd.com/comment/productPageComments.action?' \
'callback=fetchJSON_comment98vv53282&' \
'productId={}' \
'&score=0&sortType=5&' \
'page={}' \
'&pageSize=10&isShadowSku=0&rid=0&fold=1'.format(product_id, page) for page in range(1, 11)]
for url in urls:
response = requests.get(url)
html = response.text
# 删除无用字符
html = html.replace('fetchJSON_comment98vv53282(', '').replace(');', '')
data = json.loads(html)
comments = data['comments']
t = threading.Thread(target=save_mongo, args=(comments,))
t.start()
```

在这个方法中只获取了前10页的评价的url,放到urls这个列表中。通过循环获取不同页面的评价记录,这时启动了一个线程用来将留言数据存到到MongoDB中。

我们继续分析评价记录这个接口发现我们想要的两条数据

- productColor:产品颜色

- productSize:产品尺寸
![图片描述](//img.mukewang.com/5d39d5280001cabf08080508.png)

```python
# mongo服务
client = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
# jd数据库
db = client.jd
# product表,没有自动创建
product_db = db.product

# 保存mongo
def save_mongo(comments):
for comment in comments:
product_data = {}
# 颜色
# flush_data清洗数据的方法
product_data['product_color'] = flush_data(comment['productColor'])
# size
product_data['product_size'] = flush_data(comment['productSize'])
# 评论内容
product_data['comment_content'] = comment['content']
# create_time
product_data['create_time'] = comment['creationTime']
# 插入mongo
product_db.insert(product_data)

```

因为每种商品的颜色、尺寸描述上有差异,为了方面统计,我们进行了简单的数据清洗。这段代码非常的不Pythonic。不过只是一个小demo,大家无视即可。
```python
def flush_data(data):
if '肤' in data:
return '肤色'
if '黑' in data:
return '黑色'
if '紫' in data:
return '紫色'
if '粉' in data:
return '粉色'
if '蓝' in data:
return '蓝色'
if '白' in data:
return '白色'
if '灰' in data:
return '灰色'
if '槟' in data:
return '香槟色'
if '琥' in data:
return '琥珀色'
if '红' in data:
return '红色'
if '紫' in data:
return '紫色'
if 'A' in data:
return 'A'
if 'B' in data:
return 'B'
if 'C' in data:
return 'C'
if 'D' in data:
return 'D'
```

这几个模块的功能编写完毕,下面只需要将他们联系起来
```python
# 创建一个线程锁
lock = threading.Lock()

# 获取评论线程
def spider_jd(ids):
while ids:
# 加锁
lock.acquire()
# 取出第一个元素
id = ids[0]
# 将取出的元素从列表中删除,避免重复加载
del ids[0]
# 释放锁
lock.release()
# 获取评论内容
get_comment_message(id)

product_ids = find_product_id('胸罩')
for i in (1, 5):
# 增加一个获取评论的线程
t = threading.Thread(target=spider_jd, args=(product_ids,))
# 启动线程
t.start()
```
上面代码加锁的原因是为了防止重复消费共享变量

运行之后的查看MongoDB:
![图片描述](//img.mukewang.com/5d39d566000199a907250640.png)

得到结果之后,为了能更直观的表现数据,我们可以用matplotlib库进行图表化展示

```python
import pymongo
from pylab import *

client = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
# jd数据库
db = client.jd
# product表,没有自动创建
product_db = db.product
# 统计以下几个颜色
color_arr = ['肤色', '黑色', '紫色', '粉色', '蓝色', '白色', '灰色', '香槟色', '红色']

color_num_arr = []
for i in color_arr:
num = product_db.count({'product_color': i})
color_num_arr.append(num)

# 显示的颜色
color_arr = ['bisque', 'black', 'purple', 'pink', 'blue', 'white', 'gray', 'peru', 'red']

#labeldistance,文本的位置离远点有多远,1.1指1.1倍半径的位置
#autopct,圆里面的文本格式,%3.1f%%表示小数有三位,整数有一位的浮点数
#shadow,饼是否有阴影
#startangle,起始角度,0,表示从0开始逆时针转,为第一块。一般选择从90度开始比较好看
#pctdistance,百分比的text离圆心的距离
#patches, l_texts, p_texts,为了得到饼图的返回值,p_texts饼图内部文本的,l_texts饼图外label的文本
patches,l_text,p_text = plt.pie(sizes, labels=labels, colors=colors,
labeldistance=1.1, autopct='%3.1f%%', shadow=False,
startangle=90, pctdistance=0.6)
#改变文本的大小
#方法是把每一个text遍历。调用set_size方法设置它的属性
for t in l_text:
t.set_size=(30)
for t in p_text:
t.set_size=(20)
# 设置x,y轴刻度一致,这样饼图才能是圆的
plt.axis('equal')
plt.title("内衣颜色比例图", fontproperties="SimHei") #
plt.legend()
plt.show()
```

运行代码,我们发现肤色的最受欢迎 其次是黑色 (钢铁直男表示不知道是不是真的...)
![图片描述](//img.mukewang.com/5d39d5a00001dc3d05580709.png)

接下来我们再来统计一下size 的分布图,这里用柱状图进行显示

```python
index=["A","B","C","D"]

client = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
db = client.jd
product_db = db.product

value = []
for i in index:
num = product_db.count({'product_size': i})
value.append(num)

plt.bar(left=index, height=value, color="green", width=0.5)

plt.show()

```

运行后我们发现 B size的女性更多一些
![图片描述](//img.mukewang.com/5d39d5cd0001812c06380466.png)

---

最后,欢迎大家关注我的公众号(python3xxx)。每天都会推送不一样的Python干货。
![图片描述](//img.mukewang.com/5d39d61c00017fad04760268.png)

分析了京东内衣销售记录,告诉你妹子们的真Size!的更多相关文章

  1. 分析jQuery源码时记录的一点感悟

    分析jQuery源码时记录的一点感悟      1.  链式写法      这是jQuery语法上的最大特色,也许该改改POJO里的set方法,和其他的非get方法什么的,可以把多行代码合并,减去每次 ...

  2. 图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录)

    图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录): https://download.csdn.net/download/qq_39932172/11 ...

  3. 用 Python 分析网易严选 Bra 销售信息,告诉你她们真实的 Size

    今天通过爬虫数据进行分析,一起来看看网易严选商品评论的获取和分析. 声明:这是一篇超级严肃的技术文章,请本着学习交流的态度阅读,谢谢! !   ​ 网易商品评论爬取 分析网页 评论分析 进入到网易严选 ...

  4. UML作业第三次:分析《书店图书销售管理系统》

    分析图书销售管理系统 一.概览 PlantUML类图语法学习小结 <书店图书销售管理>的类图元素 绘制类图脚本程序 绘制的类图 二.PlantUML类图语法 1.类之间的关系绘制 示例: ...

  5. ELK实时日志分析平台环境部署--完整记录

    在日常运维工作中,对于系统和业务日志的处理尤为重要.今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为例说明,如有误述,敬请指出)~ ==== ...

  6. ELK实时日志分析平台环境部署--完整记录(转)

    在日常运维工作中,对于系统和业务日志的处理尤为重要.今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为例说明,如有误述,敬请指出)~ ==== ...

  7. SQL Server求解最近多少销售记录的销售额占比总销售额的指定比例

    看园中SQL Server大V潇潇隐者的博文,发现一边文就是描述了如标题描述的问题.   具体的问题描述我通过潇潇隐者的博文的截图来阐释: 注意:如果以上截取有所侵权,也请作者告知,再次感谢.   当 ...

  8. ruby 分析日志,提取特定记录

    读取日志中的每一行,分析后存入hash,然后做累加 adx_openx=Hash.new(0) File.open('watch.log.2016-08-24-21').each do |line| ...

  9. 《linux 网络日志分析与流量监控》记录

    mac中有个本机连接vpn的日志,/private/var/log/ppp.log   消除日志(echo "" >/private/var/log/ppp.log ) li ...

随机推荐

  1. Qt - 设置程序界面风格(现成的QMacStyle等等)

    类的继承关系: QMotifStyle:OSF(开放基金协会)开发的一个工业标准的GUI(图形用户接口): QCDEStyle:公共桌面环境(Common Desktop Environment)的缩 ...

  2. Ruby元编程:执行某个目录下的全部测试用例

    目前手里有个测试项目各个feature的测试用例都放在对应的子目录下,虽然有自动化测试框架的帮助执行起来很方便,但是偶尔也有需要在本地执行某个feature的全部测试用例集合.因为本人对shell脚本 ...

  3. 【算法随记三】小半径中值模糊的急速实现(16MB图7.5ms实现) + Photoshop中蒙尘和划痕算法解读。

    在本人的博客里,分享了有关中值模糊的O(1)算法,详见:任意半径中值滤波(扩展至百分比滤波器)O(1)时间复杂度算法的原理.实现及效果 ,这里的算法的执行时间和参数是无关的.整体来说,虽然速度也很快, ...

  4. 一步步教你怎么用python写贪吃蛇游戏

    目录 0 引言 1 环境 2 需求分析 3 代码实现 4 后记 0 引言 前几天,星球有人提到贪吃蛇,一下子就勾起了我的兴趣,毕竟在那个Nokia称霸的年代,这款游戏可是经典中的经典啊!而用Pytho ...

  5. 深入浅出Ajax

    原文(我的GitHub):https://github.com/liangfengbo/frontend-ability/issues/1 学习大纲 理解Ajax的工作原理 Ajax核心-XMLHtt ...

  6. Spring5源码深度分析(二)之理解@Conditional,@Import注解

    代码地址: 1.源码分析二主要分析的内容 1.使用@Condition多条件注册bean对象2.@Import注解快速注入第三方bean对象3.@EnableXXXX 开启原理4.基于ImportBe ...

  7. 627.Swap Salary-(LeetCode之Database篇)

    问题描述 给出下面的表,名为salary. id name sex salary 1 A m 2500 2 B f 1500 3 C m 5500 4 D f 500 要求执行一个UPDATE语句,将 ...

  8. 02、MySQL—数据库基本操作

    数据库是数据存储的最外层(最大单元) 1.创建数据库 基本语法:create database 数据库名字 [库选项]; 范例:使用create database 创建数据库 库选项:数据库的相关属性 ...

  9. 程序员修仙之路--优雅快速的统计千万级别uv(留言送书)

    菜菜,咱们网站现在有多少PV和UV了? Y总,咱们没有统计pv和uv的系统,预估大约有一千万uv吧 写一个统计uv和pv的系统吧 网上有现成的,直接接入一个不行吗? 别人的不太放心,毕竟自己写的,自己 ...

  10. vue2.0父子组件以及非父子组件通信传参详解

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: <parent> <child :child-msg="msg" ...