python数据分析之你不知道的bra

版权声明:转载请声明出处,谢谢! https://blog.csdn.net/qq_31468321/article/details/84660331

曾经,我把目光放在你身体上四分位的地方,发现了世界的美好。。。

之后,山水流转,时光荏苒,不再从前。。。

此一文,献给过往。

先上张图:好奇怪,为什么是这么个比例[皱眉]

这篇文章分为两个部分,python爬虫和数据分析。爬取京东bra一些数据,并进行分析,在上帝视角看一看bra的秘密。

第一部分,爬虫部分。

爬虫部分利用python和selenium包,爬取京东数据,将数据保存在数据库中。

第二部分,将爬到的数据使用pandas包和matplotlib包进行清洗,在可视化

第一步,先导入包,需要导入的包有,selenium包,用来模仿浏览器,lxml包,用来分析网页信息,显示等待和隐式等待包,数据库包。如下

from selenium import webdriver
import time
from lxml import etree
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from databases import Write_databases

然后,写打开浏览器接口,再获取URL列表时,使用PhantomJS浏览器。

#打开浏览器,返回driver
def open_web():
    driver = webdriver.PhantomJS()
    return driver

获取京东商城前100也的bra商品详情页的URL,(前100页已经足够了,50页之后的商品就基本没有销售信息了)

#获取bra列表,获取每个bra的ID,生成详情页的url,返回url列表
def get_bra_list(driver,url):
    bra_list_urls = [] #定义URL列表
    driver.get(url)#打开浏览器
    i=100
    while i>0:#设置爬取前100页
        html = etree.HTML(driver.page_source)
        bra_lists = html.xpath(".//div[@id='J_goodsList']/ul/li")

        for bra_list in bra_lists:
            bra_id = bra_list.xpath(".//div[@class='p-price']/strong/@class")
            bra_detail_url = 'https://item.jd.com/'+bra_id[0].split('_')[1]+'.html'
            bra_list_urls.append(bra_detail_url)

        next_btn = driver.find_element_by_class_name('pn-next')#某一页数据爬取完成时,点击下一页按钮
        next_btn.click()
        i -= 1
        print("=*"*20+str(i))

    return bra_list_urls

得到URL列表之后,再按照列表中的URL一个一个爬取即可。

爬取详细URL相应信息,进入详情页面之后,首先需要爬取价格,然后点击商品评价,如图

preview

然后再爬取商品评价中的颜色,尺寸,时间

如下步骤,这次,使用Chrome浏览器

#进入详情页获取每个bra的信息,
def get_bra_info(bra_list_urls):
    path = r'C:\Users\yuy-com\web_driver\chromedriver.exe'#设置Chrome浏览器的地址
    sel_driver = webdriver.Chrome(executable_path=path)
    sel_driver.maximize_window()#将浏览器设置为最大化
    time.sleep(1)
    for bra_url in bra_list_urls:
        sel_driver.get(url=bra_url)#打开详情页面的URL
         get_current(sel_driver)#开始获取数据

#获取评论信息,返回评论信息的列表
def get_current(driver):
    bra_de_info = []
    write_data = Write_databases()#初始化数据库类
    while True:
        souce_html = driver.page_source
        html = etree.HTML(souce_html)
        bra_text = html.xpath(".//div[@class='p-parameter']/ul[2]/li/text()")#获取商品介绍信息
        #获取商品评价
        current_num = html.xpath(".//div[contains(@class,'tab-main')]/ul/li[5]/s/text()")[0].split('(')[1].split(')')[0]
        #如果商品评价为0,则直接跳过
        if current_num == '0':
            print('无评价!')
            continue
        #补货商品评价标签,点击
        current = driver.find_element(By.XPATH, ".//div[contains(@class,'tab-main')]/ul/li[5]")
        current.click()
        #解析网页
        souce_h = etree.HTML(driver.page_source)
        current_list = souce_h.xpath(".//div[@class='tab-con']/div[1]/div")
        
        price = souce_h.xpath(".//div[@class='dd']/span/span[2]/text()")[0]#获取价格
        brand = souce_h.xpath(".//div[@class='p-parameter']/ul[1]/li/a/text()")[0]#获取品牌
        bra = {}
        for curr_info in current_list:
            #获取商品颜色,尺寸和时间信息
            info = curr_info.xpath(".//div[@class='comment-message']/div/span//text()")
            if info:
                color = info[0]
                size = info[1]
                times = info[2]
                bra['bra_name'] = brand
                bra['bra_color'] = color
                bra['bra_size'] = size
                bra['bra_time'] = times
                bra['bra_price'] = price
                bra['bra_text'] = " ".join(bra_text)

                print('名称:{},颜色:{},尺寸:{},时间:{},价格:{},描述:{}'.format(brand,color,size, times, price," ".join(bra_text)))
                write_data.insert_data(bra)#写入数据库

                bra_de_info.append(bra)
        try:
            点击下一页获取评论信息
            next_btn = driver.find_element(By.XPATH, './/a[@class="ui-pager-next"]')
            WebDriverWait(driver,1000).until(EC.element_to_be_clickable((By.CLASS_NAME,"ui-pager-next")))
            next_btn.click()
        except:
            return bra_de_info

如上步骤数据便可以爬下来了,写入数据库之前,我们还需要配置数据库,在此我新建一个文件配置。如下

import pymysql#导入包

class Write_databases():
    def __init__(self):
        self.db = pymysql.connect(
            host = '127.0.0.1',
            user = 'root',
            password = 'root',
            database = 'bra_jd',
            port = 3306
        )
        self.cursor = self.db.cursor()#连接数据库

    #插入数据接口
    def insert_data(self,data):
        sql = '''
            insert into bra_table(id,bra_name,bra_price,bra_color,bra_size,bra_time,bra_text)
            values(null,%s,%s,%s,%s,%s,%s)
        '''
        self.cursor.execute(sql,(data['bra_name'],data['bra_price'],data['bra_color'],data['bra_size'],data['bra_time'],data['bra_text']))
        self.db.commit()#提交
    #关闭连接
    def close_databases(self):
        self.db.close()

这样就可以吧数据全部保存在数据库中了。大约有两万条数据,如下图所示

我们先看下数据量:有两万5前多条

数据清洗:在这里,我现将数据库中的数据导出到cvs文件,然后pandas包载入文件。如图:

首先清洗尺寸数据,清洗之前先看尺寸数据的情况,真的是一片杂乱。

看到这,我的头一下就很大,慢慢分析吧,分为如下步骤,

首先,先将标记为L,S,M,XL(码)的数据删除

bra_da = bra_da[(bra_da['bra_size'] != 'S')
&(bra_da['bra_size'] != 'L')&(bra_da['bra_size'] != 'M')&
(bra_da['bra_size'] != 'X')&(bra_da['bra_size'] != 'XL')&
(bra_da['bra_size'] != 'L码')&(bra_da['bra_size'] != 'M码')&
(bra_da['bra_size'] != 'X码')&(bra_da['bra_size'] != 'XL码')&
(bra_da['bra_size'] != 'XXL码')&(bra_da['bra_size'] != 'XXL')]

看了下,虽然少了一点,但是还有很多,继续

将含有“建议”,“均码”,“通杯”的数据删除。因为这些数据没有明确的指向大小,可以视为垃圾数据。如果含有加号,则取加好之前的数据,否则写0,最后将写0的数据删除,新建一列,用MAP函数实现

def pass_cup_del(bra_data):
    if "+" in bra_data:
        return xxx.split("+")[0]
    elif "建议" in bra_data:
        return '0'
    elif "均码" in bra_data:
        return '0'
    elif "通杯" in bra_data:
        return '0'
    else:
        return bra_data
 bra_da['bra_size2'] = bra_da['bra_size'].map(pass_cup_del)

分析之后还是很凌乱,决定,将括号删去,只取括号左边的数据:再加一列数据,再删除标记为L,S,M,XL(码)的数据,将数据框的名称修改。

def brackets_delete(bra_da):
    if "(" in bra_da:
        return bra_da.split("(")[0]
    else:
        return bra_da

    bra_da['bra_size3'] = bra_da['bra_size2'].map(fun2).map(fun1)

    bra_data = bra_da[(bra_da['bra_size3'] != 'L码')&(bra_da['bra_size3'] != 'M码')&(bra_da['bra_size3'] != 'X码')&(bra_da['bra_size3'] != 'XL码')&(bra_da['bra_size3'] != 'XXL码')]

    bra_data.drop(['bra_size2','bra_size'],axis=1,inplace=True)
    bra_da_o = bra_data[bra_data['bra_size3'] == '0']
    bra_data.drop(bra_da_o.index,inplace=True)

到这时,已经差不多了,数据已经变得比较干净了,然后将有A的数据换成A,B,C,D,E,F一样处理

def set_abcd_vlaue(data):
    if 'A' in data:
        return 'A'
    elif 'B' in data:
        return 'B'
    elif 'C' in data:
        return 'C'
    elif 'E' in data:
        return 'E'
    elif 'F' in data:
        return 'F'
    elif 'D' in data:
        return 'D'
    else:
        return '0'

bra_data['bra_size'] = bra_data['bra_size3'].map(set_abcd_vlaue)
    bra_da_o1 = bra_data[bra_data['bra_size'] == '0']
    bra_data.drop(bra_da_o1.index,inplace=True)

如上图,这样就处理好了。

然后处理颜色,先看下颜色,竟然五颜六色。[捂脸]

竟然,这么多颜色,牛X

我将颜色分析了下,准备分为如下色彩:酒红,枣红,钴蓝,藏青,紫灰,粉,肤,红,蓝,杏,紫,绿,白,黑,啡,灰,棕

开始处理:

def set_color(color):
    if '酒红' in color:
        return '酒红'
    elif '枣红' in color:
        return '枣红'
    elif '钴蓝' in color:
        return '钴蓝'
    elif '藏青' in color:
        return '藏青'
    elif '粉' in color:
        return '粉'
    elif '肤' in color:
        return '肤'
    elif '红' in color:
        return '红'
    elif '蓝' in color:
        return '蓝'
    elif '杏' in color:
        return '杏'
    elif '紫' in color:
        return '紫'
    elif '绿' in color:
        return '绿'
    elif '白' in color:
        return '白'
    elif '黑' in color:
        return '黑'
    elif '啡' in color:
        return '啡'
    elif '灰' in color:
        return '灰'
    elif '棕' in color:
        return '棕'
    else:
        return '0'

bra_data['color'] = bra_data['bra_color'].map(set_color)
    bra_color_o = bra_data[bra_data['color'] == '0']
    bra_data.drop(bra_color_o.index,inplace=True)
    bra_data.drop(['bra_color','bra_size3'],axis=1,inplace=True)
    print(set(bra_data['color']))

和之前处理的套路一样,先将有关的颜色修改,最后删除无关的颜色项

果然,颜色也分析好了。

看一下处理之后还有多少数据:绳一万六千多条数据了,应该还能说明点问题。

接下来就是可视化了。可视化主要分析如下几项,

1.颜色柱状图:我们根据在京东爬的销售数据,可以查看在所销售的bra中,颜色的分部

y_color_valse = []
    bra_color = bra_data['color']
    color_list = set(bra_color)

    for x in color_list:
        num = len(bra_data[bra_data['color'] == x])
        y_color_valse.append(num)

    plt.figure()
    plt.bar(list(color_list),y_color_valse)
    plt.title("bra_color")
    plt.show()

 图如下:

可见,肤色,黑色,红色,紫色,占统治地位,白色酒红数量较少。我喜欢的粉色,竟然不多,太神奇了。

我们在画一个颜色的饼图:

第二个是查看尺寸的分部

bra_size_label = ['A','B','C','D','E','F']
    y_bra_size = []
    for bra in bra_size_label:
        num = len(bra_data[bra_data['bra_size'] == bra])
        y_bra_size.append(num)
    plt.figure()
    plt.pie(y_bra_size,labels=bra_size_label,autopct='%1.1f%%')
    plt.title("bra_size")
    plt.axis('equal')
    plt.legend(loc='upper left', bbox_to_anchor=(-0.1, 1))
    plt.show()

如图:B罩杯最多,[偷笑]

 

在这,我们再看看各个品牌的分部:

排名最多的是,carey Key,迪万,都市丽人,为啥我只听过都市丽人呢?

猜你喜欢

转载自blog.csdn.net/qq_31468321/article/details/84660331