悄悄告訴你七夕禮物清單,最適合你女/男神的禮物!!趕忙收藏!

前言

中國情人節——七夕節(別稱:乞巧節、七巧節、七姐誕、道德臘,英文名:Double Seventh Festival)被賦予了「牛郎織女」的美麗愛情傳說,使其成爲了象徵愛情的節日,從而被認爲是中國最具浪漫色彩的傳統節日,日期是每一年農曆七月初七,有拜月祈福、拜織女、吃巧果、乞求姻緣等習俗。html

隨着七夕的臨近,不少小夥伴都開始籌備送女友/男友的禮物了,禮物做爲一種傳達情感的媒介,表達了對於女友/男友的祝福和心意,但同時對於要送什麼禮物,對於不少小夥伴來說卻是選擇困難,本文利用 Python 爬取某寶商品頁面,爲小夥伴們分析銷量較高的禮物清單,以供你們參考。瀏覽器

程序說明

根據不一樣關鍵字,爬取「某寶」獲取商品信息(以「七夕禮物」「七夕禮物送男朋友」「七夕禮物送女朋友」等爲例),根據所獲取數據分析獲得七夕禮物清單,並經過詞雲可視化的方式展現不一樣禮物的頻率比重對比。markdown

數據爬取

🕸️ 網址構成分析

爬蟲少不了網址,所以首先觀察網址的構成,在輸入關鍵字「七夕禮物」進行搜索時,發現網址中 q 的參數值即爲所鍵入的關鍵字「七夕禮物」,以下圖所示:cookie

​​所以可使用如下方式構造網址:網絡

q_value = "七夕禮物"
url = "https://s.taobao.com/search?q={}imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210802&ie=utf8&bcoffset=5&p4ppushleft=2%2C48&ntoffset=5&s=44".format(q_value) 
複製代碼

雖然也能夠直接複製網址,可是這種方法的弊端在於,每次想要爬取其餘類別的商品時,都須要從新打開網頁複製網址;而利用 q_value 變量構造網址,當須要獲取其餘品類商品時僅須要修改 q_value 變量,例如要爬取關鍵字「七夕禮物送男朋友」,只須要作以下修改:app

q_value = "七夕禮物送男朋友" 
複製代碼

🕸️ 網頁結構分析

使用瀏覽器「開發者工具」,觀察網頁結構,能夠看出商品的信息都是在 <script> 中,工具

​​

所以,首先使用 requests 庫請求網頁內容,須要注意的是,在請求頁面信息時,須要構造請求頭中的 cookie 和 user-agent 信息,不然並不會獲得有效響應,獲取 cookie 和 user-agent 信息須要在瀏覽器「開發者工具」中的網絡標籤下單擊當前請求頁面(若是網絡標籤下沒有當前請求的頁面,須要刷新後才能夠顯示),在標頭選項卡中找到請求標頭的 cookie 和 user-agent 值並複製,按照如下方式構造請求頭:oop

headers = {
	# 將user-agent值,替換爲剛剛複製的user-agent值
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62",
    # 將cookie值,替換爲剛剛複製的cookie值
    "cookie":"...JSESSIONID=4990DB1E8783DF90266F5159209F8E3A"
} 
複製代碼

下圖顯示了獲取 cookie 值的示例(獲取 user-agent 值的方式相似,只需在標頭選項卡中找到學習

請求標頭user-agent 值):字體

​​

獲得響應網頁後,須要使用 BeautifulSoup4 與正則表達庫 re 解析網頁,獲取商品信息:

import re
import  requests
from bs4 import BeautifulSoup

# 請求網頁
response = requests.get(url,headers =headers)
response.raise_for_status()
response.encoding = 'utf-8'
# 解析網頁
soup = BeautifulSoup(response.text, 'html.parser')
results = soup.find_all('script')
information = str(results[7])

# 獲取商品標題
raw_title = re.findall(r'"raw_title":"(.*?)"', information)
# 獲取商品價格
view_price = re.findall(r'"view_price":"(.*?)"', information)
# 獲取購買人數
view_sales = re.findall(r'"view_sales":"(.*?)"', information)
# 獲取發貨地址
item_loc = re.findall(r'"item_loc":"(.*?)"', information)
# 獲取店鋪名
nick = re.findall(r'"nick":"(.*?)"', information)
# 獲取詳情頁地址
detail_url = re.findall(r'"detail_url":"(.*?)"', information)
# 獲取封面圖片地址
pic_url = re.findall(r'"pic_url":"(.*?)"', information) 
複製代碼

須要注意的是,因爲一開始使用 utf-8 方式解碼網頁,並不能解碼 Unicode,所以打印詳情頁地址和封面圖片地址會看到解碼不正確的狀況:

print(detail_url[4])
# //detail.tmall.com/item.htm?id\u003d628777347316\u0026ns\u003d1\u0026abbucket\u003d17 
複製代碼

所以須要使用如下方式進行正確解碼:

decodeunichars = detail_url[4].encode('utf-8').decode('unicode-escape')
print(decodeunichars)
# //detail.tmall.com/item.htm?id=628777347316&ns=1&abbucket=17 
複製代碼

🕸️ 將數據寫入csv文件中

爲了將數據寫入 csv 文件中,首先建立 csv 文件並寫入標頭:

#建立存儲csv文件存儲數據
file = open('gift.csv', "w", encoding="utf-8-sig",newline='')
csv_head = csv.writer(file)
#表頭
header = ['raw_title','view_price','view_sales','salary','item_loc','nick','detail_url','pic_url']
csv_head.writerow(header)
file.close() 
複製代碼

而後,因爲英文逗號(",")表示單元格的切換,所以須要將獲取的數據通過預處理:

def precess(item):
    return item.replace(',', ' ') 
複製代碼

最後將預處理數據後,將數據寫入 csv 文件中:

for i in range(len(raw_title)):
    with open('gift.csv', 'a+', encoding='utf-8-sig') as f:
        f.write(precess(raw_title[i]) + ',' 
                + precess(view_price[i]) + ',' 
                + precess(view_sales[i]) + ','  
                + precess(item_loc[i]) +',' 
                + precess(nick[i]) + ','
                + precess(detail_url[i]) + ','
                + precess(pic_url[i]) + '\n') 
複製代碼

🕸️ 經過觀察頁面連接,爬取更多頁面

經過查看第2頁以及第3頁,網址:

https://s.taobao.com/search?q=七夕禮物imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=1&ntoffset=1&p4ppushleft=2%2C48&s=44
https://s.taobao.com/search?q=七夕禮物&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=1&ntoffset=1&p4ppushleft=2%2C48&s=88 
複製代碼

能夠看到,網址的不一樣僅在於第二頁的 s 的參數值爲 44,而第三頁 s 的參數值爲 88,結合能夠每頁有 44 個商品,所以可使用如下方式構造爬取20頁商品:

url_pattern = "https://s.taobao.com/search?q={}&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=1&ntoffset=1&p4ppushleft=2%2C48&s={}"
for i in range(20):
    url = url_pattern.format(q, i*44) 
複製代碼

🕸️ 爬蟲程序完整代碼

import re
import  requests
import time
from bs4 import BeautifulSoup
import csv
import os

q = "七夕禮物"
url_pattern = "https://s.taobao.com/search?q={}&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=2&ntoffset=2&p4ppushleft=2%2C48&s={}"

headers = {
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62",
    # cookie值替換爲使用上述方式獲取的cookie值
    "cookie":"..."
}
    
def analysis(item,results):
    pattern = re.compile(item, re.I|re.M)
    result_list = pattern.findall(results)
    return result_list

def analysis_url(item, results):
    pattern = re.compile(item, re.I|re.M)
    result_list = pattern.findall(results)
    for i in range(len(result_list)):
        result_list[i] = result_list[i].encode('utf-8').decode('unicode-escape')
    return result_list


def precess(item):
    return item.replace(',', ' ')

# 建立csv文件
if not os.path.exists("gift.csv"):
    file = open('gift.csv', "w", encoding="utf-8-sig",newline='')
    csv_head = csv.writer(file)
    #表頭
    header = ['raw_title','view_price','view_sales','salary','item_loc','nick','detail_url','pic_url']
    csv_head.writerow(header)
    file.close()

for i in range(100):
    #增長時延防止反爬蟲
    time.sleep(25)
    url = url_pattern.format(q, i*44)
    response = requests.get(url=url, headers=headers)
    
    #聲明網頁編碼方式,須要根據具體網頁響應狀況
    response.encoding = 'utf-8'
    response.raise_for_status()
    soup = BeautifulSoup(response.text, 'html.parser')

    results = soup.find_all('script')
    information = str(results[7])

    # 獲取全部的商品信息,因爲有些購買人數爲空白,致使返回空值,所以添加異常處理
    all_goods = analysis(r'"raw_title":"(.*?)"shopLink"', information)
    for good in all_goods:
        
        # 獲取商品標題
        raw_title = analysis(r'(.*?)","pic_url"', good)
        if not raw_title:
            raw_title.append('未命名')
        # 獲取商品價格
        view_price = analysis(r'"view_price":"(.*?)"', good)
        if not view_price:
            view_price.append('0.00')
        # 獲取購買人數,因爲有些購買人數爲空白,致使返回空值,所以添加異常處理
        view_sales = analysis(r'"view_sales":"(.*?)"', good)
        #print(view_sales)
        if not view_sales:
            view_sales.append('0人付款')
        # 獲取發貨地址
        item_loc = analysis(r'"item_loc":"(.*?)"', good)
        if not item_loc:
            item_loc.append('未知地址')
        # 獲取店鋪名
        nick = analysis(r'"nick":"(.*?)"', good)
        if not nick:
            nick.append('未知店鋪')
        # 獲取詳情頁地址
        detail_url = analysis_url(r'"detail_url":"(.*?)"', good)
        if not detail_url:
            detail_url.append('無詳情頁')
        # 獲取封面圖片地址
        pic_url = analysis_url(r'"pic_url":"(.*?)"', good)
        if not pic_url:
            pic_url.append('無封面')
        with open('gift.csv', 'a+', encoding='utf-8-sig') as f:
            f.write(precess(raw_title[0]) + ',' 
                    + precess(view_price[0]) + ',' 
                    + precess(view_sales[0]) + ',' 
                    + precess(item_loc[0]) +',' 
                    + precess(nick[0]) + ','
                    + precess(detail_url[0]) + ','
                    + precess(pic_url[0]) + '\n') 
複製代碼

🕸️ 爬取數據結果

​​

數據分析及可視化

可能不少朋友(並不是)是爲了學習技術才點擊進來的,完(shun)全(bian)是求知若渴的想知道要送男友/女友什麼禮物,彆着急,你們最關注的部分來了。
接下來使用詞雲可視化分析,分別考慮包含銷量與不包含銷量兩種狀況。

🎁 七夕禮物清單

不考慮銷量時:

from os import path
from PIL import Image
import matplotlib.pyplot as plt
import jieba
from wordcloud import WordCloud, STOPWORDS
import pandas as pd
import matplotlib.ticker as ticker
import numpy as np
import math
import re

df = pd.read_csv('gift.csv', encoding='utf-8-sig',usecols=['raw_title','view_price','view_sales','salary','item_loc','nick','detail_url','pic_url'])

raw_title_list = df['raw_title'].values
raw_title = ','.join(raw_title_list)
with open('text.txt','a+') as f:
    f.writelines(raw_title)

###當前文件路徑
d = path.dirname(__file__)

# Read the whole text.
file = open(path.join(d, 'text.txt')).read()
##進行分詞
#停用詞,去除修飾性的詞
stopwords = ["七夕","七夕情人節","情人節","男朋友","女朋友","男生","女生","女友","男友","禮物","生日禮物","創意","實用","朋友","男士","老婆","老公","直營","閨蜜","結婚","送給"]
text_split = jieba.cut(file)  # 未去掉停用詞的分詞結果   list類型

#去掉停用詞的分詞結果  list類型
text_split_no = []
for word in text_split:
    if word not in stopwords:
        text_split_no.append(word)
#print(text_split_no)

text =' '.join(text_split_no)
#背景圖片
picture_mask = np.array(Image.open(path.join(d, "beijing.jpg")))
stopwords = set(STOPWORDS)
stopwords.add("said")
wc = WordCloud(  
    #設置字體,指定字體路徑
    font_path=r'C:\Windows\Fonts\simsun.ttc',
    background_color="white",   
    max_words=4000,   
    mask=picture_mask,  
    stopwords=stopwords)  
# 生成詞雲
wc.generate(text)

# 存儲圖片
wc.to_file(path.join(d, "result.jpg")) 
複製代碼

​​

接下來考慮銷量:

def get_sales(item):
    tmp = item[:-3]
    if '萬' in tmp:
        tmp = tmp.replace('萬','0000').replace('.','')
    if '+' in tmp:
        tmp = tmp.replace('+','')
    tmp = int(tmp)
    tmp = tmp / 100.0
    if tmp <= 0:
        tmp = 0
    tmp = round(tmp)
    return tmp
    
raw_title_list = df['raw_title'].values
view_sales_list = df['view_sales'].values
for i in range(len(raw_title_list)):
    for j in range(get_sales(view_sales_list[i])):
        with open('text.txt','a+') as f:
            f.writelines(raw_title_list[i]+',')
# 其他代碼再也不贅述
"""
...
""" 
複製代碼

​​

能夠看到差異仍是較爲明顯的,最後將分詞結果,進行排序,手動去除無效詞後,歸類整理出排名前15的禮物清單:

gift = {}
for i in text_split_no:
	if gift.get(i,0):
		gift[i] += 1
	else:
		gift[i] = 1
sorted_gift = sorted(gift.items(), key=lambda x:x[1],reverse=True) 
複製代碼

❤️禮物清單❤️

玩偶/公仔/毛絨玩具/抱抱熊
糖果
項鍊
巧克力
相冊/記念冊
零食/小吃
手鍊/手鐲/鐲子
玫瑰
吊墜
小夜燈
音樂盒/八音盒
戒指/對戒
口紅
手繩/紅繩
耳釘 
複製代碼

👧 送女友禮物清單

以一樣的方法,將關鍵字改成「女朋友+禮物」,能夠獲得❤️送女友禮物清單❤️:

小夜燈
相冊/記念冊/相框
刻字類禮物
八音盒
項鍊/手鍊/手鐲/鐲子
口紅
手錶
包
水晶鞋
玩偶 
複製代碼

👦 送男友禮物清單

最後,將關鍵字改成「男朋友+禮物」,能夠獲得❤️送男友禮物清單❤️:

可樂刻字
相冊/記念冊/相框
花束
手辦
擺件
鑰匙扣
木刻畫
情書
刺繡
籃球 
複製代碼

能夠看出,送女友和男友的禮物仍是有一些差異的。 固然,和主觀感受上有很些差別的緣由可能在於,不少商品的標題太過創意,徹底不包含商品。  

結尾

固然,本文僅作分析之用,結果也僅供參考,若是清單裏沒有令你心儀的禮物,也能夠選擇紅包或者清空購物車的方式。不管送女友/男友什麼禮物,傳達本身的❤️心意❤️最重要了。

文章的項目代碼,往期的文章可免費領取,私信小編:06便可。

記得點點關注哦!!!愛你別走!!!

相關文章
相關標籤/搜索