淘寶數據分析實戰:美食霸榜銷量No.1的竟然是….
- 2020 年 2 月 19 日
- 筆記
想必大家都喜歡囤貨吧,小編購物車裡全是加購的零食,閑來無事,就順手爬了淘寶搜索美食出來的商品信息,簡單做了個分析,藉此案例給大家學習參考。
◆◆數據採集◆◆
淘寶的頁面也是通過Ajax來抓取相關數據,但是參數比較複雜,甚至包含加密秘鑰。用selenium來模擬瀏覽器操作,抓取淘寶商品信息,即可做到可見即可爬。我就用selenium爬了淘寶網頁上能顯示的100頁的數據,大約4400個左右,速度也不慢,具體步驟如下:
1.準備工作
用selenium抓取淘寶商品,並用pyquery解析得到商品的圖片,名稱,價格,購買人數,店鋪名稱和店鋪所在位置。需要安裝selenium,pyquery,以及Chrome瀏覽器並配置ChromeDriver。

我們的目標是獲取商品的信息,那麼先搜索,例如我們搜索美食。而我們需要的信息都在每一頁商品條目里。在頁面的最下面,有個分頁導航。為100頁,要獲得所以的信息只需要從第一頁到帶一百頁順序遍歷。
採用selenium模擬瀏覽器不斷的遍歷即可得到,這裡為直接輸入頁數然後點擊確定轉跳。這樣即使程序中途出錯,也可以知道爬到那一頁了,而不必從頭再來。

我們爬取淘寶商品信息,只需要得到總共多少條商品條目,而淘寶默認100頁,則只需要每一頁商品條目都加載完之後爬取,然後再轉跳就好了。用selenium只需要定位到專業和條目即可。
整體代碼如下:
from selenium import webdriver from selenium.common.exceptions import TimeoutException from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from urllib.parse import quote from pyquery import PyQuery as pq import pymongo MAX_PAGE = 100 MONGO_URL = 'localhost' MONGO_DB = 'taobao' MONGO_COLLECTION = 'foods' client = pymongo.MongoClient(MONGO_URL) db = client[MONGO_DB] browser = webdriver.Chrome() wait = WebDriverWait(browser, 10) KEYWORD='美食' def index_page(page): """ 抓取索引頁:param page:頁碼 """ print('正在爬取第', page, '頁') try: url = 'https://s.taobao.com/search?q=' + quote(KEYWORD) browser.get(url) if page > 1: input = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager div.form > input'))) submit = wait.until( EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager div.form > span.btn.J_Submit'))) input.clear() input.send_keys(page) submit.click() wait.until( EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager li.item.active > span'), str(page))) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.m-itemlist .items .item'))) get_products() except TimeoutException: index_page(page) def get_products(): ''' 提取商品 ''' html = browser.page_source doc = pq(html) items = doc('#mainsrp-itemlist .items .item').items() for item in items: product = { 'image': item.find('.pic .img').attr('src'), 'price': item.find('.price').text(), 'deal': item.find('.deal-cnt').text(), 'title': item.find('.title').text(), 'shop': item.find('.shop').text(), 'location': item.find('.location').text() } print(product) save_to_mongo(product) def main(): ''' 遍歷每一頁 ''' for i in range(1, MAX_PAGE+1): index_page(i) browser.close() def save_to_mongo(result): """ 保存至MongoDB """ try: if db[MONGO_COLLECTION].insert(result): print('存儲到MongoDB 成功') except Exception: print('存儲到MongoDB失敗') if __name__ == '__main__': main()
運行結果:

◆◆數據清洗◆◆
拿到數據後,對商品數據進行清洗和處理。
1. 導入數據
import pandas as pd import numpy as np import pymysql import re coon = pymysql.connect( host='localhost', user='root', passwd='root', port=3306, db='taobao', charset='utf8' # port必須寫int類型 # charset必須寫utf8,不能寫utf-8 ) cur = coon.cursor() # 建立游標 sql='select * from taobao_food' df=pd.read_sql(sql=sql,con=coon) #print(df.values) df=pd.DataFrame(df) df=df.drop('id',axis=1) print(pd.isnull(df).values.any())
2. 去重
print('去重之前的形狀',df.shape) df=df.drop_duplicates(keep='first') print('去重之後的形狀',df.shape) print(df.head())

3. 提取地址信息以及購買數量
def get_buy_num(buy_num): if u'萬' in buy_num: # 針對1-2萬/月或者10-20萬/年的情況,包含- buy_num=float(buy_num.replace("萬",''))*10000 #print(buy_num) else: buy_num=float(buy_num) returnbuy_num df['place'] = df['place'].replace('','未知') #fillna("['未知']")datasets = pd.DataFrame() for index, row in df.iterrows(): #print(row["place"]) row["place"] = row["place"][:2] row["buy_num"]=get_buy_num(row["buy_num"][:-3].replace('+','')) #print(row["place"]) df.to_csv('taobao_food.csv',encoding='utf8',index_label=False)
◆◆數據分析◆◆
先來看看美食搜索結果裏面,哪些種類關鍵詞出現的比較多,對商品標題進行文本分析,用詞雲圖進行可視化,代碼如下:
import pandas as pd import jieba, re from scipy.misc import imread from wordcloud import WordCloud, ImageColorGenerator, STOPWORDS import matplotlib.pyplot as plt fr = open('停用詞.txt', 'r') stop_word_list = fr.readlines() new_stop_word_list = [] for stop_word in stop_word_list: stop_word = stop_word.replace('\ufeef', '').strip() new_stop_word_list.append(stop_word) file1 = df.loc[:,'title'].dropna(how='any') # 去掉空值 print('去掉空值後有{}行'.format(file1.shape[0])) # 獲得一共有多少行 print(file1.head()) text1 = ''.join(i for i in file1) # 把所有字符串連接成一個長文本 responsibility = re.sub(re.compile(',|;|.|、|。'), '', text1) # 去掉逗號等符號 wordlist1 = jieba.cut(responsibility, cut_all=True) print(wordlist1) word_dict={} word_list='' for word in wordlist1: if (len(word) > 1 and not word in new_stop_word_list): word_list = word_list + ' ' + word if (word_dict.get(word)): word_dict[word] = word_dict[word] + 1 else: word_dict[word]=1 print(word_list) print(word_dict)#輸出西遊記詞語出現的次數 #按次數進行排序 sort_words=sorted(word_dict.items(),key=lambda x:x[1],reverse=True) print(sort_words[0:101])#輸出前0-100的詞 font_path=r'C:WindowsFontsSIMYOU.TTF' #bgimg=imread(r'1.png')#設置背景圖片 wc = WordCloud(font_path=font_path, # 設置字體 background_color="black", # 背景顏色 max_words=300, # 詞雲顯示的最大詞數 stopwords=stopwords, # 設置停用詞 max_font_size=400, # 字體最大值 random_state=42, # 設置有多少種隨機生成狀態,即有多少種配色 width=2000, height=1720, margin=4, # 設置圖片默認的大小,margin為詞語邊緣距離 ).generate(str(word_list)) #image_colors = ImageColorGenerator(bgimg) # 根據圖片生成詞雲顏色 plt.imshow(wc) plt.axis("off") plt.savefig("examples.jpg") # 必須在plt.show之前,不是圖片空白 plt.show()

果然,不出所料,休閑零食小吃之類的銷量最高;
接下來我們再對商品的銷量進行排名:
print(df['buy_num'].sort_values(ascending=False)) print(df.loc[df['buy_num'].sort_values(ascending=False).index,'shop']) a=df['buy_num'].sort_values(ascending=False) b=df.loc[df['buy_num'].sort_values(ascending=False).index,'shop'] c=df.loc[df['buy_num'].sort_values(ascending=False).index,'title'] frames = [a,b,c] data=pd.concat(frames,axis=1) print(data)

銷量第一名是三隻松鼠旗艦店的豬肉脯,而且前20名裏面,三隻松鼠就佔了將近一半,不得不佩服,果然是零食界扛把子,再一看我老婆的購物車,果然有不少三隻松鼠的零食。
我們再獲取一下銷量排名商店所在的城市信息,看看淘寶銷量最高的美食都來自哪裡
a=df['buy_num'].sort_values(ascending=False) b=df.loc[df['buy_num'].sort_values(ascending=False).index,'place'] c=df.loc[df['buy_num'].sort_values(ascending=False).index,'shop'] frames = [a,c,b] data=pd.concat(frames,axis=1) print('銷售排名商店與所在城市信息分佈n',data)

buy_num_sum=df.groupby(['place'])['buy_num'].sum().sort_values(ascending=False) print('地區銷售總量信息分佈n',buy_num_sum)

做個地區銷售總量信息分佈圖
brougt=buy_num_sum.values.tolist() address=buy_num_sum.index.tolist() map = Map("地區銷售總量信息分佈", "data from 51job",title_color="#404a59", title_pos="left") map.add("銷售總量", address,brougt , maptype='china',visual_range=[0, 300000],is_visualmap=True,visual_text_color='#000',is_label_show=True,is_map_symbol_show=False) map.render("地區銷售總量信息分佈圖.html")

安徽和上海的美食總銷量處於TOP級別的位置,上海排在前幾名我可以理解,安徽有些讓我出乎意料,我猜安徽應該有不少的食品加工廠。
最後,我再來看看商品價格與銷量的分析,看看價格和銷量的關係
a=df.loc[df['buy_num'].sort_values(ascending=False).index,'price'] b=df['buy_num'].sort_values(ascending=False) frames = [a,b] data=pd.concat(frames,axis=1).reset_index() print('商品價格對銷售額的影響分析',data) from pyecharts import Line line = Line("商品價格對銷售額的影響分析") line.add("價格隨銷量降低而變化",data['price'].index,data['price'], is_smooth=True,mark_line=["max", "average"]) line.render('折線圖1.html')

可以明顯看出,隨着銷售額的下降,商品的售賣價格也在增高。換句話說,銷量排名靠前的商品大部分價格都不高,人們也傾向於購買價格實惠的美食
End.
作者:王大陽
來源:CSDN