前言
相信提及「淘寶」 ,你們都不會感到陌生吧。做爲中國最大的電商平臺,淘寶彷彿已經與咱們的生活緊密相連。正好以前在CSDN上看到@不正經的kimol君 寫了一篇利用《python爬取並分析淘寶商品信息》的文章,因而仔細拜讀了一下,感受貼近生活,且十分實用,故寫下這篇文章,記錄一下。html
一、模擬登錄
興致勃勃的我,衝進淘寶就準備一頓亂搜:
在搜索欄裏填好關鍵詞:「顯卡」,小手輕快敲擊着回車鍵(小樣~看個人)python
心情愉悅的我等待着返回滿滿的商品信息,結果苦苦的等待換了的倒是302,因而我意外地來到了登錄界面。
狀況基本就是這麼個狀況了…web
而後我查了一下,隨着淘寶反爬手段的不斷增強,不少小夥伴應該已經發現,淘寶搜索功能是須要用戶登錄的!canvas
關於淘寶模擬登錄,已經有大佬已經利用requests成功模擬登錄(你們能夠去CSDN上看@豬哥66的《Python模擬登陸淘寶》)瀏覽器
這個方法得先分析淘寶登錄的各類請求,並模擬生成相應的參數,相對來講有必定的難度。
因而我決定換一種思路,經過 selenium+二維碼 的方式:cookie
# 打開圖片 def Openimg(img_location): img=Image.open(img_location) img.show() # 登錄獲取cookies def Login(): driver = webdriver.PhantomJS() driver.get('https://login.taobao.com/member/login.jhtml') try: #driver.find_element_by_id("J_Static2Quick").click() #切換成二維碼模式 driver.find_element_by_xpath('//*[@id="login"]/div[1]/i').click() except: pass time.sleep(3) #code_element = driver.find_element_by_xpath('//*[@id="J_QRCodeImg"]/img') #code_url = code_element.get_attribute('src') # 執行JS得到canvas的二維碼 JS = 'return document.getElementsByTagName("canvas")[0].toDataURL("image/png");' im_info = driver.execute_script(JS) # 執行JS獲取圖片信息 im_base64 = im_info.split(',')[1] #拿到base64編碼的圖片信息 im_bytes = base64.b64decode(im_base64) #轉爲bytes類型 time.sleep(2) with open('./login.png','wb') as f: f.write(im_bytes) f.close() t = threading.Thread(target=Openimg,args=('./login.png',)) t.start() print("Logining...Please sweep the code!\n") while(True): c = driver.get_cookies() if len(c) > 20: #登錄成功獲取到cookies cookies = { } for i in range(len(c)): cookies[c[i]['name']] = c[i]['value'] driver.close() print("Login in successfully!\n") return cookies time.sleep(1)
經過webdriver打開淘寶登錄界面,把二維碼下載到本地並打開等待用戶掃碼(相應的元素你們經過瀏覽器的F12元素分析很容易就能找出)。待掃碼成功後,將webdriver裏的cookies轉爲DICT形式,並返回。(這裏是爲了後續requests爬取信息的時候使用)app
二、爬取商品信息
當我拿到cookies以後,便能對商品信息進行爬取了。svg
2.1 定義相關參數
定義相應的請求地址,請求頭等等,用於模擬瀏覽器進行訪問:ui
# 定義參數 headers = { 'Host':'s.taobao.com', 'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Accept-Encoding':'gzip, deflate, br', 'Connection':'keep-alive'} list_url = 'http://s.taobao.com/search?q=%(key)s&ie=utf8&s=%(page)d'
2.2 分析並定義正則
當請求獲得HTML頁面後,想要獲得咱們想要的數據就必須得對其進行提取,這裏我選擇了正則的方式。經過查看頁面源碼:
偷懶的我上面只標誌了兩個數據,不過其餘也是相似的,因而獲得如下正則:編碼
# 正則模式 p_title = '"raw_title":"(.*?)"' #標題 p_location = '"item_loc":"(.*?)"' #銷售地 p_sale = '"view_sales":"(.*?)人付款"' #銷售量 p_comment = '"comment_count":"(.*?)"'#評論數 p_price = '"view_price":"(.*?)"' #銷售價格 p_nid = '"nid":"(.*?)"' #商品惟一ID p_img = '"pic_url":"(.*?)"' #圖片URL
聰明的小夥伴應該確定已經發現了,其實商品信息是被保存在了g_page_config變量裏面,因此咱們也能夠先提取這個變量(一個字典),而後再讀取數據,也可!
2.3 數據爬取
完事具有,只欠東風。因而,東風來了:
# 數據爬取 key = input('請輸入關鍵字:') # 商品的關鍵詞 N = 20 # 爬取的頁數 data = [] cookies = Login() for i in range(N): try: page = i*44 url = list_url%{ 'key':key,'page':page} res = requests.get(url,headers=headers,cookies=cookies) html = res.text title = re.findall(p_title,html) location = re.findall(p_location,html) sale = re.findall(p_sale,html) comment = re.findall(p_comment,html) price = re.findall(p_price,html) nid = re.findall(p_nid,html) img = re.findall(p_img,html) for j in range(len(title)): data.append([title[j],location[j],sale[j],comment[j],price[j],nid[j],img[j]]) print('-------Page%s complete!--------\n\n'%(i+1)) time.sleep(3) except: pass data = pd.DataFrame(data,columns=['title','location','sale','comment','price','nid','img']) data.to_csv('%s.csv'%key,encoding='utf-8',index=False)
上面代碼爬取20頁商品信息,並將其保存在本地的csv文件中,效果是這樣的:
三、簡單數據分析
如今數據有了,放着豈不浪費,我但是社會主義好青年,怎麼能作這種事?那麼,就讓咱們來簡單看看這些數據:(固然,數據量小,僅供娛樂參考)
3.1 導入庫
import jieba import operator import pandas as pd from wordcloud import WordCloud from matplotlib import pyplot as plt
以上相應庫的安裝,基本都能經過pip解決,這裏就不介紹了
3.2 中文顯示
# matplotlib中文顯示 plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = ['SimHei']
不設置可能出現中文亂碼等鬧心的狀況哦~
3.3 讀取數據
這一步咱們讀取以前咱們收集的顯卡.csv文件
# 讀取數據 key = '顯卡' data = pd.read_csv('%s.csv'%key,encoding='utf-8',engine='python')
3.4 分析價格分佈
# 價格分佈 plt.figure(figsize=(16,9)) plt.hist(data['price'],bins=20,alpha=0.6) plt.title('價格頻率分佈直方圖') plt.xlabel('價格') plt.ylabel('頻數') plt.savefig('價格分佈.png')
價格頻率分佈直方圖:
3.5 分析銷售地分佈
# 銷售地分佈 group_data = list(data.groupby('location')) loc_num = { } for i in range(len(group_data)): loc_num[group_data[i][0]] = len(group_data[i][1]) plt.figure(figsize=(19,9)) plt.title('銷售地') plt.scatter(list(loc_num.keys())[:20],list(loc_num.values())[:20],color='r') plt.plot(list(loc_num.keys())[:20],list(loc_num.values())[:20]) plt.savefig('銷售地.png') sorted_loc_num = sorted(loc_num.items(), key=operator.itemgetter(1),reverse=True)#排序 loc_num_10 = sorted_loc_num[:10] #取前10 loc_10 = [] num_10 = [] for i in range(10): loc_10.append(loc_num_10[i][0]) num_10.append(loc_num_10[i][1]) plt.figure(figsize=(16,9)) plt.title('銷售地TOP10') plt.bar(loc_10,num_10,facecolor = 'lightskyblue',edgecolor = 'white') plt.savefig('銷售地TOP10.png')
銷售地分佈:
銷售地TOP10:
3.6 詞雲分析
有了以前的 顯卡.csv 數據,咱們也能夠對商品標題 title作一個詞頻展現:
# 製做詞雲 content = '' for i in range(len(data)): content += data['title'][i] wl = jieba.cut(content,cut_all=True) wl_space_split = ' '.join(wl) wc = WordCloud('simhei.ttf', background_color='white', # 背景顏色 width=1000, height=600,).generate(wl_space_split) wc.to_file('%s.png'%key)
下面展現的是淘寶商品」顯卡「的詞雲:
最後感謝各位大大的耐心閱讀~
小結
本篇內容主要爲你們介紹了下經過python去爬取並分析淘寶商品數據的步驟,並穿插一些細節的講解,但因爲篇幅問題,更多細化的知識點並無詳細展開介紹。須要完整項目源碼的同窗,能夠關注下方公衆號,回覆「python淘寶爬蟲」便可獲取。
本文同步分享在 博客「Alice菌」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。