接下来我们尝试用 Python 抓取天猫内衣销售数据,并分析得到中国女性普遍的罩杯数据、最受欢迎的内衣颜色是什么、评论的关键字。希望看完之后你能替你女朋友买上一件心怡的内衣。我们先看看分析得到的成果是怎样的?(讲的很详细,推荐跟着敲一遍)

当然在学习Python的道路上肯定会困难,没有好的学习资料,怎么去学习呢? 学习Python中有不明白推荐加入交流群号:790921645 群里有志同道合的小伙伴,互帮互助, 群里有不错的视频学习教程和PDF!

(买个内衣这么开心)

图片看不清楚的话,可以把图片单独拉到另一个窗口。 这里是分析了一万条数据得出的结论,可能会有误差,但是还是希望单身的你们能找到 0.06% 那一批妹纸。下面我会详细介绍怎么抓取天猫内衣销售数据,存储、分析、展示。

  • 研究天猫网站
  • 抓取天猫评论数据
  • 存储、分析数据
  • 可视化

研究天猫网站

我们随意进入一个商品的购买界面(能看到评论的那个界面),F12 开发者模式 – Network 栏 – 刷新下界面 – 在如图的位置搜索 list_ 会看到一个 list_detail_rate.htm?itemId= ….

如下图:【单击】这个url 能看到返回的是一个 Json 数据 ,检查一下你会发现这串 Json 就是商品的评论数据 [‘rateDetail’][‘rateList’]

【双击】这个url 你会得到一个新界面,如图

看一下这个信息

这里的路径 就是获取评论数据的 url了。这个 URL 有很多参数你可以分析一下每个值都是干嘛的。

itemId 对应的是商品id, sellerId 对应的是店铺id,currentPage 是当前页。这里 sellerId 可以填任意值,不影响数据的获取。

抓取天猫评论数据

写一个抓取天猫评论数据的方法。getCommentDetail

# 获取商品评论数据
def getCommentDetail(itemId,currentPage):url = 'https://rate.tmall.com/list_detail_rate.htm?itemId=' + str(itemId) + '&sellerId=2451699564ℴ=3&currentPage=' + str(currentPage) + '&append=0callback=jsonp336'# itemId 产品id ;sellerId 店铺id 字段必须有值,但随意值就行html = common.getUrlContent(url)  # 获取网页信息# 删掉返回的多余信息html = html.replace('jsonp128(','') #需要确定是不是 jsonp128html = html.replace(')','')html = html.replace('false','"false"')html = html.replace('true','"true"')# 将string 转换为字典对象tmalljson = json.loads(html)return tmalljson

这里需要注意的是 jsonp128 这个值需要你自己看一下,你那边跟我这个应该是不同的。

在上面的方法里有两个变量,itemId 和 currentPage 这两个值我们动态来控制,所以我们需要获得 一批 商品id号 和 评论的最大页数 用来遍历。

写个获取商品评论最大页数的方法 getLastPage

# 获取商品评论最大页数
def getLastPage(itemId):tmalljson = getCommentDetail(itemId,1)return tmalljson['rateDetail']['paginator']['lastPage'] #最大页数

那现在怎么获取 产品的id 列表呢?我们可以在天猫中搜索商品关键字 用开发者模式观察

这里观察一下这个页面的元素分布,很容易就发现了 商品的id 信息,当然你可以想办法确认一下。

现在就写个 获取商品id 的方法 getProductIdList

# 获取商品id
def getProductIdList():url = 'https://list.tmall.com/search_product.htm?q=内衣' # q参数 是查询的关键字html = common.getUrlContent(url)  # 获取网页信息soup = BeautifulSoup(html,'html.parser')idList = []# 用Beautiful Soup提取商品页面中所有的商品IDproductList = soup.find_all('div', {'class': 'product'})for product in productList:idList.append(product['data-id'])return idList

现在所有的基本要求都有了,是时候把他们组合起来。

在 main 方法中写剩下的组装部分

if __name__ == '__main__':productIdList = getProductIdList() #获取商品idinitial = 0while initial < len(productIdList) - 30:  # 总共有60个商品,我只取了前30个try:itemId = productIdList[initial]print('----------', itemId, '------------')maxPage = getLastPage(itemId) #获取商品评论最大页数num = 1while num <= maxPage and num < 20: #每个商品的评论我最多取20 页,每页有20条评论,也就是每个商品最多只取 400 个评论try:# 抓取某个商品的某页评论数据tmalljson = getCommentDetail(itemId, num)rateList = tmalljson['rateDetail']['rateList']commentList = []n = 0while (n < len(rateList)):comment = []# 商品描述colorSize = rateList[n]['auctionSku']m = re.split('[:;]', colorSize)rateContent = rateList[n]['rateContent']dtime = rateList[n]['rateDate']comment.append(m[1])comment.append(m[3])comment.append('天猫')comment.append(rateContent)comment.append(dtime)commentList.append(comment)n += 1print(num)sql = "insert into bras(bra_id, bra_color, bra_size, resource, comment, comment_time)  value(null, %s, %s, %s, %s, %s)"common.patchInsertData(sql, commentList) # mysql操作的批量插入num += 1except Exception as e:num += 1print(e)continueinitial += 1except Exception as e:print(e)

所有的代码就这样完成了,我现在把 common.py 的代码,还有 tmallbra.py 的代码都贴出来

# -*- coding:utf-8 -*-
# Author: zww
import requests
import time
import random
import socket
import http.client
import pymysql
import csv# 封装requests
class Common(object):def getUrlContent(self, url, data=None):header = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8','Accept-Encoding': 'gzip, deflate, br','Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8','user-agent': "User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",'cache-control': 'max-age=0'}  # request 的请求头timeout = random.choice(range(80, 180))while True:try:rep = requests.get(url, headers=header, timeout=timeout)  # 请求url地址,获得返回 response 信息# rep.encoding = 'utf-8'breakexcept socket.timeout as e:  # 以下都是异常处理print('3:', e)time.sleep(random.choice(range(8, 15)))except socket.error as e:print('4:', e)time.sleep(random.choice(range(20, 60)))except http.client.BadStatusLine as e:print('5:', e)time.sleep(random.choice(range(30, 80)))except http.client.IncompleteRead as e:print('6:', e)time.sleep(random.choice(range(5, 15)))print('request success')return rep.text  # 返回的 Html 全文def writeData(self, data, url):with open(url, 'a', errors='ignore', newline='') as f:f_csv = csv.writer(f)f_csv.writerows(data)print('write_csv success')def queryData(self, sql):db = pymysql.connect("localhost", "zww", "960128", "test")cursor = db.cursor()results = []try:cursor.execute(sql)    #执行查询语句results = cursor.fetchall()except Exception as e:print('查询时发生异常' + e)# 如果发生错误则回滚db.rollback()# 关闭数据库连接db.close()return resultsprint('insert data success')def insertData(self, sql):# 打开数据库连接db = pymysql.connect("localhost", "zww", "000000", "zwwdb")# 使用 cursor() 方法创建一个游标对象 cursorcursor = db.cursor()try:# sql = "INSERT INTO WEATHER(w_id, w_date, w_detail, w_temperature) VALUES (null, '%s','%s','%s')" % (data[0], data[1], data[2])cursor.execute(sql)    #单条数据写入# 提交到数据库执行db.commit()except Exception as e:print('插入时发生异常' + e)# 如果发生错误则回滚db.rollback()# 关闭数据库连接db.close()print('insert data success')def patchInsertData(self, sql, datas):# 打开数据库连接db = pymysql.connect("localhost", "zww", "960128", "test")# 使用 cursor() 方法创建一个游标对象 cursorcursor = db.cursor()try:# 批量插入数据# cursor.executemany('insert into WEATHER(w_id, w_date, w_detail, w_temperature_low, w_temperature_high) value(null, %s,%s,%s,%s)',datas)cursor.executemany(sql, datas)# 提交到数据库执行db.commit()except Exception as e:print('插入时发生异常' + e)# 如果发生错误则回滚db.rollback()# 关闭数据库连接db.close()print('insert data success')

上面需要注意,数据库的配置。

# -*- coding:utf-8 -*-
# Author: zwwfrom Include.commons.common import Common
from bs4 import BeautifulSoup
import json
import re
import pymysqlcommon = Common()# 获取商品id
def getProductIdList():url = 'https://list.tmall.com/search_product.htm?q=内衣' # q参数 是查询的关键字,这要改变一下查询值,就可以抓取任意你想知道的数据html = common.getUrlContent(url)  # 获取网页信息soup = BeautifulSoup(html,'html.parser')idList = []# 用Beautiful Soup提取商品页面中所有的商品IDproductList = soup.find_all('div', {'class': 'product'})for product in productList:idList.append(product['data-id'])return idList# 获取商品评论数据
def getCommentDetail(itemId,currentPage):url = 'https://rate.tmall.com/list_detail_rate.htm?itemId=' + str(itemId) + '&sellerId=2451699564ℴ=3&currentPage=' + str(currentPage) + '&append=0callback=jsonp336'# itemId 产品id ;sellerId 店铺id 字段必须有值,但随意值就行html = common.getUrlContent(url)  # 获取网页信息# 删掉返回的多余信息html = html.replace('jsonp128(','') #需要确定是不是 jsonp128html = html.replace(')','')html = html.replace('false','"false"')html = html.replace('true','"true"')# 将string 转换为字典对象tmalljson = json.loads(html)return tmalljson# 获取商品评论最大页数
def getLastPage(itemId):tmalljson = getCommentDetail(itemId,1)return tmalljson['rateDetail']['paginator']['lastPage'] #最大页数if __name__ == '__main__':productIdList = getProductIdList() #获取商品idinitial = 0while initial < len(productIdList) - 30:  # 总共有60个商品,我只取了前30个try:itemId = productIdList[initial]print('----------', itemId, '------------')maxPage = getLastPage(itemId) #获取商品评论最大页数num = 1while num <= maxPage and num < 20: #每个商品的评论我最多取20 页,每页有20条评论,也就是每个商品最多只取 400 个评论try:# 抓取某个商品的某页评论数据tmalljson = getCommentDetail(itemId, num)rateList = tmalljson['rateDetail']['rateList']commentList = []n = 0while (n < len(rateList)):comment = []# 商品描述colorSize = rateList[n]['auctionSku']m = re.split('[:;]', colorSize)rateContent = rateList[n]['rateContent']dtime = rateList[n]['rateDate']comment.append(m[1])comment.append(m[3])comment.append('天猫')comment.append(rateContent)comment.append(dtime)commentList.append(comment)n += 1print(num)sql = "insert into bras(bra_id, bra_color, bra_size, resource, comment, comment_time)  value(null, %s, %s, %s, %s, %s)"common.patchInsertData(sql, commentList) # mysql操作的批量插入num += 1except Exception as e:num += 1print(e)continueinitial += 1except Exception as e:print(e)

存储、分析数据

所有的代码都有了,就差数据库的建立了。我这里用的是 MySql 数据库。

CREATE TABLE `bra` (
`bra_id`  int(11) NOT NULL AUTO_INCREMENT COMMENT 'id' ,
`bra_color`  varchar(25) NULL COMMENT '颜色' ,
`bra_size`  varchar(25) NULL COMMENT '罩杯' ,
`resource`  varchar(25) NULL COMMENT '数据来源' ,
`comment`  varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '评论' ,
`comment_time`  datetime NULL COMMENT '评论时间' ,
PRIMARY KEY (`bra_id`)
) character set utf8
;

这里有两个地方需要注意, comment 评论字段需要设置编码格式为 utf8mb4 ,因为可能有表情文字。还有表需要设置为 utf8 编码,不然存不了中文。

建好了表,就可以完整执行代码了。(这里的执行可能需要点时间,可以做成多线程的方式)。看一下执行完之后,数据库有没有数据。

数据是有了,但是有些我们多余的文字描述,我们可以稍微整理一下。

update bra set bra_color = REPLACE(bra_color,'2B6521-无钢圈4-','');
update bra set bra_color = REPLACE(bra_color,'-1','');
update bra set bra_color = REPLACE(bra_color,'5','');
update bra set bra_size = substr(bra_size,1,3);

这里需要根据自己实际情况来修改。如果数据整理的差不多了,我们可以分析一下数据库的信息。

select 'A罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%A'
union all select 'B罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%B'
union all select 'C罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%C'
union all select 'D罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%D'
union all select 'E罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%E'
union all select 'F罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%F'
union all select 'G罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%G'
union all select 'H罩杯' as 罩杯, CONCAT(ROUND(COUNT(*)/(select count(*) from bra) * 100, 2) , "%") as 比例, COUNT(*) as 销量  from bra where bra_size like '%H'
order by 销量 desc;

(想知道是哪6位小姐姐买的 G (~ ̄▽ ̄)~ )

数据可视化

数据的展示,我用了是 mycharts 模块,如果不了解的可以去学习一下http://pyecharts.org/#/zh-cn/prepare

这里我就不细说了,直接贴代码看

# encoding: utf-8
# author zwwfrom pyecharts import Pie
from Include.commons.common import Commonif __name__ == '__main__':common = Common()results = common.queryData("""select count(*) from bra where bra_size like '%A' union all select count(*) from bra where bra_size like '%B' union all select count(*) from bra where bra_size like '%C' union all select count(*) from bra where bra_size like '%D' union all select count(*) from bra where bra_size like '%E' union all select count(*) from bra where bra_size like '%F' union all select count(*) from bra where bra_size like '%G'""")  # 获取每个罩杯数量attr = ["A罩杯", 'G罩杯', "B罩杯", "C罩杯", "D罩杯", "E罩杯", "F罩杯"]v1 = [results[0][0], results[6][0], results[1][0], results[2][0], results[3][0], results[4][0], results[5][0]]pie = Pie("内衣罩杯", width=1300, height=620)pie.add("", attr, v1, is_label_show=True)pie.render('size.html')print('success')results = common.queryData("""select count(*) from bra where bra_color like '%肤%' union all select count(*) from bra where bra_color like '%灰%' union all select count(*) from bra where bra_color like '%黑%' union all select count(*) from bra where bra_color like '%蓝%' union all select count(*) from bra where bra_color like '%粉%' union all select count(*) from bra where bra_color like '%红%' union all select count(*) from bra where bra_color like '%紫%'  union all select count(*) from bra where bra_color like '%绿%' union all select count(*) from bra where bra_color like '%白%' union all select count(*) from bra where bra_color like '%褐%' union all select count(*) from bra where bra_color like '%黄%' """)  # 获取每个罩杯数量attr = ["肤色", '灰色', "黑色", "蓝色", "粉色", "红色", "紫色", '绿色', "白色", "褐色", "黄色"]v1 = [results[0][0], results[1][0], results[2][0], results[3][0], results[4][0], results[5][0], results[6][0], results[7][0], results[8][0], results[9][0], results[10][0]]pieColor = Pie("内衣颜色", width=1300, height=620)pieColor.add("", attr, v1, is_label_show=True)pieColor.render('color.html')print('success')

这一章就到这里了,该知道的你也知道了,不该知道的你也知道了。

为了给女友挑合适的内衣,我用 Python 爬了天猫内衣店的数据相关推荐

  1. 为了给女友挑合适的内衣,我用 Python 爬了天猫内衣店的数据!

    接下来我们尝试用 Python 抓取天猫内衣销售数据,并分析得到中国女性普遍的罩杯数据.最受欢迎的内衣颜色是什么.评论的关键字.希望看完之后你能替你女朋友买上一件心怡的内衣.我们先看看分析得到的成果是 ...

  2. 为了给小女友挑合适罩杯的内衣,我用 Python 爬了淘宝内衣店的数据!

    点击"开发者技术前线",选择"星标?" 13:21 在看|星标|留言,  真爱 编辑: 可可| 本文作者:躲猫猫的猫, 原文链接:https://www.cnb ...

  3. 为了给女朋友买件心怡内衣,我用Python爬虫了天猫内衣售卖数据

    点击上方"视学算法" 真爱,请置顶或星标 大家好,希望各位能怀着正直.严谨.专业的心态观看这篇文章.ヾ(๑╹◡╹)ノ" 接下来我们尝试用 Python 抓取天猫内衣销售数 ...

  4. 为了给七夕的女盆友挑合适的内衣,我用Python爬了网易严选的内衣店的数据!

    为了给心爱的女盆友选一套surprise我 用python把网易优选小姐姐文胸看了个遍 这一切的的目的只是因为我爱女盆友&&爱学习~~~ 需求分析 我们的目标是爬取网易小姐姐2000+ ...

  5. Python爬取2万条相亲数据!看看中国单身男女都在挑什么

    想必昨天的七夕节,一定是有人欢喜有人忧的一天,朋友圈里的晒照惹恼了我的一个程序员朋友,在昨晚怒爬2万条相亲网站数据,做了一次相亲男女画像! 话不多说,我们今天就以某相亲网站为例子,爬取搜索页面当中所有 ...

  6. 周六想和女友浪不知道怎么选酒店?Python告诉你全国著名高校附近酒店评论!...

    点击上方"Python高校",关注 文末干货立马到手 /1 前言/ 简介:本文介绍如何用python爬取全国著名高校附近的酒店点评,并进行分析,带大家看看著名高校附近的酒店怎么样. ...

  7. 为了探究妹子对内衣的偏好,我爬了淘宝内衣店的数据!

    作者丨躲猫猫的猫 链接: https://www.cnblogs.com/zhaww/p/9636383.html 大家好,希望各位能怀着正直.严谨.专业的心态观看这篇文章.ヾ(๑╹◡╹)ノ" ...

  8. 为了探究妹纸对内衣的喜好,我爬了淘宝内衣店的数据!

    作者:躲猫猫的猫 来源:https://www.cnblogs.com/zhaww/p/9636383.html 公众号:杰哥的IT之旅,后台回复[内衣]获取全部源码. 大家好,希望各位能怀着正直.严 ...

  9. python爬取+BI分析5000条内衣数据,发现妹子最爱这款文胸

    生活中我们经常会用python进行数据爬取,但是爬取简单分析难,很多人喜欢用echarts图表接口或者是python的第三方库进行数据可视化,甚至是用matlab,基本上都需要用代码实现,在数据展示上 ...

最新文章

  1. 兄弟!kafka的重试机制,你可能用错了~
  2. 简书python自动化运维_简明Python开发教程(4):网络自动化运维的曙光
  3. selenium找不到元素
  4. efi分区咋移动到c盘里_怎么手动安装CLOVER到U盘EFI分区
  5. 【Java学习笔记之一】java关键字及作用
  6. 谈谈ASP.NET Core中的ResponseCaching
  7. 【Acwing 219. 剪纸游戏】
  8. axure html 360安装扩展,win10系统360浏览器添加Axure扩展的操作方法
  9. RSA2013系列(1):中国成为热点
  10. python安装anaconda ubuntu_Ubuntu 16.4 安装anaconda 详细教程
  11. 领域驱动设计战术模式--领域事件
  12. java常用面板_Java 常用面板
  13. 微信小程序实现浮动按钮
  14. Python下载prettyloaded的swf
  15. 搭建SpringMVC
  16. zend studio html插件安装,Zend Studio使用教程:将Zend Studio作为插件安装
  17. c++编游戏-扫雷-c++游戏将彩色化-windows7自带扫雷游戏休闲娱乐
  18. hibernate枚举类型注解 @Enumerated
  19. The Love Dare爱的挑战
  20. 图片木马制作方法详细教程

热门文章

  1. Switch与for循环
  2. python怎么获取token值_python 产生token及token验证
  3. Android扫描银行卡获取银行卡号
  4. 机器学习基石 机器学习技法 林轩田 课件 ppt
  5. 关于汽车定位追踪的一点设计思路
  6. VS2017+QT5.9 QT5.9基础大全 医疗图像处理界面设计
  7. 对DAO 的恶意收购,我们能做些什么?
  8. 使用google搜索引擎的技巧
  9. 华为首席开源联络官任旭东:业务和战略驱动华为拥抱开源
  10. Java主流框架面试题