本篇文章是關於某化妝品企業的銷售分析。從分析思路開始帶大家一步步地用python進行分析,找出問題,並提出解決方案的整個流程。
以下文章來源於修煉Python
作者:葉庭雲
一、前言
看到可愛的貓咪表情包,總是會忍不住收藏,曬部份圖如下:
認識的一些朋友也養了貓,比如橘貓、英短、加菲貓之類的,看他們發朋友圈擼貓,老羨慕了,貓咪真的太可愛啦。發現一個專門交易貓貓的網站—貓貓交易網可以雲看貓: http://www. maomijiaoyi.com/
從這個網站裏爬取了貓貓品種介紹的數據,以及 20W+ 條貓貓交易數據,以此來了解一下可愛的貓咪。
二、數據獲取
開啟貓貓交易網,先爬取貓咪品種數據,開啟頁面可以看到貓貓品種列表:
但只顯示了每種貓貓的品種名,參考價格,點進詳情頁,可以看到更加詳細的數據:品種名、參考價格、中文學名、基本資訊、性格特點、生活習性、優缺點、餵養方法等。
檢查網頁,可以發現網頁結構簡單,容易解析和提取數據。爬蟲程式碼如下:
import requests
import re
import csv
from lxml import etree
from tqdm import tqdm
from fake_useragent import UserAgent
# 隨機產生請求頭
ua = UserAgent(verify_ssl=False, path='fake_useragent.json')
def random_ua(): # 用於隨機切換請求頭
headers = {
"Accept-Encoding": "gzip",
"Accept-Language": "zh-CN",
"Connection": "keep-alive",
"Host": "www.maomijiaoyi.com",
"User-Agent": ua.random
}
return headers
def create_csv(): # 建立保存數據的csv
with open('./data/cat_kind.csv', 'w', newline='', encoding='utf-8') as f:
wr = csv.writer(f)
wr.writerow(['品種', '參考價格', '中文學名', '別名', '祖先', '分布區域',
'原產地', '體型', '原始用途', '今日用途', '分組', '身高',
'體重', '壽命', '整體', '毛發', '顏色', '頭部', '眼睛',
'耳朵', '鼻子', '尾巴', '胸部', '頸部', '前驅', '後驅',
'基本資訊', 'FCI標準', '性格特點', '生活習性', '優點/缺點',
'餵養方法', '鑒別挑選'])
def scrape_page(url1): # 獲取HTML網頁原始碼 返回文本
response = requests.get(url1, headers=random_ua())
# print(response.status_code)
response.encoding = 'utf-8'
return response.text
def get_cat_urls(html1): # 獲取每個品種貓咪詳情頁url
dom = etree.HTML(html1)
lis = dom.xpath('//div[@ class="pinzhong_left"]/a')
cat_urls = []
for li in lis:
cat_url = li.xpath('./@href')[0]
cat_url = 'http://www.maomijiaoyi.com' + cat_url
cat_urls.append(cat_url)
return cat_urls
def get_info(html2): # 爬取每個品種貓咪詳情頁裏的有關資訊
# 品種
kind = re.findall('div class="line1">.*?<div class="name">(.*?)<span>', html2, re.S)[0]
kind = kind.replace('\r','').replace('\n','').replace('\t','')
# 參考價格
price = re.findall('<div>參考價格:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
price = price.replace('\r', '').replace('\n', '').replace('\t', '')
# 中文學名
chinese_name = re.findall('<div>中文學名:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
chinese_name = chinese_name.replace('\r', '').replace('\n', '').replace('\t', '')
# 別名
other_name = re.findall('<div>別名:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
other_name = other_name.replace('\r', '').replace('\n', '').replace('\t', '')
# 祖先
ancestor = re.findall('<div>祖先:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
ancestor = ancestor.replace('\r', '').replace('\n', '').replace('\t', '')
# 分布區域
area = re.findall('<div>分布區域:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
area = area.replace('\r', '').replace('\n', '').replace('\t', '')
# 原產地
source_area = re.findall('<div>原產地:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
source_area = source_area.replace('\r', '').replace('\n', '').replace('\t', '')
# 體型
body_size = re.findall('<div>體型:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
body_size = body_size.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 原始用途
source_use = re.findall('<div>原始用途:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
source_use = source_use.replace('\r', '').replace('\n', '').replace('\t', '')
# 今日用途
today_use = re.findall('<div>今日用途:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
today_use = today_use.replace('\r', '').replace('\n', '').replace('\t', '')
# 分組
group = re.findall('<div>分組:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
group = group.replace('\r', '').replace('\n', '').replace('\t', '')
# 身高
height = re.findall('<div>身高:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
height = height.replace('\r', '').replace('\n', '').replace('\t', '')
# 體重
weight = re.findall('<div>體重:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
weight = weight.replace('\r', '').replace('\n', '').replace('\t', '')
# 壽命
lifetime = re.findall('<div>壽命:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
lifetime = lifetime.replace('\r', '').replace('\n', '').replace('\t', '')
# 整體
entirety = re.findall('<div>整體</div>.*?<!-- 頁面小折角 -->.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
entirety = entirety.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 毛發
hair = re.findall('<div>毛發</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
hair = hair.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 顏色
color = re.findall('<div>顏色</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
color = color.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 頭部
head = re.findall('<div>頭部</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
head = head.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 眼睛
eye = re.findall('<div>眼睛</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
eye = eye.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 耳朵
ear = re.findall('<div>耳朵</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
ear = ear.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 鼻子
nose = re.findall('<div>鼻子</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
nose = nose.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 尾巴
tail = re.findall('<div>尾巴</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
tail = tail.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 胸部
chest = re.findall('<div>胸部</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
chest = chest.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 頸部
neck = re.findall('<div>頸部</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
neck = neck.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 前驅
font_foot = re.findall('<div>前驅</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
font_foot = font_foot.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 後驅
rear_foot = re.findall('<div>前驅</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
rear_foot = rear_foot.replace('\r', '').replace('\n', '').replace('\t', '').strip()
# 保存前面貓貓的各種有關資訊
cat = [kind, price, chinese_name, other_name, ancestor, area, source_area,
body_size, source_use, today_use, group, height, weight, lifetime,
entirety, hair, color, head, eye, ear, nose, tail, chest, neck, font_foot, rear_foot]
# 提取標簽欄資訊(基本資訊-FCI標準-性格特點-生活習性-優缺點-餵養方法-鑒別挑選)
html2 = etree.HTML(html2)
labs = html2.xpath('//div[@ class="property_list"]/div')
for lab in labs:
text1 = lab.xpath('string(.)')
text1 = text1.replace('\n','').replace('\t','').replace('\r','').replace(' ','')
cat.append(text1)
return cat
def write_to_csv(data): # 保存數據 追加寫入
with open('./data/cat_kind.csv', 'a+', newline='', encoding='utf-8') as fn:
wr = csv.writer(fn)
wr.writerow(data)
if __name__ == '__main__':
# 建立保存數據的csv
create_csv()
# 貓咪品種頁面url
base_url = 'http://www.maomijiaoyi.com/index.php?/pinzhongdaquan_5.html'
# 獲取品種頁面中的所有url
html = scrape_page(base_url)
urls = get_cat_urls(html)
# 進度條視覺化執行情況 就不打印東西來看了
pbar = tqdm(urls)
# 開始爬取
for url in pbar:
text = scrape_page(url)
info = get_info(text)
write_to_csv(info)
執行效果如下:
成功爬取了貓咪品種數據保存到csv,接下來爬取貓貓交易數據,進入到買貓賣貓頁面:
爬取更詳細的數據需要進入詳情頁,包含商家資訊、貓咪品種、貓齡、價格、標題、在售只數、預防等資訊。
由於數據量較大,可以分開爬取,先獲取到每一頁中的所有貓貓詳情交易連結的 url 保存到csv,再讀取 csv 中的 url 來請求,爬取每條交易數據,爬蟲思路跟前面類似,為了加快爬取效率,可以使用多執行緒或者異步爬蟲。最終獲取了 20W+ 條數據。
三、數據探索
透過詞雲圖來直觀看一下,可愛的貓咪都有那些品種。
看各種貓咪的體型分布
所有品種的貓咪裏,大型的只有一個品種,是布偶貓,其他品種都是中小型,那以後看見體型比較大的,可以先想到布偶貓。
橘貓是世界各地都有的,不愧是我大橘貓。俗話說 "十個橘貓九個胖還有一個壓塌炕"。橘貓比起其他花色的貓咪更喜歡吃東西,它們的食欲很好,能更好地生存,可能這也是橘貓在世界範圍都有的原因吧。可它卻是小型貓,橘貓小時候顏值一般挺高,看起來小小的一只,又嫩又可愛的,但等橘貓長大以後,才真正地意識到什麽是 "橘足輕重"。
下面來看貓咪的交易數據,在交易的貓咪中,哪些品種交易數量最多呢?
橘貓的交易數量最多呀,之前也提到橘貓世界各地都有,從這裏也可以看到橘貓數量最多。其次是咖啡貓,布偶貓,英短藍白貓等。(不愧是我大橘)
緬因貓、布偶貓均價名列前茅啊,橘貓的均價排倒數第二,看來挺實惠。
這些售賣的貓咪貓齡一般為多大呢?
售賣的貓咪貓齡主要在1-6個月,都是剛出生還未滿半歲的小貓咪呀。這時候的小貓咪應該很可愛吧,等待有緣的主人把它帶回家。
最後來看一下網站裏價格最貴的貓咪和瀏覽次數最多的貓咪
import pandas as pd
df = pd.read_excel('處理後數據.xlsx')
print(df.info())
df1 = df.sort_values(by='瀏覽次數', ascending=False)
print(df1.iloc[:3, ::].values)
print('----------------------------------------------------------')
df2 = df.sort_values(by='價格', ascending=False)
print(df2.iloc[:3, ::].values)
# 瀏覽次數最多的
http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_441879.html
http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_462431.html
http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_455366.html
瀏覽次數最多的是這一家賣的緬因貓,瀏覽次數為16164
反觀瀏覽次數排第二、第三的,價格便宜不少,預防都打了3針疫苗,在售只數還比較充裕
# 價格最貴的如下
http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_265770.html
http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_281910.html
http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_230417.html
價格最貴的發現均為 3000 元的布偶貓。查閱資料發現,布偶貓,大型貓咪,不僅購買的時候價格高昂,飼養成本也比較高,因為食量和運動量都比較大,而且美容等相關費用也會高一些。