淘寶數據分析實戰:美食霸榜銷量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