利用Python對天貓店鋪銷售進(jìn)行分析.上

<p>自從上年年底了解到數(shù)據(jù)分析和挖掘這個概念之后拉宗,今年1月底畢業(yè)前夕峦树,讓自己完全沉下心來學(xué)習(xí)Python的數(shù)據(jù),截止到目前也有4個多月了簿废。我稱這條路叫做數(shù)據(jù)之路空入,我一直在想络它,我們現(xiàn)在身處在這個被數(shù)據(jù)充滿的世界里面族檬,學(xué)會挖掘數(shù)據(jù)以及分析數(shù)據(jù),就像是學(xué)會游泳一樣化戳。即使我不是一個數(shù)據(jù)分析師单料,甚至不是程序員,我僅僅是作為在一家小小的電商公司的計劃工程師点楼,學(xué)會數(shù)據(jù)分析一定可以提高我的工作效率(當(dāng)然最開始的時候是考慮能不能將這個當(dāng)成自己的副業(yè))扫尖。</p>


數(shù)據(jù)之路:

<p>廢話不說,先來聊聊我1月底到現(xiàn)在整個數(shù)據(jù)之路的經(jīng)過掠廓。決定了要用Python進(jìn)行數(shù)據(jù)分析之后换怖,我是先通過這個Codecademy來進(jìn)行Python學(xué)習(xí)的。這個網(wǎng)址好像主要是針對網(wǎng)頁編程的蟀瞧。迅速的過完里面的Python練習(xí)沉颂,有了基本概念条摸,就開始考慮怎么用Python來進(jìn)行數(shù)據(jù)分析了。</p>

<p>這個時候铸屉,第二個網(wǎng)站映入了我的眼簾钉蒲,叫做Dataquest。這個網(wǎng)址不錯彻坛,里面有所有關(guān)于數(shù)據(jù)分析的課程顷啼,他有三個Level,分別叫做Data Analyst昌屉,Data Scientist钙蒙,以及Data Engineer(這個目前還沒有開放)。</p>

  • Data Analyst的課程包括:基本Python的用法间驮,Pandas的使用仪搔,數(shù)據(jù)可視化,Linux系統(tǒng)命令行操作基礎(chǔ)蜻牢,簡單的爬蟲網(wǎng)絡(luò)烤咧,統(tǒng)計原理,R語言抢呆。
  • Data Scientist可以認(rèn)為是Data Analyst 的升級版煮嫌,加入了:機器學(xué)習(xí),數(shù)據(jù)結(jié)構(gòu)和算法抱虐,高級Python用法昌阿,大數(shù)據(jù)的處理方式。

<p>其中部分課程是要收費才能做恳邀,我就充了兩個月的Basic會員懦冰,將Data Analyst的課程完成了個85%之后感覺就差不多了。</p>

<p>除此之外谣沸,還看了些書刷钢,最重要當(dāng)然要看是Python各個庫的Document。</p>


第一個實例:

立項

<p>第一個實例做什么我還是想了好久乳附,想做點實用點的内地,就選了淘寶的一個門店,來做數(shù)據(jù)每天的銷量以及評論更新狀態(tài)分析吧赋除。任務(wù)包括:</p>

  • 收集產(chǎn)品的基本信息阱缓;
  • 每天定點收集最新的銷量以及推送的評論;

<p>隨便選了個門店举农,先打開主頁瀏覽下荆针,發(fā)現(xiàn)是賣傘的,仔細(xì)看一下,有5個類別:Black航背、Air秸妥、Bon、Joli沃粗、Moma(X系列進(jìn)去看好像都停售粥惧,就不管了)。</p>

Request扒內(nèi)容

<p>采用Requests模塊最盅,采用get(說起來get函數(shù)和post函數(shù)是什么區(qū)別突雪,什么時候要用get函數(shù)或者post函數(shù),到現(xiàn)還沒有搞懂)函數(shù)將url里面的內(nèi)容扒下來涡贱,同時加了headers咏删,將自己偽裝成瀏覽器。將扒下來來的內(nèi)容用BeautifulSoup進(jìn)行中‘lxml’解析器進(jìn)行解析问词,這樣網(wǎng)頁的內(nèi)容就像是被扒光衣服一樣展示在我們面前督函。</p>

<p>另外,在BeautifulSoup中有四種解析器激挪,分別是自帶的辰狡、'lxml'、‘xml’以及‘html5lib’四種解析器垄分,具體區(qū)別可以看Document文件宛篇。</p>

import requests
from bs4 import BeautifulSoup

url = "https://bananaumbrella.tmall.com/?"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36"}
response = requests.get(url, headers = headers)
interial = BeautifulSoup(response.content, "lxml")

<p>獲得HTML的內(nèi)容之后,快速在Console上Crtl+F尋找上面的幾個類別薄湿,很快就找到了這個這段代碼(每個類別都類似叫倍,就復(fù)制兩段),每個href中的catName很明顯就是我們要找的東西:</p>

<li class="cat fst-cat">
<li class="cat fst-cat">
<h4 class="cathd fst-cat-hd ">
<i class="cat-icon fst-cat-icon active-trigger"></i>
<a class="cat-name fst-cat-name" >Black</a>
</h4>
</li>
<li class="cat fst-cat">
<h4 class="cat-hd fst-cat-hd ">
<i class="cat-icon fst-cat-icon active-trigger"></i>
<a class="cat-name fst-cat-name" >Air</a>
</h4>
</li>

<p>其中豺瘤,每個tag里面的href中的url就是我們需要的吆倦。利用BeautifulSoup中的find_all函數(shù)將這些標(biāo)簽抓出來,先通過find_all尋找所有a標(biāo)簽坐求,返回一個含有a標(biāo)簽的list蚕泽,再通過list的鏈表推導(dǎo)式將其中的href抓取出來。其中get()是個好東西赛糟,例如這句話:</p>

<a class="cat-name fst-cat-name" >Moma</a>

<p>通過get('href')就可以直接獲得其中的鏈接,對獲得的list再通過list slice就可以得到每個類別的url砸逊。</p>

categroys = interial.find_all("a")
categroy = [item.get("href") for item in categroys if item.get("class") == ['cat-name', 'fst-cat-name']]
categroy = categroy[1:]
建立Sqlite數(shù)據(jù)庫

<p> 我也不知道為什么我對Sql如此的喜歡,其中項目一開始我是導(dǎo)出為csv函數(shù)的掌逛,后來大概是可能想到之前在dataquest上學(xué)了Sql的語法师逸,就想在這個任務(wù)里面嘗試吧。(從最終的結(jié)果來看豆混,其實我不太能分別我最后得到db好還是csv好篓像,求大神指點呀动知。。)</p>

<p>在Sql上學(xué)過db中幾個表格的關(guān)聯(lián)员辩,經(jīng)過無數(shù)次的嘗試盒粮,我知道每次采集的數(shù)據(jù)中有很多相同的參數(shù),例如產(chǎn)品的ID(skuid)奠滑,名稱(name)丹皱,鏈接地址(href),原售價(oldprice)宋税,活動售價(price)摊崭。而變化的參數(shù)有兩個:</p>

  • 銷量(scount)
  • 評論(cite)

<p>評論和銷量每次更新時,都會以當(dāng)前時間增加一列杰赛,加入新內(nèi)容呢簸。</p>

<p>因此我就想到了用采用表格的鍵約束,制作一個主表用于存放變化不變的參數(shù)乏屯,制作兩個附表分別存放銷量和評論根时,主表的附表之間通過鍵(key)來連接。</p>

<p>所以首先當(dāng)然是要建立一個數(shù)據(jù)庫db文件了辰晕,然后建立表格啸箫,建表的時候一開始我是采用CREATE TABLE UB(skuid int primary key , name text, href text, oldprice real, price real);,后來發(fā)現(xiàn)如果重復(fù)調(diào)試這個程序的時候伞芹,必須要先將久的db文件刪除之后忘苛,才能執(zhí)行,不然回報錯唱较。所以后面我就將這句話改成CREATE TABLE IF NOT EXISTS UB(skuid int primary key , name text, href text, oldprice real, price real)扎唾;。</p>

<p>建立主表時候南缓,一個要約定哪個是鍵(primary key)胸遇,這里采用每個商品的id作為鍵(key),而主表UB里面的是primary key,附表 scount 和 cite 里面的是foreign key汉形。</p>

import datetime, sqlite3

conn = sqlite3.connect("data.db")
time = datetime.datetime.now()
c = conn.cursor()
time = time.strftime("%Y%m%d-%H%M")
c.execute("CREATE TABLE IF NOT EXISTS UB(skuid int primary key , name text, href text, oldprice real, price real);")
c.execute("CREATE TABLE IF NOT EXISTS CITE(citeskuid int, FOREIGN KEY(citeskuid) REFERENCES UB(skuid));")
c.execute("CREATE TABLE IF NOT EXISTS SCOUNT(scountskuid int, FOREIGN KEY(scountskuid) REFERENCES UB(skuid));")
c.execute("ALTER TABLE CITE ADD COLUMN '%s' 'text';" % time)
c.execute("ALTER TABLE SCOUNT ADD COLUMN '%s' 'int';" % time)
解析每個類別網(wǎng)址的內(nèi)容

<p>首先繼續(xù)采用Requests函數(shù)以及BeautifulSoup函數(shù)去將頁面的內(nèi)容解析出來纸镊,過程和我們一開始做的一樣,不做重復(fù)概疆。</p>

<p>結(jié)合瀏覽器的Inspect功能進(jìn)行搜索逗威,不難找到每個類似的這樣一段內(nèi)容(誰可以告訴我像這種html正確的排版應(yīng)該是怎樣的。岔冀。凯旭。):</p>

<div class="popitem" style="width:167px;">
<a class="pic"  style="width:167px;" target="_blank">
<img data-ks-lazyload="http://gdp.alicdn.com/bao/uploaded/i4/TB13q8EKpXXXXbzaXXXXXXXXXXX_!!0-item_pic.jpg_220x10000.jpg" src="http://assets.alicdn.com/s.gif" title="【新品】BananaUmbrella蕉下小黑傘蘇桃雙層防曬女太陽傘遮陽傘" width="167"/> 
</a>
<div class="expannel expannel-float">
<a class="mask"  style="display:block;visibility:visible;" target="_blank">
</a>
<div class="exinfo exi_2 ext_4 abs" style="bottom:0px;">
<div class="desc">
<a  target="_blank">【新品】BananaUmbrella蕉下小黑傘蘇桃雙層防曬女太陽傘遮陽傘</a>
</div>
<div class="scount" style="float:left;">
<i>已售:</i> 
<em>(218520)</em>
</div>
<div class="simple-sns sns-widget" data-like='{"title":"http://item.taobao.com/item.htm?id=24875700842","key":"24875700842","type":2}' style="float:left;"></div>
<div class="simple-sns sns-widget" data-sharebtn='{"type":"item","key":"24875700842","client_id":"68"}' style="float:right;" title="微博分享"></div>
<div style="clear:both;"></div>
</div>
</div>
<div class="itembox" style="width:167px;">
<div class="bottom-sprice">
<a  target="_blank">
<span class="rmb">RMB: </span><em>249.00</em>
<s class="oldprice"><span class="rmb">RMB: </span><em>599</em></s>
</a>
</div>
</div>
<div class="rates" style="width:167px;">
<div class="feedback">
<img data-ks-lazyload="http://wwc.alicdn.com/avatar/getAvatar.do?userId=0&width=24&height=24&type=sns" height="20" src="http://assets.alicdn.com/s.gif"/> 
 <span>1***_</span> 質(zhì)量很好,遮陽也超好,就是份量有點撐罐呼,因為是雙層所以卷完也比較大鞠柄,總體還是不錯的
</div>
</div>
</div>

<p>里面涵蓋了所有我們需要的信息。因此嫉柴,先用find_all函數(shù)將所有tag為div厌杜,classpopitem的先扒出來。扒出來之后计螺,發(fā)現(xiàn)list有重復(fù)的夯尽,通過set函數(shù)刪除重復(fù)的項目</p>

find_item = interial_item.find_all("div", "popitem")
find_item = list(set(find_item))

<p>對find_item里面的內(nèi)容進(jìn)行循環(huán),開始按照我們的需要將里面的內(nèi)容一個個的剔除出來危尿。</p>

<p>先是找出我們的primary key呐萌。在classdesc的標(biāo)簽中,里面就包含了產(chǎn)品的商品的名字以及對應(yīng)的鏈接谊娇,再仔細(xì)看看鏈接回發(fā)現(xiàn)后面有id=24875700842肺孤,這就是我們要找的。注意济欢,找class時候可以同時根據(jù)tagclass一起找赠堵,而class的尋找除了可以用上面的方法,還可以通過關(guān)鍵字class_(區(qū)別class法褥,用class會報錯)來尋找茫叭。找到href之后,發(fā)現(xiàn)我們要的id就是一串?dāng)?shù)字半等,可以通過正則表達(dá)式re.search("\d+", href)來搜索揍愁,并通過group()返回搜索的字符串,再通過int將字符串轉(zhuǎn)為整型杀饵,最終寫為:</p>

desc = item.find("div", class_="desc")
href = desc.a.get("href")
pri = int(re.search("\d+", href).group())

<p>這個時候莽囤,基本信息已經(jīng)找到了,可以將相應(yīng)的信息寫入我們的主表中切距,寫的時候需要判斷朽缎,這個id在我們的表格中是否存在,如果存在我們就不繼續(xù)添加信息到主表中:</p>

c.execute("SELECT skuid FROM UB;")
if (pri,) not in c.fetchall():
    name = desc.string
    prices = item.find("div", class_="bottom-sprice").find_all("em")
    price = float(prices[0].string)
    oldprice = float(prices[1].string)
    href = "https:" + href
    c.execute("INSERT INTO UB VALUES(?, ?, ?, ?, ?);", [pri, name, href, oldprice, price]) 

<p>后面就是將sount和cite扒出來谜悟,scount容易通過item.em.string就出來话肖,但是剔除出來的是一個帶括號的字符,寫一個正則表達(dá)式的函數(shù)將括號剔除:</p>

def del_par(string):
    patt = re.compile("\((.*)\)")
    str_list = patt.findall(string)
    return int(str_list[0])

<p>對應(yīng)的scount和cite找到之后葡幸,就要考慮怎么將數(shù)據(jù)寫入到我們的附表中最筒,這個時候需要注意有兩種情況,如果是第一次輸入的時候礼患,需要加入產(chǎn)品的skuid以及相應(yīng)的內(nèi)容是钥,如果是判定該skuid是已經(jīng)在附表的id列表中掠归,那就直接更新對應(yīng)列的數(shù)據(jù)即可:</p>

scount = del_par(item.em.string)
feedback = item.find("div", "feedback").contents
user = feedback[2].string
cite = user + ":" +feedback[3]     
c.execute("SELECT scountskuid FROM SCOUNT;")
if (pri,) not in c.fetchall():
    c.execute("INSERT INTO SCOUNT(scountskuid, '%s') VALUES('%s', '%s');" % (time, pri, scount))
    c.execute("INSERT INTO CITE(citeskuid, '%s') VALUES('%s', '%s');" % (time, pri, scount))           
else:
    c.execute("UPDATE SCOUNT SET '%s' = '%s' WHERE scountskuid = '%s';" % (time, scount, pri))
    c.execute("UPDATE CITE SET '%s' = '%s' WHERE citeskuid = '%s';" % (time, cite, pri))

最后缅叠,寫完之后悄泥。還要將所有我們的命令提交才叫完成:

c.close()
conn.commit()
Ubuntu定時任務(wù)

<p>為了可以時刻監(jiān)控數(shù)據(jù),需要在Ubuntu里面設(shè)置任務(wù)肤粱,買了一個國外的服務(wù)DigitalOcean弹囚,并設(shè)置Ubuntu的定時任務(wù):</p>

$ crontab -e

<p>通過nano設(shè)置任務(wù):</p>

30 8,13,18,23 * * * [script address] >> [log record] 2<&1

結(jié)語:

<p>這樣就基本完成自己寫的第一個項目任務(wù)了,可以收集信息领曼,可以儲存數(shù)據(jù)鸥鹉,當(dāng)然稍作改動就可以將數(shù)據(jù)保存為csv。除此之外庶骄,后續(xù)這個程序還有改進(jìn)的空間毁渗,包括:</p>

  • 每天晚上對一天采集的數(shù)據(jù)進(jìn)行分析,分析出今天的最佳銷量(用Sql就可以實現(xiàn))
  • 通過銷量和單價計算每日的銷售額(終于需要可以用Pandas了)
  • 將上面的內(nèi)容統(tǒng)一生成pdf報表(pdf生成目前還沒有思路)
  • 將報表發(fā)到郵箱中(發(fā)送郵箱應(yīng)該是可以很輕松完成的)

<p>下一篇文章將會對這方面進(jìn)行重點研究单刁。</p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末灸异,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子羔飞,更是在濱河造成了極大的恐慌肺樟,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逻淌,死亡現(xiàn)場離奇詭異么伯,居然都是意外死亡,警方通過查閱死者的電腦和手機卡儒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門田柔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人骨望,你說我怎么就攤上這事硬爆。” “怎么了锦募?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵摆屯,是天一觀的道長。 經(jīng)常有香客問我糠亩,道長虐骑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任赎线,我火速辦了婚禮廷没,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垂寥。我一直安慰自己颠黎,他們只是感情好另锋,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著狭归,像睡著了一般夭坪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上过椎,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天室梅,我揣著相機與錄音,去河邊找鬼疚宇。 笑死亡鼠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的敷待。 我是一名探鬼主播间涵,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼榜揖!你這毒婦竟也來了勾哩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤根盒,失蹤者是張志新(化名)和其女友劉穎钳幅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炎滞,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡敢艰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了册赛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钠导。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖森瘪,靈堂內(nèi)的尸體忽然破棺而出牡属,到底是詐尸還是另有隱情,我是刑警寧澤扼睬,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布逮栅,位于F島的核電站,受9級特大地震影響窗宇,放射性物質(zhì)發(fā)生泄漏措伐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一军俊、第九天 我趴在偏房一處隱蔽的房頂上張望侥加。 院中可真熱鬧,春花似錦粪躬、人聲如沸担败。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽提前。三九已至吗货,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岖研,已是汗流浹背卿操。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工警检, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留孙援,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓扇雕,卻偏偏與公主長得像拓售,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子镶奉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容