分析了京東內衣銷售記錄,告訴你妹子們的真Size!

今天閒暇之餘寫了一個爬蟲例子。經過爬蟲去爬取京東的用戶評價,經過分析爬取的數據能獲得不少結果,好比,哪種顏色的胸罩最受女性歡迎,以及中國女性的平均size(僅供參考哦~)html

打開開發者工具-network,在用戶評價頁面咱們發現瀏覽器有這樣一個請求python

圖片描述

經過分析咱們發現主要用的參數有三個productId,page,pageSize。後兩個爲分頁參數,productId是每一個商品的id,經過這個id去獲取商品的評價記錄,因此咱們只須要知道每一個商品的productId就垂手可得的獲取評價了。再來分析搜索頁面的網頁源代碼mongodb

圖片描述

經過分析咱們發現每一個商品都在li標籤中,而li標籤又有一個data-pid屬性,這個對應的值就是商品的productId了。數據庫

大概瞭解了整個流程,就能夠開始咱們的爬蟲工做了。json


首先咱們須要在搜索頁面獲取商品的id,爲下面爬取用戶評價提供productId。key_word爲搜索的關鍵字,這裏就是【胸罩】瀏覽器

import requests
import re

""" 查詢商品id """
def find_product_id(key_word):
    jd_url = 'https://search.jd.com/Search'
    product_ids = []
    # 爬前3頁的商品
    for i in range(1,4):
        param = {'keyword': key_word, 'enc': 'utf-8', 'page': i}
        response = requests.get(jd_url, params=param)
        # 商品id
        ids = re.findall('data-pid="(.*?)"', response.text, re.S)
        product_ids += ids
    return product_ids
複製代碼

將前三頁的商品id放入列表中,接下來咱們就能夠爬取評價了app

咱們經過分析preview發現獲取用戶評價這個請求響應的格式是一個字符串後面拼接了一個json(以下圖),因此咱們只要將無用的字符刪除掉,就能夠獲取到咱們想要的json對象了。ide

而在json對象中的comments的內容就是咱們最終想要的評價記錄工具

圖片描述

""" 獲取評論內容 """
def get_comment_message(product_id):
    urls = ['https://sclub.jd.com/comment/productPageComments.action?' \
            'callback=fetchJSON_comment98vv53282&' \
            'productId={}' \
            '&score=0&sortType=5&' \
            'page={}' \
            '&pageSize=10&isShadowSku=0&rid=0&fold=1'.format(product_id, page) for page in range(1, 11)]
    for url in urls:
        response = requests.get(url)
        html = response.text
        # 刪除無用字符
        html = html.replace('fetchJSON_comment98vv53282(', '').replace(');', '')
        data = json.loads(html)
        comments = data['comments']
        t = threading.Thread(target=save_mongo, args=(comments,))
        t.start()
複製代碼

在這個方法中只獲取了前10頁的評價的url,放到urls這個列表中。經過循環獲取不一樣頁面的評價記錄,這時啓動了一個線程用來將留言數據存到到MongoDB中。fetch

咱們繼續分析評價記錄這個接口發現咱們想要的兩條數據

  • productColor:產品顏色

  • productSize:產品尺寸

    圖片描述

# mongo服務
client = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
# jd數據庫
db = client.jd
# product表,沒有自動建立
product_db = db.product

# 保存mongo
def save_mongo(comments):
    for comment in comments:
        product_data = {}
        # 顏色
        # flush_data清洗數據的方法
        product_data['product_color'] = flush_data(comment['productColor'])
        # size
        product_data['product_size'] = flush_data(comment['productSize'])
        # 評論內容
        product_data['comment_content'] = comment['content']
        # create_time
        product_data['create_time'] = comment['creationTime']
        # 插入mongo
        product_db.insert(product_data)

複製代碼

由於每種商品的顏色、尺寸描述上有差別,爲了方面統計,咱們進行了簡單的數據清洗。這段代碼很是的不Pythonic。不過只是一個小demo,你們無視便可。

def flush_data(data):
    if '膚' in data:
        return '膚色'
    if '黑' in data:
        return '黑色'
    if '紫' in data:
        return '紫色'
    if '粉' in data:
        return '粉色'
    if '藍' in data:
        return '藍色'
    if '白' in data:
        return '白色'
    if '灰' in data:
        return '灰色'
    if '檳' in data:
        return '香檳色'
    if '琥' in data:
        return '琥珀色'
    if '紅' in data:
        return '紅色'
    if '紫' in data:
        return '紫色'
    if 'A' in data:
        return 'A'
    if 'B' in data:
        return 'B'
    if 'C' in data:
        return 'C'
    if 'D' in data:
        return 'D'
複製代碼

這幾個模塊的功能編寫完畢,下面只須要將他們聯繫起來

# 建立一個線程鎖
lock = threading.Lock()

# 獲取評論線程
def spider_jd(ids):
    while ids:
        # 加鎖
        lock.acquire()
        # 取出第一個元素
        id = ids[0]
        # 將取出的元素從列表中刪除,避免重複加載
        del ids[0]
        # 釋放鎖
        lock.release()
        # 獲取評論內容
        get_comment_message(id)


product_ids = find_product_id('胸罩')
for i in (1, 5):
    # 增長一個獲取評論的線程
    t = threading.Thread(target=spider_jd, args=(product_ids,))
    # 啓動線程
    t.start()
複製代碼

上面代碼加鎖的緣由是爲了防止重複消費共享變量

運行以後的查看MongoDB:

圖片描述

獲得結果以後,爲了能更直觀的表現數據,咱們能夠用matplotlib庫進行圖表化展現

import pymongo
from pylab import *


client = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
# jd數據庫
db = client.jd
# product表,沒有自動建立
product_db = db.product
# 統計如下幾個顏色
color_arr = ['膚色', '黑色', '紫色', '粉色', '藍色', '白色', '灰色', '香檳色', '紅色']

color_num_arr = []
for i in color_arr:
    num = product_db.count({'product_color': i})
    color_num_arr.append(num)

# 顯示的顏色
color_arr = ['bisque', 'black', 'purple', 'pink', 'blue', 'white', 'gray', 'peru', 'red']

#labeldistance,文本的位置離遠點有多遠,1.1指1.1倍半徑的位置
#autopct,圓裏面的文本格式,%3.1f%%表示小數有三位,整數有一位的浮點數
#shadow,餅是否有陰影
#startangle,起始角度,0,表示從0開始逆時針轉,爲第一塊。通常選擇從90度開始比較好看
#pctdistance,百分比的text離圓心的距離
#patches, l_texts, p_texts,爲了獲得餅圖的返回值,p_texts餅圖內部文本的,l_texts餅圖外label的文本
patches,l_text,p_text = plt.pie(sizes, labels=labels, colors=colors,
                                labeldistance=1.1, autopct='%3.1f%%', shadow=False,
                                startangle=90, pctdistance=0.6)
#改變文本的大小
#方法是把每個text遍歷。調用set_size方法設置它的屬性
for t in l_text:
    t.set_size=(30)
for t in p_text:
    t.set_size=(20)
# 設置x,y軸刻度一致,這樣餅圖才能是圓的
plt.axis('equal')
plt.title("內衣顏色比例圖", fontproperties="SimHei") #
plt.legend()
plt.show()
複製代碼

運行代碼,咱們發現膚色的最受歡迎 其次是黑色 (鋼鐵直男表示不知道是否是真的...)

圖片描述

接下來咱們再來統計一下size 的分佈圖,這裏用柱狀圖進行顯示

index=["A","B","C","D"]

client = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
db = client.jd
product_db = db.product

value = []
for i in index:
    num = product_db.count({'product_size': i})
    value.append(num)

plt.bar(left=index, height=value, color="green", width=0.5)

plt.show()

複製代碼

運行後咱們發現 B size的女性更多一些

圖片描述


最後,歡迎你們關注個人公衆號(python3xxx)。天天都會推送不同的Python乾貨。

圖片描述
相關文章
相關標籤/搜索