您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Python實(shí)現(xiàn)商品價(jià)格監(jiān)控的方法,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
一年一度的“雙十一”又要來了,很多人已經(jīng)開始摩拳擦掌,畢竟幾天之后手還在不在就不好說了。
各種社交軟件也是跟著遭殃,整天就是“來幫我一起蓋樓”,各種字體繞過屏蔽,什么奇葩的腦洞也出來了:
不過也感謝這些電商平臺(tái),讓多年未聯(lián)系的好友、加過但沒有對(duì)話的陌生人都找到了打破尷尬的話題。(讓場(chǎng)面更加尷尬)
月薪上萬的白領(lǐng)們?yōu)榱?塊5毛錢的優(yōu)惠券起早貪黑,也是堪稱人類迷惑行為大賞了……
問題是,你以為自己真的賺到了?
商品“明降暗升”的傳言早有耳聞:很多商品在雙十一之前早早地把價(jià)格調(diào)高,加上優(yōu)惠之后也不過就是跟以前的原價(jià)相當(dāng)。讓不知情的消費(fèi)者在心理上感覺占了便宜。
這個(gè)傳言是不是真的,很好判斷,只要定期去訪問商品頁面,記錄價(jià)格就可以。不過一般人也沒閑工夫這么去做。于是,我們用 Python 做了一個(gè)可以定時(shí)監(jiān)控商品的小工具,可以幫你監(jiān)控想要關(guān)注的商品。
工具完成之后,我們隨機(jī)挑選了幾個(gè)商品作為測(cè)試,結(jié)果就有一個(gè)中招了……(真的是隨便選的):
這款保暖背心產(chǎn)品,之前標(biāo)價(jià) 39.9元,到11月之后卻突然調(diào)價(jià)為 49.9元,并標(biāo)注上了“雙11狂歡價(jià)”,也就是原價(jià)……
商品價(jià)格監(jiān)控
實(shí)現(xiàn)功能
·輸入天貓、蘇寧、京東、拼多多(網(wǎng)頁頁面 http://yangkeduo.com/)任一商品鏈接,不是口令。請(qǐng)復(fù)制選擇好商品配置的頁面鏈接,即返回相應(yīng)商品價(jià)格,并保存到文件。商品頁面若有團(tuán)購(gòu)與單獨(dú)購(gòu)買兩個(gè)價(jià)格,返回團(tuán)購(gòu)價(jià)格。
·使用 Windows 任務(wù)計(jì)劃或 Linux 定時(shí)任務(wù),定時(shí)執(zhí)行程序。獲取不同時(shí)段的商品價(jià)格信息。
·單獨(dú)運(yùn)行畫圖程序,可根據(jù)定時(shí)任務(wù)獲取的數(shù)據(jù),生成商品價(jià)格時(shí)間變化折線圖。
·程序監(jiān)測(cè)的兩件商品截圖如下,具體文件在 pic 文件夾下 bnbx.html、kyy.html,推薦本地查看。
簡(jiǎn)單的商品查看頁面 https://htmlpreview.github.io/?https://raw.githubusercontent.com/spiderbeg/price_monitor/master/search/search.html 。輸入查詢商品關(guān)鍵詞,選擇商城,即可查看相應(yīng)商城商品列表。默認(rèn)為蘇寧。效果圖如下。注意:點(diǎn)擊后請(qǐng)等待一段時(shí)間即可,請(qǐng)勿頻繁刷新。
運(yùn)行環(huán)境
·python3.7
·Windows
·jupyter notebook
運(yùn)行依賴包
·requests
·pyecharts
·beautifulsoup4
項(xiàng)目思路
部分問題回答
項(xiàng)目的大致思路流程:
·第一步:使用商品詳細(xì)頁鏈接獲取商品信息與商品價(jià)格,并保存獲取數(shù)據(jù) 時(shí)間、商品介紹,價(jià)格 到 csv 文件中;
·第二步:使用定時(shí)任務(wù)定時(shí)執(zhí)行第一步完成的程序;
·第三步:讀取前兩步獲取到的時(shí)間、商品介紹、價(jià)格數(shù)據(jù)。使用 pyecharts 繪制繪制商品價(jià)格時(shí)間變化折線圖。
為什么不使用 pc 端來調(diào)試網(wǎng)頁,獲取價(jià)格信息?
因?yàn)樵谖吹卿洜顟B(tài)天貓的詳細(xì)商品頁的信息是虛假的,同時(shí)從移動(dòng)端網(wǎng)頁入手,可以降低調(diào)試難度。
谷歌瀏覽器如何開啟手機(jī)調(diào)試模式?
F12 進(jìn)入開發(fā)者模式,然后鼠標(biāo)點(diǎn)擊一下,具體見下圖,包括后文的查找價(jià)格接口信息。
實(shí)現(xiàn)代碼
test.py
測(cè)試商品鏈接是否能夠成功獲取到商品價(jià)格。
import timing """ 1、調(diào)用 timing.py 中的 go 方法測(cè)試鏈接的可用性 2、調(diào)用 timing.py 中的 go, get_url() 方法測(cè)試 goods.csv 文件中鏈接的可用性 """ # 鏈接測(cè)試 # urls = ['https://m.suning.com/product/0000000000/000000011210599174.html?utm_source=baidu&utm_midium=brand-wuxian &utm_content=&utm_campaign=title&safp=f73ee1cf.wapindex7.113464229882.4&safc=prd.1.rec_14-40_0_A_ab:A', # 'https://m.suning.com/product/0070067092/000000000188392234.html?utm_source=baidu&utm_midium=brand-wuxian& utm_content=&utm_campaign=title&safp=f73ee1cf.wapindex7.113464229882.60&safc=prd.1.rec_5-5_1018C,1014C$ c3ae37eafeb814a098d120647449da6f_H_ab:A', # 'https://m.suning.com/product/0000000000/000000000107426461.html?src=snsxpd_none_recssxcnxhq_1-3_p_0000000000 _000000000107426461_rec_21-65_3_A&safp=f73ee1cf.71jyzx.112079032536.4&safc=prd.1.rec_21-65_3_A', # 'https://m.suning.com/product/0000000000/10606656136.html?safp=f73ee1cf.phone2019.121927933306.2&safc=prd.0.0'] # 輸入文本的鏈接可用性測(cè)試 if __name__ == '__main__': urls = timing.get_url() for url in urls: try: timing.go(url) # 獲取返回信息 except BaseException as e: print(url,'\n',e)
timing.py
進(jìn)行定時(shí)抓取任務(wù)時(shí),運(yùn)行的文件。
# encoding:utf8 import time import os import re import csv from shop.jd import JD # 自定義 from shop.tm import TM from shop.sn import SN from shop.pdd import PDD from apscheduler.schedulers.blocking import BlockingScheduler # import logging # formats = "%(asctime)s %(name)s %(levelname)s function:%(funcName)s -> :%(message)s" # logging.basicConfig(format=formats, datefmt='%m/%d/%Y %I:%M:%S %p') # ,handlers=[logging.FileHandler(log_path, 'a+', 'utf-8')] # LOGGER = logging.getLogger(__name__) # LOGGER.setLevel(logging.INFO) basePath = os.path.dirname(os.path.abspath(__file__)) # 當(dāng)前文件夾 def get_date(): """獲取日期""" timestamp = int(time.time()) time_local = time.localtime(timestamp) # #時(shí)間戳 轉(zhuǎn) 時(shí)間數(shù)組 dt = time.strftime("%Y-%m-%d %H:%M:%S",time_local) # #時(shí)間數(shù)組 轉(zhuǎn) 新的時(shí)間格式(2016-05-05 20:28:54) return dt def get_url(): """讀取商品鏈接 返回:圖像名,商品名,商品鏈接 元組 """ urls = [] with open(os.path.join(basePath, 'goods.csv'),'r',encoding='utf8') as f: f_csv = csv.reader(f) next(f_csv) # 返回標(biāo)題,直接到內(nèi)容 for row in f_csv: # 內(nèi)容 if row: urls.append(row) return urls def go(url): '''輸入:鏈接 輸出:(時(shí)間,標(biāo)題,商品價(jià)格), 文件路徑 元組 統(tǒng)一價(jià)格輸出,以最低價(jià)格為標(biāo)準(zhǔn),如有團(tuán)購(gòu)和單獨(dú)購(gòu)買以單獨(dú)購(gòu)買為準(zhǔn) ''' result = re.findall('://(.+?).com', url[2]) if result: result = result[0] if 'yangkeduo' in result: pd = PDD(url[2]) title,price = pd.main() elif 'suning' in result: sn = SN(url[2]) title,price = sn.main() elif 'tmall' in result or 'taobao' in result: tm = TM(url[2]) # 605030977928:聯(lián)想筆記本 ; 603330883901 華為 mate30 pro ; 523962011119: 酸奶 title,price = tm.main() elif 'jd' in result: jd = JD(url[2]) # 測(cè)試 id:100009083152 商品:聯(lián)想 y9000x 筆記本電腦 2 熱水壺 or 薯?xiàng)l? title,price = jd.main() else: raise TypeError('請(qǐng)檢查輸入的網(wǎng)站鏈接') print('%s 標(biāo)題 %s, 價(jià)格(多個(gè)價(jià)格以團(tuán)購(gòu)為準(zhǔn)) %s. '%(result,title,price)) else: raise TypeError('請(qǐng)檢查輸入是否為目標(biāo)網(wǎng)站的商品詳細(xì)頁面鏈接') # 文件名 replace_string = ['.',' ',r'/',r'\\'] for rs in replace_string: url[1] = url[1].replace(rs,'_') path = os.path.join(os.path.join(basePath, 'data'), url[1]+'.csv') today = get_date() # 日期 return (today, title, price),path def addData(row, path): """數(shù)據(jù)寫入文件""" with open(path,'a+',encoding='utf8') as f: fieldnames = ['時(shí)間', '標(biāo)題','價(jià)格'] writer = csv.DictWriter(f, fieldnames=fieldnames) if f.tell() == 0: # 如果內(nèi)容為空則添加標(biāo)題 writer.writeheader() writer.writerow({'時(shí)間': row[0], '標(biāo)題': row[1],'價(jià)格':row[2]}) def main(): """運(yùn)行程序""" urls = get_url() for url in urls: try: row,path = go(url) # 獲取返回信息 addData(row,path) # 寫入文件 except BaseException as e: print('請(qǐng)求問題?報(bào)錯(cuò):%s'%e) if __name__ == '__main__': print('時(shí)間',get_date()) main() # scheduler = BlockingScheduler() # scheduler.add_job(go,'cron', args=[url],hour='8-23', minute= '5,35' , second='15') # # scheduler.add_job(main,'cron', args=[3088512],hour='8-23', minute= 5 , second='15') # print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) # try: # scheduler.start() # except (KeyboardInterrupt, SystemExit): # pass
draw.py
圖像文件生成在 pic 文件中。
# encoding: utf8 from pyecharts import options as opts from pyecharts.charts import Page, Line import os import csv basePath = os.path.dirname(os.path.abspath(__file__)) # 當(dāng)前文件夾 def line(title,checktime,price) -> Line: """繪圖函數(shù)""" c = ( Line() .add_xaxis(checktime) .add_yaxis(title, price, is_smooth=True) .set_global_opts(title_opts=opts.TitleOpts(title="商品價(jià)格"), yaxis_opts=opts.AxisOpts(name="元/臺(tái)"), xaxis_opts=opts.AxisOpts(name=title, axislabel_opts=opts.LabelOpts(formatter="{value}", font_size=12, rotate=30,) # x,y 軸標(biāo)簽 ) ) ) return c def files(): """ 輸出字典,每一個(gè)鍵值代表一張圖表 """ global basePath files = {} with open(os.path.join(basePath,'goods.csv'),'r',encoding='utf8') as f: f_csv = csv.reader(f) next(f_csv) # 標(biāo)題 for row in f_csv: # 內(nèi)容 if row: replace_string = ['.',' ',r'/',r'\\'] # 特殊字符處理 for rs in replace_string: row[1] = row[1].replace(rs,'_') files.setdefault(row[0],[]).append(row[1]) return files def draw(files): """繪制圖形文件""" datapath = os.path.join(basePath,'data') picpath = os.path.join(basePath,'pic') for k,i in files.items(): page = Page() for n in i: try: with open(os.path.join(datapath, n +'.csv'),'r', encoding='utf8') as f: f_csv = csv.DictReader(f) price,checktime = [],[] for row in f_csv: checktime.append(row['時(shí)間']) price.append(row['價(jià)格']) title = n page.add(line(title,checktime,price)) # 24 發(fā)帖回帖變化圖、近3月變化圖、瀏覽、回復(fù)散點(diǎn)圖 except: print('未制圖:',n) page.render(os.path.join(picpath, k +'.html')) if __name__ == '__main__': draw(files())
關(guān)于Python實(shí)現(xiàn)商品價(jià)格監(jiān)控的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。