用python買手機
最近某同學一直碎碎念要買P20,我想說此時買似不太明智,但不知從何說起,恰逢放假,閑來無事,遂用python爬取淘寶、京東手機銷售資料做個簡單分析,本部落客要實作了以下功能
- 爬取淘寶上手機的月銷售資料并存為excel表格
- 統計淘寶上不同品牌手機的月銷量并以條形圖形式展示
- 使用python代碼打開浏覽器搜尋京東上手機資料并爬取
- 統計京東上不同手機品牌的評價量并以條形圖形式展示
爬取淘寶資料
-
URL
電腦浏覽器打開淘寶,搜尋手機,得到浏覽器位址欄連結為https://s.taobao.com/search?ie=utf8&initiative_id=staobaoz_20170905&stats_click=search_radio_all%3A1&js=1&imgfile=&q=%E6%89%8B%E6%9C%BA&suggest=0_1&_input_charset=utf-8&wq=u&suggest_query=u&source=suggest&p4ppushleft=5%2C48&s=48
經過測試,發現q=之後為關鍵詞手機,s=之後為頁數乘以48,48為每頁顯示的商品數量。是以寫得URL函數如下:
def key_name( number ):
#擷取頁面的内容并傳回
name = '手機'
URL_1 = "https://s.taobao.com/search?ie=utf8&initiative_id=staobaoz_20170905&stats_click=search_radio_all%3A1&js=1&imgfile=&q="
URL_2 = "&suggest=0_1&_input_charset=utf-8&wq=u&suggest_query=u&source=suggest&p4ppushleft=5%2C48&s="
URL = ( URL_1 + name + URL_2 + str(number))
#print(URL)
res = requests.get( URL )
return res.text
-
擷取資料塊
檢視淘寶搜尋手機後所在頁面源代碼如圖
可以看到,我所需要的手機價格與月銷量等資料在data:之後,header之前,是以使用正規表達式來擷取資料塊,擷取資料塊代碼如下:用python買手機用python買手機
def find_date( text):
#根據整個頁面的資訊,擷取商品的資料所在的HTML源碼并放回
reg = r',"data":{"spus":\[({.+?)\]}},"header":'
reg = re.compile(reg)
info = re.findall(reg, text)
return info[0]
-
解析資料
擷取到資料塊之後,需要從資料塊中解析需要的手機品牌、配置、價格、月銷量等資料。需要注意的是,代碼擷取的價格和月銷量為字元串形式,需要強制轉換為int型再寫入excel表格。
對于計算不同品牌手機的月銷量問題,采用字元串查找方式,比如華為手機,在手機商品的标題中查找‘華為’、‘榮耀’關鍵詞,如查找到,則該手機則認為是華為手機,月銷量加在華為手機上。
代碼如下:
def manipulation_data( info, sales_count, sheet ):
#解析擷取的HTML源碼,擷取資料
Date = eval(info)
for d in Date:
T = " ".join([t['tag'] for t in d['tag_info']])
#print(d['title'] + '\t' + d['price'] + '\t' + d['importantKey'][0:len(d['importantKey'])-1] + '\t' + T)
#将資料寫入對應的excel表格中
sheet.write(sales_count['line'],0,d['title'])
sheet.write(sales_count['line'],1,int(d['price']))
sheet.write(sales_count['line'],2,int(d['month_sales']))
sheet.write(sales_count['line'],3,T)
#統計不同品牌手機的月銷售量
for key in sales_count.keys():
if str(d['title']).find('榮耀')>=0:
sales_count['華為']=sales_count['華為']+(int(d['month_sales']))
elif str(d['title']).find(str(key))>=0:
sales_count[key]=sales_count[key]+(int(d['month_sales']))
sales_count['line']= sales_count['line'] + 1
return sales_count
-
繪制條形圖
得到不同品牌手機月銷量後,需要對其進行按月銷量進行排序,使用sorted方法,排序完成後再使用dict方法強制轉換為字典形式,我寫了兩個繪制條形圖函數,可根據需要調用,使用包主要是matplotlib和pygal:
def show(sales_count):
#按照手機銷售量進行排序并繪圖(網頁版)
sales_count=dict(sorted(sales_count.items(),key=lambda d:d[1],reverse=True))
print('正在繪制直方圖')
picture=pygal.Bar()
picture.title="各大品牌手機月銷售量直方圖 by社會主義接班人1号"
picture.x_labels=sales_count.keys()
sales_count.keys()
picture.x_title="手機品牌"
picture.y_title="月銷售量"
picture.add('淘寶',sales_count.values())
picture.render_to_file('淘寶手機月銷售量直方圖.svg')
print('繪制完成')
print(sales_count)
def show2(sales_count):
#按照手機銷售量進行排序并繪圖(圖檔版)
sales_count=dict(sorted(sales_count.items(),key=lambda d:d[1],reverse=True))
print('正在繪制直方圖')
x=[0,1,2,3,4,5,6,7,8,9,10]
picture=plt.bar(x,sales_count.values(),width=0.4,tick_label=list(sales_count.keys()),fc='r')
for rect in picture:
h=rect.get_height()
plt.text(rect.get_x()+rect.get_width()-0.6,1.03*h,'%d'% int(h))
plt.xlabel('手機品牌')
plt.ylabel('月銷售量')
plt.title('各大品牌手機月銷售量直方圖 by社會主義接班人1号')
plt.savefig("淘寶手機月銷售量直方圖.jpg")
print('繪制完成')
plt.show()
print(sales_count)
-
主函數
主函數如下:
def main():
#初始化建立字典,key為手機品牌,value為月銷量
sales_count={'華為':0,'小米':0,'蘋果':0,'vivo':0,'OPPO':0,'魅族':0,'紐曼':0,'尼凱恩':0,'諾基亞':0,'三星':0,'聯想':0,'line':1}
book = Workbook()
#建立excel表格
sheet = book.add_sheet('淘寶手機資料')
sheet.write(0,0,'品牌')
sheet.write(0,1,'價格')
sheet.write(0,2,'月銷售量')
sheet.write(0,3,'配置')
book.save('淘寶手機資料.xls')
#k用于生成連結,每個連結的最後面的數字相差48.
#sales_count['line']用于記錄表格的資料行數,便于寫入資料
#end為結束頁數,可通過end控制擷取資料數量
k = 0
end=20
for i in range(end+1):
text = key_name( k + i * 48 )
info = find_date(text)
sales_count= manipulation_data( info ,sales_count, sheet )
book.save('淘寶手機資料.xls')
print('爬取第' + str(i) + '頁資料完成,共'+str(end)+'頁')
del sales_count['line']
#show(sales_count)
show2(sales_count)
- 運作結果
用python買手機用python買手機 用python買手機用python買手機 用python買手機用python買手機
爬取京東資料
京東的情況與淘寶略有不同,京東是搜尋一頁商品後,滑鼠下滑加載下一頁,是以需要用到webdriver模拟浏覽器打開滑鼠下滑操作,并且京東資料塊也與淘寶有所不同。并且京東并沒有月銷量,隻有評價人數。不同代碼如下:
def key_name( driver,number ):
#擷取頁面的内容并傳回
name = '手機'
URL_1 = "https://search.jd.com/Search?keyword="
URL_2 = "&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq="
URL_3="&cid2=653&cid3=655&page="
URL_4 = "&s=1&click=0"
URL = ( URL_1 + name + URL_2 + name + URL_3+ str(number)+URL_4)
#driver = webdriver.Firefox()
#driver.implicitly_wait(3)
driver.get(URL)
# 模拟下滑到底部操作
for i in range(1, 5):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(1)
# 将加載好的頁面源碼給bs4解析
soup = BeautifulSoup(driver.page_source, "html.parser")
t=0
# 進行資訊的抽取(商品名稱,價格)
goods_info = soup.select(".gl-item")
#driver.close()
return goods_info
def manipulation_data( goods_info, sales_count, sheet ):
#解析擷取的HTML源碼,擷取資料并對資料進行解析
for info in goods_info:
title = info.select(".p-name.p-name-type-2 a")[0].text.strip()
price_str = info.select(".p-price")[0].text.strip()
count_str = info.select(".p-commit")[0].text.strip()
#print (title)
price_start=price_str.find('¥')+1
price_end=price_str.find('.')
price=int(price_str[price_start:price_end])
#print (price)
if(count_str.find('\n'))>=0:
count_start=count_str.find('\n')+1
else:
count_start=0
if(count_str.find('萬+'))>=0:
count=float(count_str[count_start:count_str.find('萬')])*10000
elif(count_str.find('+'))>=0:
count=int(count_str[count_start:count_str.find('+')])
#print(count)
sheet.write(sales_count['line'],0,title)
sheet.write(sales_count['line'],1,int(price))
sheet.write(sales_count['line'],2,int(count))
for key in sales_count.keys():
if str(title).find('榮耀')>=0:
sales_count['華為']=sales_count['華為']+(int(count))
elif str(title).find('Apple')>=0:
sales_count['蘋果']=sales_count['蘋果']+(int(count))
elif str(title).find(str(key))>=0:
sales_count[key]=sales_count[key]+(int(count))
sales_count['line']= sales_count['line'] + 1
return sales_count
def main():
sales_count={'華為':0,'小米':0,'蘋果':0,'vivo':0,'OPPO':0,'魅族':0,'紐曼':0,'尼凱恩':0,'諾基亞':0,'三星':0,'聯想':0,'line':1}
book = Workbook()
sheet = book.add_sheet('京東手機資料')
sheet.write(0,0,'手機')
sheet.write(0,1,'價格')
sheet.write(0,2,'評價數量')
book.save('京東手機資料.xls')
driver = webdriver.Firefox()
driver.implicitly_wait(3)
end=30
#sales_count['line']用于記錄表格的資料行數,便于寫入資料
for i in range(end):
goods_info = key_name(driver,i*2)
sales_count= manipulation_data( goods_info ,sales_count, sheet )
book.save('京東手機資料.xls')
print('爬取第' + str(i+1) + '頁資料完成,共'+str(end)+'頁')
del sales_count['line']
#show(sales_count)
show2(sales_count)
- 運作結果
用python買手機用python買手機 用python買手機用python買手機 對比淘寶和京東資料發現,淘寶上華為一馬當先,京東上幾乎是華為、蘋果各占半壁江山,都說華為賺錢,這次我信了。用python買手機用python買手機
本文完
1
- 部分代碼來源網絡,如有侵權,請聯系 ↩︎