前言
文章介紹并整理了一直在維護(hù)的一個(gè)小項(xiàng)目:京東價(jià)格監(jiān)控锦秒,并詳細(xì)整理了該項(xiàng)目前前后后幾次重構(gòu)的技術(shù)選型,作為一篇總結(jié)。
網(wǎng)站介紹
在京東購物時(shí)尚氛,你是否遇到如下情況:
- 心儀的商品降價(jià)了贩疙,你卻一無所知讹弯,等發(fā)現(xiàn)后早已斷貨况既。
- 你設(shè)置了京東自帶的降價(jià)提醒,結(jié)果在降價(jià)后很久才收到郵件提醒或者干脆沒有提醒组民,錯(cuò)失搶購良機(jī)棒仍。
- 網(wǎng)上各種折扣信息,各種折扣網(wǎng)站臭胜,卻總是不能選擇關(guān)注指定商品
- 想買手機(jī)/電腦/耳機(jī)等類別商品莫其,想知道整個(gè)京東上手機(jī)/電腦/耳機(jī)類目實(shí)時(shí)折扣力度最大的商品。
現(xiàn)在耸三,一個(gè)基于python爬蟲的實(shí)時(shí)價(jià)格監(jiān)控網(wǎng)站上線了乱陡,你要做的僅僅是打開瀏覽器,輸入:
pricemonitor.online
網(wǎng)站功能
一:自定義商品監(jiān)控
設(shè)置商品ID(京東商品編號)和您的預(yù)期價(jià)格仪壮,當(dāng)商品價(jià)格【低于】設(shè)定的預(yù)期價(jià)格后自動(dòng)發(fā)送郵件提醒用戶憨颠。
二:品類商品訂閱
用戶訂閱某品類后(例如數(shù)碼大類),該類所有商品中降價(jià)幅度大于7折的【自營商品】會(huì)被選出并發(fā)送郵件提醒用戶积锅。
網(wǎng)站架構(gòu)演變
小白期:Flask+HTML模板+Python腳本
2017年烙心,我當(dāng)時(shí)入門Python語言,學(xué)著一步步寫網(wǎng)頁爬蟲乏沸,后來接觸到了Python后臺開發(fā)淫茵,之后便萌生了做一個(gè)與爬蟲結(jié)合的前后端項(xiàng)目作為練手,最后想到的就是電商商品的爬取蹬跃。
但是匙瘪,就算在幾年前,信息整合的網(wǎng)站就已經(jīng)非常多了蝶缀。國內(nèi)的商品優(yōu)惠信息整合網(wǎng)站大多是以什么值得買丹喻、惠惠購物助手等信息流推薦+商品歷史價(jià)格查看這種方式運(yùn)營。想要做到有自己的特色翁都,就必須做點(diǎn)不一樣的碍论。
于是我決定將爬蟲作為監(jiān)控手段,監(jiān)控商品的實(shí)時(shí)價(jià)格柄慰。
實(shí)際上鳍悠,拿京東舉例,京東在當(dāng)時(shí)就已經(jīng)有了自己的降價(jià)提醒坐搔,但實(shí)際效果并不好藏研,主要問題出在時(shí)效性上。用自營商品設(shè)置價(jià)格提醒后概行,在京東秒殺時(shí)不提醒蠢挡,在正常顯示價(jià)格調(diào)整后往往在3.4個(gè)小時(shí)后才能收到提醒郵件。
于是,我從單個(gè)商品的監(jiān)控下手业踏,開始了這個(gè)小項(xiàng)目(與其說是項(xiàng)目禽炬,不如說僅僅是一個(gè)小腳本)。
網(wǎng)站需求很簡單勤家,整個(gè)一代目架構(gòu)總結(jié)如下:
爬蟲組件:就是個(gè)簡單的Python腳本瞎抛,加上了定時(shí)循環(huán)。
數(shù)據(jù)庫:采用了最輕量的Sqlite却紧,不需要客戶端和服務(wù)桐臊,單文件保存。
Web端:后臺我采用了網(wǎng)上推薦的Flask晓殊,前端只套用了HTML模板断凶。
Flask中,涉及到使用Flask-Admin巫俺,F(xiàn)lask-Login认烁,F(xiàn)lask-SQLAlchemy,F(xiàn)lask-WTF等組件介汹,搭建了用戶注冊登錄系統(tǒng)却嗡。
爬蟲開源:https://github.com/qqxx6661/Price-monitor
Flask+HTML開源:https://github.com/qqxx6661/flask_yzd
從現(xiàn)在的眼光來看,相比于Python中的Django嘹承,我認(rèn)為Flask對于新上手后臺的小白來說窗价,并不能稱得上是很好的入門框架。至于我為什么這么認(rèn)為叹卷,這就涉及到Flask和Django的區(qū)別了撼港,我摘抄一段答案在這里:
Flask
- Flask與關(guān)系型數(shù)據(jù)庫的配合使用不弱于Django,而其與NoSQL數(shù)據(jù)庫的配合遠(yuǎn)遠(yuǎn)優(yōu)于Django
- 自由骤竹、靈活帝牡,可擴(kuò)展性強(qiáng),開發(fā)時(shí)可以結(jié)合自己最喜歡用的第三方庫
- 適用于小型網(wǎng)站
- 適用于開發(fā)web服務(wù)的API
- 開發(fā)大型網(wǎng)站無壓力蒙揣,但代碼架構(gòu)需要自己設(shè)計(jì)
- 各方面性能均等于或優(yōu)于Django
- Flask比Django更加Pythonic靶溜,與Python的philosophy更加吻合
Django
- 太重了,靈活和自由度不夠高
- Django能開發(fā)小應(yīng)用懒震,但總會(huì)有“殺雞焉用牛刀”的感覺
- Django自帶的Admin好評如潮
- Django的自帶ORM非常優(yōu)秀
- Django自帶的模板引擎
- Django自帶ORM也使Django與關(guān)系型數(shù)據(jù)庫耦合度過高罩息,如果想使用MongoDB等NoSQL數(shù)據(jù),需要選取合適的第三方庫
- Django非常適合企業(yè)級網(wǎng)站的開發(fā):快速挎狸、靠譜扣汪、穩(wěn)定
- Django上手也比較容易断楷,開發(fā)文檔詳細(xì)锨匆、完善,相關(guān)資料豐富
- Django目前支持Jinja等非官方模板引擎
我認(rèn)為對于小白來說,可以先熟悉Django恐锣,我覺得:
- Flask其實(shí)和Spring(或者說Springboot)有異曲同工之妙茅主,兩者依靠官方的第一方庫和網(wǎng)絡(luò)上的第三方庫,來構(gòu)建一個(gè)完整的系統(tǒng)土榴。對于新手來說诀姚,跟著教程上手,很容易在各種庫的組裝中迷失了自己玷禽,各種兼容沖突赫段,各種版本匹配,都會(huì)讓新手摸不到頭腦矢赁。我也深受其害糯笙,兩個(gè)月之后我再拾起代碼,對于之前是如何將各個(gè)庫進(jìn)行整合的撩银,忘得一干二凈给涕。
- Django雖然重,但勝在能讓小白對各個(gè)系統(tǒng)(管理后臺额获,用戶系統(tǒng)够庙,登錄注冊,郵箱驗(yàn)證抄邀,數(shù)據(jù)庫ORM等)都有直觀且實(shí)際的概念耘眨,知道各個(gè)系統(tǒng)在一個(gè)web項(xiàng)目中應(yīng)該發(fā)揮的作用。
如果讓我推薦純小白開始學(xué)Python后臺開發(fā)境肾,我會(huì)建議他從Django開始毅桃,在深入去了解Flask。
說回我的網(wǎng)站准夷,網(wǎng)站初步上線后钥飞,我在自己的博客上還有Github上做了些宣傳。陸續(xù)每天都有幾個(gè)人來訪問我的網(wǎng)站衫嵌,也有在Github上提Issue提建議的读宙。不得不說,正是這些小事讓我看到了項(xiàng)目的活力楔绞,讓我也擁有了更大的編碼熱情结闸。
[圖片上傳失敗...(image-1a2f0b-1545911281129)]
但由于學(xué)校的科研任務(wù)緊,這個(gè)項(xiàng)目在搭建好后酒朵,就進(jìn)入了漫長的維護(hù)階段桦锄,在這個(gè)階段中,除了幾次爬蟲規(guī)則的重新設(shè)計(jì)外蔫耽,并沒有其他業(yè)務(wù)上的改進(jìn)结耀。
過渡期:Django+Bootstrap+Scrapy爬蟲框架+代理池
大概半年后,我重新拾了起來,此時(shí)已經(jīng)有一百多個(gè)注冊用戶了图甜,雖然每天的使用率并不高碍粥,但是也足夠讓我滿足了。本著學(xué)習(xí)技術(shù)的想法黑毅,我開始重構(gòu)網(wǎng)站嚼摩。
當(dāng)時(shí)流行的比價(jià)插件(購物黨/惠惠比價(jià))已經(jīng)開始做商品的價(jià)格監(jiān)控了,并且他們做的是瀏覽器插件矿瘦,完美嵌入瀏覽器枕面,更方便用戶使用,我的價(jià)格監(jiān)控還需要獨(dú)立的網(wǎng)站進(jìn)行商品登記缚去,顯然已經(jīng)out了膊畴。在這期間,我也萌生了品類監(jiān)控的想法病游。
這一時(shí)期的主要改動(dòng)有:
- 從Flask轉(zhuǎn)為Django唇跨,前端使用Bootstrap代替原生HTML模板
- 采用Scrapy分布式爬蟲框架爬取整個(gè)品類的商品
- 采用代理池提高整體采集效率
整個(gè)二代目架構(gòu)總結(jié)如下:
爬蟲組件:從單一的Python腳本改為Scrapy框架爬取。
數(shù)據(jù)庫:使用Mysql作為商品和用戶數(shù)據(jù)庫
Web端:Django衬衬,Django大而全买猖,使用到了Django自帶的后臺管理,數(shù)據(jù)庫ORM滋尉,登錄驗(yàn)證玉控,Session,郵件等子模塊
穩(wěn)定期:Springboot+React+Scrapy爬蟲框架+代理池+任務(wù)隊(duì)列
18年的秋招狮惜,對我來說試一次一場難忘的經(jīng)歷高诺,詳情可以看我的秋招文章。秋招我主要是尋找Java后臺開發(fā)的工作碾篡,所以鉆研了一段時(shí)間的Spring虱而,加之之前的實(shí)習(xí)經(jīng)歷,開發(fā)過實(shí)際的SSM項(xiàng)目开泽,對于后臺開發(fā)牡拇,尤其是web后臺開發(fā)有了更加深刻和廣闊的認(rèn)識,穆律。于是惠呼,我打算對電商監(jiān)控網(wǎng)站進(jìn)行第三次重構(gòu),當(dāng)然峦耘,這次的重點(diǎn)主要是用Spring全家桶替代Django剔蹋。
此外,為了應(yīng)用前后臺分離思想辅髓,我找了一個(gè)帥哥同學(xué)幫我寫React前端泣崩,整個(gè)項(xiàng)目一下子就有模有樣起來少梁。
這一時(shí)期的主要改動(dòng)有:
- 使用Springboot代替Django作為后臺,向前端提供API
- 使用React作為前端律想,接受JSON數(shù)據(jù)
- 改用任務(wù)隊(duì)列發(fā)送郵件
- 代理池支持免費(fèi)代理猎莲,收費(fèi)代理
- 免費(fèi)代理使用Github明星開源項(xiàng)目:https://github.com/jhao104/proxy_pool
整個(gè)三代目架構(gòu)總結(jié)如下:
web網(wǎng)站:Springboot提供接口+React前端頁面
- Springboot(Api)+ Mysql(用戶數(shù)據(jù))+ React(前端)
- 表結(jié)構(gòu)設(shè)計(jì)绍弟、Mybaits技即、Swagger2、Spring Security + JWT樟遣、Spring Cache而叼、跨域、數(shù)據(jù)庫定時(shí)備份
爬蟲:Scrapy分布式爬蟲框架
- Requests/Selenium(爬缺)葵陵、Mysql(商品信息)、Scrapy + Redis(分布式爬蟲)
- 反爬策略瞻佛、IP代理脱篙、Scrapy自定義中間件、Headless Chrome網(wǎng)頁渲染
監(jiān)控:Python腳本+Celery任務(wù)隊(duì)列
- Supervisor(守護(hù)進(jìn)程)伤柄、Crontab(定時(shí)監(jiān)控腳本)绊困、Celery任務(wù)隊(duì)列(提醒郵件)
未來
這個(gè)項(xiàng)目有很多的不足,我也一邊編碼一邊總結(jié)适刀。
現(xiàn)在我的TODO List:
- Docker化各個(gè)模塊
-全局搜索 - QQ微信登錄
- 價(jià)格曲線
- 推廣鏈接
- 添加更多商品
- ...
時(shí)至今日秤朗,這個(gè)項(xiàng)目的兩個(gè)功能可能都能找到更好的替代產(chǎn)品,畢竟一個(gè)人的精力有限笔喉,無法將所有想法都體現(xiàn)在程序上取视。但是這個(gè)項(xiàng)目我還會(huì)堅(jiān)持下去,它已經(jīng)成為了我技術(shù)的試驗(yàn)田常挚,也成為了我繼續(xù)學(xué)習(xí)的動(dòng)力作谭。
關(guān)注我
我的Csdn:
我的知乎:
https://www.zhihu.com/people/yang-zhen-dong-1/
我的簡書:
http://www.reibang.com/u/b5f225ca2376
我的個(gè)人公眾號:Rude3Knife