1. 程式人生 > >買手機選擇困難症,Python資料分析幫你解決

買手機選擇困難症,Python資料分析幫你解決

每年各大品牌旗艦機發布都是一大熱點,特別是前幾天釋出的iPhone Xs Max算是手機界的大新聞了,新款iPhone的價格也再度重新整理了手機定價的記錄。看完釋出會,相信很多人的心情是這樣的(文末爬蟲資料贈送)

我一朋友魚哥之前用的蘋果機,現在想換個安卓的,但是安卓種類太多,讓他這個選擇困難症的人來說,確實有點犯難,相信也有很多朋友會有選擇困難的問題吧,其實藉助資料分析就能很好的幫你解決問題,幫你解決犯難的問題。

分析思路

思路很簡單,上京東商城把所有手機的資料爬下來,然後根據配置、價格過濾出符合條件的手機,在過濾出來的手機裡選擇一部價效比最高的。畫成流程圖,大致是這樣的

爬蟲資料群519970686

爬取資料

第一步,我們先從京東商城爬取所有在售的手機資料。這裡我們關心的主要是價格和配置資訊,商品頁面上的價格和配置資訊像下面兩張圖所示

我們編寫程式碼爬取所有手機的價格和配置資訊,爬蟲的核心程式碼如下


# 獲取手機單品的價格
def get_price(skuid):
    url = "https://c0.3.cn/stock?skuId=" + str(skuid) + "&area=1_72_4137_0&venderId=1000004123&cat=9987,653,655&buyNum=1&choseSuitSkuIds=&extraParam={%22originid%22:%221%22}&ch=1&fqsp=0&pduid=15379228074621272760279&pdpin=&detailedAdd=null&callback=jQuery3285040"
    r = requests.get(url, verify=False)
    content = r.content.decode('GBK')
    matched = re.search(r'jQuery\d+\((.*)\)', content, re.M)
    if matched:
        data = json.loads(matched.group(1))
        price = float(data["stock"]["jdPrice"]["p"])
        return price
    return 0

# 獲取手機的配置資訊
def get_item(skuid, url):
    price = get_price(skuid)
    r = requests.get(url, verify=False)
    content = r.content
    root = etree.HTML(content)
    nodes = root.xpath('.//div[@class="Ptable"]/div[@class="Ptable-item"]')
    params = {"price": price, "skuid": skuid}
    for node in nodes:
        text_nodes = node.xpath('./dl')[0]
        k = ""
        v = ""
        for text_node in text_nodes:
            if text_node.tag == "dt":
                k = text_node.text
            elif text_node.tag == "dd" and "class" not in text_node.attrib:
                v = text_node.text
                params[k] = v
    return params

# 獲取一個頁面中的所有手機資訊
def get_cellphone(page):
    url = "https://list.jd.com/list.html?cat=9987,653,655&page={}&sort=sort_rank_asc&trans=1&JL=6_0_0&ms=4#J_main".format(page)
    r = requests.get(url, verify=False)
    content = r.content.decode("utf-8")
    root = etree.HTML(content)
    cell_nodes = root.xpath('.//div[@class="p-img"]/a')
    client = pymongo.MongoClient()
    db = client[DB]
    for node in cell_nodes:
        item_url = fix_url(node.attrib["href"])
        matched = re.search('item.jd.com/(\d+)\.html', item_url)
        skuid = int(matched.group(1))
        saved = db.items.find({"skuid": skuid}).count()
        if saved > 0:
            print(saved)
            continue
        item = get_item(skuid, item_url)
        # 結果存入MongoDB
        db.items.insert(item)

需要注意的是,上面的get_price和get_item函式分別從兩個url獲取資料,這是因為配置資訊可以直接從商品頁面中解析得到,而價格資訊需要從另外一個ajax請求裡獲得。爬下來的所有資料存入MongoDB。

過濾資料

爬下來的手機資料當中,資訊完整的共有4700多條資料,這4700多部手機屬於70個手機品牌。 這些品牌畫成詞雲圖是這樣的

手機的配置主要有以下這些引數

  • 是否雙卡雙待

  • 機身材質

  • CPU型號

  • 記憶體大小

  • 儲存容量

  • 電池容量

  • 螢幕材質

  • 螢幕大小

  • 解析度

  • 攝像頭

強哥平時用手機主要是看看書、刷刷知乎微信、買買東西,所以選購新手機的時候最關心的就是速度、容量、待機時間這幾項,對攝像頭、螢幕材質倒不是特別在乎。考慮以上因素,在對資料做過濾的時候,我設定了以下幾個條件

  • CPU的品牌是高通

  • 記憶體大小大於等於6GB

  • 儲存容量大於等於64GB

  • 電池容量大於3000mAh

  • 必須是雙卡雙待

  • 價格在1500元以內

過濾資料的程式碼如下


client = pymongo.MongoClient()
db = client[DB]
items = db.items.find({})
result = preprocess(items)
df = pd.DataFrame(result)
df_res = df[df.cpu_brand=="驍龍(Snapdragon)"][df.battery_cap >= 3000][df.rom >= 64][df.ram >= 6][df.dual_sim == True][df.price<=1500]
print(df_res[["brand", "model", "color", "cpu_brand", "cpu_freq", "cpu_core", "cpu_model", "rom", "ram", "battery_cap", "price"]].sort_values(by="price"))

首先從MongoDB裡讀取資料,然後建立DataFrame,對DataFrame裡的資料按照上面的條件作選擇。程式碼的最後一行將篩選出來的手機打印出來,並按價格從低到高排序。

經過了這樣一輪篩選後,我們得到了下面的38款手機

上面的幾部手機配置都比較接近,但是網上對小米的評價普遍比較高,於是又在上面的列表裡篩選出了所有的小米手機,得到下面7款

這裡就變成了紅米Note5和小米6X的PK了。價格上,兩者不差上下。配置方面,網上查到紅米Note5的cpu是驍龍636的(上面的表格裡缺少紅米Note5的cpu型號),相比小米6X的驍龍660,636雖然效能上不如660,但更省電,而且考慮到紅米Note5 4000毫安的超大容量電池,最後決定了購買紅米Note 5這一款。作為一款千元機,驍龍636八核CPU、6G大記憶體、64G大儲存、5.99英寸大視野全面屏、前置相機+後置雙攝、超長的待機時間,這款手機大概算是千元機中的機皇了。

其實購買其他物件也可以爬取相關網站上的資料,選出自己最適合的產品服務。好了,也到福利時間了,需要相關爬蟲資料以及更多Python技術學習資料可以加Q群519970686免費領取,一起學習,相互討論。群內還有大咖分享專案經驗。