爬了20W+條貓咪交易數據,它不愧是人類團寵

作者 | 葉庭雲

來源 | 修煉Python

頭圖 | 下載於視覺中國

前言

看到可愛的貓咪表情包,總是會忍不住收藏,曬部分圖如下:

認識的一些朋友也養了貓,比如橘貓、英短、加菲貓之類的,看他們發朋友圈擼貓,老羨慕了,貓咪真的太可愛啦。發現一個專門交易貓貓的網站—貓貓交易網可以雲看貓:http://www.maomijiaoyi.com/

從這個網站裏爬取了貓貓品種介紹的數據,以及 20W+ 條貓貓交易數據,以此來了解一下可愛的貓咪。

數據獲取

打開貓貓交易網,先爬取貓咪品種數據,打開頁面可以看到貓貓品種列表:

但只顯示了每種貓貓的品種名,參考價格,點進詳情頁,可以看到更加詳細的數據:品種名、參考價格、中文學名、基本信息、性格特點、生活習性、優缺點、餵養方法等。

檢查網頁,可以發現網頁結構簡單,容易解析和提取數據。爬蟲代碼如下:

  1# -*- coding: UTF-8 -*-
  2"""
  3@File    :cat_kind_spider.py
  4@Author  :葉庭雲
  5@CSDN    :https://yetingyun.blog.csdn.net/
  6"""
  7import requests
  8import re
  9import csv
 10from lxml import etree
 11from tqdm import tqdm
 12from fake_useragent import UserAgent
 13
 14# 隨機產生請求頭
 15ua = UserAgent(verify_ssl=False, path='fake_useragent.json')
 16
 17def random_ua():        # 用於隨機切換請求頭
 18    headers = {
 19        "Accept-Encoding": "gzip",
 20        "Accept-Language": "zh-CN",
 21        "Connection": "keep-alive",
 22        "Host": "www.maomijiaoyi.com",
 23        "User-Agent": ua.random
 24    }
 25    return headers
 26
 27
 28def create_csv():          # 創建保存數據的csv
 29    with open('./data/cat_kind.csv', 'w', newline='', encoding='utf-8') as f:
 30        wr = csv.writer(f)
 31        wr.writerow(['品種', '參考價格', '中文學名', '別名', '祖先', '分佈區域',
 32                     '原產地', '體型', '原始用途', '今日用途', '分組', '身高',
 33                     '體重', '壽命', '整體', '毛髮', '顏色', '頭部', '眼睛',
 34                     '耳朵', '鼻子', '尾巴', '胸部', '頸部', '前驅', '後驅',
 35                     '基本信息', 'FCI標準', '性格特點', '生活習性', '優點/缺點',
 36                     '餵養方法', '鑑別挑選'])
 37
 38
 39def scrape_page(url1):      # 獲取HTML網頁源代碼 返回文本
 40    response = requests.get(url1, headers=random_ua())
 41    # print(response.status_code)
 42    response.encoding = 'utf-8'
 43    return response.text
 44
 45
 46def get_cat_urls(html1):    # 獲取每個品種貓咪詳情頁url
 47    dom = etree.HTML(html1)
 48    lis = dom.xpath('//div[@class="pinzhong_left"]/a')
 49    cat_urls = []
 50    for li in lis:
 51        cat_url = li.xpath('./@href')[0]
 52        cat_url = 'http://www.maomijiaoyi.com' + cat_url
 53        cat_urls.append(cat_url)
 54    return cat_urls
 55
 56
 57def get_info(html2):    # 爬取每個品種貓咪詳情頁裏的有關信息
 58    # 品種
 59    kind = re.findall('div class="line1">.*?<div class="name">(.*?)<span>', html2, re.S)[0]
 60    kind = kind.replace('\r','').replace('\n','').replace('\t','')
 61    # 參考價格
 62    price = re.findall('<div>參考價格:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 63    price = price.replace('\r', '').replace('\n', '').replace('\t', '')
 64    # 中文學名
 65    chinese_name = re.findall('<div>中文學名:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 66    chinese_name = chinese_name.replace('\r', '').replace('\n', '').replace('\t', '')
 67    # 別名
 68    other_name = re.findall('<div>別名:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 69    other_name = other_name.replace('\r', '').replace('\n', '').replace('\t', '')
 70    # 祖先
 71    ancestor = re.findall('<div>祖先:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 72    ancestor = ancestor.replace('\r', '').replace('\n', '').replace('\t', '')
 73    # 分佈區域
 74    area = re.findall('<div>分佈區域:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 75    area = area.replace('\r', '').replace('\n', '').replace('\t', '')
 76    # 原產地
 77    source_area = re.findall('<div>原產地:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 78    source_area = source_area.replace('\r', '').replace('\n', '').replace('\t', '')
 79    # 體型
 80    body_size = re.findall('<div>體型:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 81    body_size = body_size.replace('\r', '').replace('\n', '').replace('\t', '').strip()
 82    # 原始用途
 83    source_use = re.findall('<div>原始用途:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 84    source_use = source_use.replace('\r', '').replace('\n', '').replace('\t', '')
 85    # 今日用途
 86    today_use = re.findall('<div>今日用途:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 87    today_use = today_use.replace('\r', '').replace('\n', '').replace('\t', '')
 88    # 分組
 89    group = re.findall('<div>分組:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 90    group = group.replace('\r', '').replace('\n', '').replace('\t', '')
 91    # 身高
 92    height = re.findall('<div>身高:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 93    height = height.replace('\r', '').replace('\n', '').replace('\t', '')
 94    # 體重
 95    weight = re.findall('<div>體重:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 96    weight = weight.replace('\r', '').replace('\n', '').replace('\t', '')
 97    # 壽命
 98    lifetime = re.findall('<div>壽命:</div>.*?<div>(.*?)</div>', html2, re.S)[0]
 99    lifetime = lifetime.replace('\r', '').replace('\n', '').replace('\t', '')
100    # 整體
101    entirety = re.findall('<div>整體</div>.*?<!-- 頁面小折角 -->.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
102    entirety = entirety.replace('\r', '').replace('\n', '').replace('\t', '').strip()
103    # 毛髮
104    hair = re.findall('<div>毛髮</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
105    hair = hair.replace('\r', '').replace('\n', '').replace('\t', '').strip()
106    # 顏色
107    color = re.findall('<div>顏色</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
108    color = color.replace('\r', '').replace('\n', '').replace('\t', '').strip()
109    # 頭部
110    head = re.findall('<div>頭部</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
111    head = head.replace('\r', '').replace('\n', '').replace('\t', '').strip()
112    # 眼睛
113    eye = re.findall('<div>眼睛</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
114    eye = eye.replace('\r', '').replace('\n', '').replace('\t', '').strip()
115    # 耳朵
116    ear = re.findall('<div>耳朵</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
117    ear = ear.replace('\r', '').replace('\n', '').replace('\t', '').strip()
118    # 鼻子
119    nose = re.findall('<div>鼻子</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
120    nose = nose.replace('\r', '').replace('\n', '').replace('\t', '').strip()
121    # 尾巴
122    tail = re.findall('<div>尾巴</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
123    tail = tail.replace('\r', '').replace('\n', '').replace('\t', '').strip()
124    # 胸部
125    chest = re.findall('<div>胸部</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
126    chest = chest.replace('\r', '').replace('\n', '').replace('\t', '').strip()
127    # 頸部
128    neck = re.findall('<div>頸部</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
129    neck = neck.replace('\r', '').replace('\n', '').replace('\t', '').strip()
130    # 前驅
131    font_foot = re.findall('<div>前驅</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
132    font_foot = font_foot.replace('\r', '').replace('\n', '').replace('\t', '').strip()
133    # 後驅
134    rear_foot = re.findall('<div>前驅</div>.*?<div></div>.*?<div>(.*?)</div>', html2, re.S)[0]
135    rear_foot = rear_foot.replace('\r', '').replace('\n', '').replace('\t', '').strip()
136
137    # 保存前面貓貓的各種有關信息
138    cat = [kind, price, chinese_name, other_name, ancestor, area, source_area,
139           body_size, source_use, today_use, group, height, weight, lifetime,
140           entirety, hair, color, head, eye, ear, nose, tail, chest, neck, font_foot, rear_foot]
141
142    # 提取標籤欄信息(基本信息-FCI標準-性格特點-生活習性-優缺點-餵養方法-鑑別挑選)
143    html2 = etree.HTML(html2)
144    labs = html2.xpath('//div[@class="property_list"]/div')
145    for lab in labs:
146        text1 = lab.xpath('string(.)')
147        text1 = text1.replace('\n','').replace('\t','').replace('\r','').replace(' ','')
148        cat.append(text1)
149    return cat
150
151
152def write_to_csv(data):     # 保存數據  追加寫入
153    with open('./data/cat_kind.csv', 'a+', newline='', encoding='utf-8') as fn:
154        wr = csv.writer(fn)
155        wr.writerow(data)
156
157
158if __name__ == '__main__':
159    # 創建保存數據的csv
160    create_csv()
161    # 貓咪品種頁面url
162    base_url = 'http://www.maomijiaoyi.com/index.php?/pinzhongdaquan_5.html'
163    # 獲取品種頁面中的所有url
164    html = scrape_page(base_url)
165    urls = get_cat_urls(html)
166    # 進度條可視化運行情況    就不打印東西來看了
167    pbar = tqdm(urls)
168    # 開始爬取
169    for url in pbar:
170        text = scrape_page(url)
171        info = get_info(text)
172        write_to_csv(info)

運行效果如下:

成功爬取了貓咪品種數據保存到csv,接下來爬取貓貓交易數據,進入到買貓賣貓頁面:

爬取更詳細的數據需要進入詳情頁,包含商家信息、貓咪品種、貓齡、價格、標題、在售只數、預防等信息。

由於數據量較大,可以分開爬取,先獲取到每一頁中的所有貓貓詳情交易鏈接的 url 保存到csv,再讀取 csv 中的 url 來請求,爬取每條交易數據,爬蟲思路跟前面類似,爲了加快爬取效率,可以使用多線程或者異步爬蟲。最終獲取了 20W+ 條數據。

數據探索

通過詞雲圖來直觀看一下,可愛的貓咪都有那些品種。

看各種貓咪的體型分佈

所有品種的貓咪裏,大型的只有一個品種,是布偶貓,其他品種都是中小型,那以後看見體型比較大的,可以先想到布偶貓。

橘貓是世界各地都有的,不愧是我大橘貓。俗話說 "十個橘貓九個胖還有一個壓塌炕"。橘貓比起其他花色的貓咪更喜歡喫東西,它們的食慾很好,能更好地生存,可能這也是橘貓在世界範圍都有的原因吧。可它卻是小型貓,橘貓小時候顏值一般挺高,看起來小小的一隻,又嫩又可愛的,但等橘貓長大以後,才真正地意識到什麼是 "橘足輕重"。

下面來看貓咪的交易數據,在交易的貓咪中,哪些品種交易數量最多呢?

橘貓的交易數量最多呀,之前也提到橘貓世界各地都有,從這裏也可以看到橘貓數量最多。其次是咖啡貓,布偶貓,英短藍白貓等。

再看看賣貓商家地區分佈

四川,重慶,廣東是貓咪售賣商家數量最多的省份,江浙滬等地區貓咪售賣商家數量也很多,均在 10000 家以上。

緬因貓、布偶貓均價名列前茅啊,橘貓的均價排倒數第二,看來挺實惠。

這些售賣的貓咪貓齡一般爲多大呢?

售賣的貓咪貓齡主要在1-6個月,都是剛出生還未滿半歲的小貓咪呀。這時候的小貓咪應該很可愛吧,等待有緣的主人把它帶回家。

最後來看一下網站裏價格最貴的貓咪和瀏覽次數最多的貓咪

 1# -*- coding: UTF-8 -*-
 2"""
 3@File    :瀏覽最多_價格最貴的.py
 4@Author  :葉庭雲
 5@CSDN    :https://yetingyun.blog.csdn.net/
 6"""
 7import pandas as pd
 8
 9df = pd.read_excel('處理後數據.xlsx')
10print(df.info())
11df1 = df.sort_values(by='瀏覽次數', ascending=False)
12print(df1.iloc[:3, ::].values)
13print('----------------------------------------------------------')
14df2 = df.sort_values(by='價格', ascending=False)
15print(df2.iloc[:3, ::].values)
1# 瀏覽次數最多的
2http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_441879.html
3http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_462431.html
4http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_455366.html

瀏覽次數最多的是這一家賣的緬因貓,瀏覽次數爲16164。emmm,感覺這種貓咪看着還挺兇的,不怎麼可愛。

反觀瀏覽次數排第二、第三的,價格便宜不少,預防都打了3針疫苗,在售只數還比較充裕,還比第一可愛好多(個人感覺)。

1# 價格最貴的如
2http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_265770.html
3http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_281910.html
4http://www.maomijiaoyi.com/index.php?/chanpinxiangqing_230417.html

價格最貴的發現均爲 3000 元的布偶貓。查閱資料發現,布偶貓,大型貓咪,不僅購買的時候價格高昂,飼養成本也比較高,因爲食量和運動量都比較大,而且美容等相關費用也會高一些。

參考文章:

https://mp.weixin.qq.com/s/-Fh156bh1166R9fqNa6OmQ

福 利

CSDN給大家發壓歲錢啦!

2月4日到2月11日每天上午11點

價值198元的芒果TV年卡,價值99元的CSDN月卡現金紅包,CSDN電子書月卡等獎品大放送!百分百中獎

電腦端點擊鏈接參與:

https://t.csdnimg.cn/gAkN

更多精彩推薦
☞英超引入 AI 球探,尋找下一個足球巨星☞三年投 1000 億,達摩院何以仗劍走天涯?☞程序員硬核“年終大掃除”,清理了數據庫 70GB 空間
☞2021年淺談多任務學習
點分享點收藏點點贊點在看
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章