python數據分析之你不知道的bra
來自專欄 python學習總結專欄
曾經,我把目光放在你身體上四分位的地方,發現了世界的美好。。。
之後,山水流轉,時光荏苒,不再從前。。。
此一文,獻給過往。
先上張圖:好奇怪,為什麼是這麼個比例[皺眉]
這篇文章分為兩個部分,python爬蟲和數據分析。爬取京東bra一些數據,並進行分析,在上帝視角看一看bra的秘密。
第一部分,爬虫部分。
爬虫部分利用python和selenium包,爬取京東數據,將數據保存在資料庫中。
第二部分,將爬到的數據使用pandas包和matplotlib包進行清洗,在可視化
第一步,先導入包,需要導入的包有,selenium包,用來模仿瀏覽器,lxml包,用來分析網頁信息,顯示等待和隱式等待包,資料庫包。如下
from selenium import webdriverimport timefrom lxml import etreefrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom databases import Write_databases
然後,寫打開瀏覽器介面,再獲取URL列表時,使用PhantomJS瀏覽器。
#打開瀏覽器,返回driverdef 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相應信息,進入詳情頁面之後,首先需要爬取價格,然後點擊商品評價,如圖
然後再爬取商品評價中的顏色,尺寸,時間
如下步驟,這次,使用Chrome瀏覽器
#進入詳情頁獲取每個bra的信息,def get_bra_info(bra_list_urls): path = rC:Usersyuy-comweb_driverchromedriver.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 0bra_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 0bra_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,迪萬,都市麗人,為啥我只聽過都市麗人呢?
各位看官,請多多指教
推薦閱讀:
※AI時代的國際關係=黑科技 體系變革?——人工智慧與國際關係研究(一)
※他是國家科技進步獎的常客,美國卻視他為眼中釘
※讓機器「析毫剖厘」:圖像理解與編輯|VALSE2018之三
※螞蟻中間件 SOFABoot v2.3.2 和 SOFARPC v5.3.2 發布
※秒知新科技