現(xiàn)在越來越多的人喜歡化妝、醫(yī)美啊,所以長得都一樣。放眼望去大街上到處是美女,而且怎么還長得很像呢?
我們測測他們的顏值如何吧? 此次我們明星里的美女帥哥為例測試顏值(當(dāng)然也可以加入你的照片了,只要結(jié)果不怕被打擊)
測評步驟:
爬取貼吧中的你想測評的明星美女和帥哥們
使用第三方的人臉識別測評工具
使用數(shù)據(jù)分析對其結(jié)果進(jìn)行可視化
先給大家一個效果圖,帥哥的顏值排名!
想知道你的顏值嗎?那我們就開始吧!
爬蟲部分
此次我們爬取的是百度貼吧中的明星圖片,以劉詩詩的圖片爬取為例
鏈接:https://tieba.baidu.com/p/3263751314#!/l/p1
分析一下圖片的加載方式,發(fā)現(xiàn)是AJAX的異步請求,請求的鏈接是:
其中紅線位置的是有變化的部分。pn=1表示第一頁的圖片顯示,除了默認(rèn)加載的圖片隨著鼠標(biāo)的滑動在第一頁還可以加載更多的內(nèi)容,但是需要指定開始和結(jié)束位置。而ps=1就表示從第1開始,pe=40就表示到40結(jié)束(ps和pe中的s表示start,e表示end)。一頁一共有200條數(shù)據(jù),那后面的紅線位置是什么呢?是不斷變化的數(shù)值。通過分析我們了解到這個數(shù)值是時(shí)間戳。于是我們可以這樣拼接我們的請求鏈接。
import time
def get_timestamp():
t = str(time.time())
return t.replace(".","")[:-3] # 因?yàn)樽詈蟮臅r(shí)間是13位
if __name__ == '__main__':
for page in range(1,2):
for i in range(page,page+5):
start = (i-page)*40+1+200*(page-1)
end = 200*(page-1)+(i-page+1)*40
ts = get_timestamp()
url = f'https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E5%88%98%E8%AF%97%E8%AF%97&alt=jview&rn=200&tid=3263751314&pn={page}&ps={start}&pe={end}&info=1&_={ts}'
print(url)
OK!這樣我們的鏈接就做好了,注意本次選擇的只有一頁。所以外層循環(huán)是range(1,2)。
因?yàn)檫@個鏈接返回結(jié)果是Json數(shù)據(jù),所以我們網(wǎng)絡(luò)請求要這樣處理
head = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36",
'Referer': 'https://tieba.baidu.com/p/1457326101'} # 必不可少的Referer 認(rèn)證
# 通過requests獲取訪問的頁面
def get_json(url):
r = requests.get(url, headers=head)
if r.status_code != 200: # 如果沒有正常獲得網(wǎng)頁,產(chǎn)生異常
raise Exception()
return r.json()
這樣我們就可以獲取所有圖片的json數(shù)據(jù)啦!但是我們要從數(shù)據(jù)中把圖片的鏈接解析出來。格式化后的json如下圖:
我們現(xiàn)在要從json中把purl對應(yīng)的鏈接解析出來,代碼如下
def parse_json(json, name):
pic_list = json.get('data').get('pic_list')
for pic in pic_list:
purl = pic.get('purl')
# time.sleep(3) # 此處可以考慮使用休眠
拿到purl之后,我們可以再次請求網(wǎng)絡(luò)進(jìn)行下載
head1 = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36",
'Host': 'imgsrc.baidu.com'
}
def get_pic(pic_url, name):
r = requests.get(pic_url, headers=head1)
if r.status_code != 200: # 如果沒有正常獲得網(wǎng)頁,產(chǎn)生異常
raise Exception()
filename = pic_url.rsplit('/')[-1]
print(filename)
with open('girl1/' + name + filename, mode='wb') as sw:
sw.write(r.content)
print('下載圖片:' + filename + '成功!')
這樣圖片就會被保存到指定的位置,注意在保存的時(shí)候使用了一個name,主要用于后期我們進(jìn)行識別時(shí)的分類。
最后在入口調(diào)用上面的函數(shù)代碼如下:
def maindown(url, name):
num = 1
# 下載html頁面
json = get_json(url)
# 從頁面中提取鏈接
parse_json(json, name)
if __name__ == '__main__':
for page in range(1, 5):
for i in range(page, page + 5):
start = (i - page) * 40 + 1 + 200 * (page - 1) # 201. 241. 281. 321 361
end = 200 * (page - 1) + (i - page + 1) * 40 # 240 280 320 360 400 440. 3*40
ts = get_timestamp()
url = f'https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E5%88%98%E8%AF%97%E8%AF%97&alt=jview&rn=200&tid=3263751314&pn={page}&ps={start}&pe={end}&info=1&_={ts}'
# 下載html頁面
json = get_json(url)
# 從頁面中提取圖片鏈接并下載到本地
parse_json(json, name)
time.sleep(5) # 此處加了休眠的目的是防止被阻止爬取
下載成功后的圖片展示:
顏值測評
顏值測評我們使用到的是百度的AI人臉檢測,我們并沒有使用自定義的人臉檢測部分。
所以我們要簡單的了解下如何使用人家做好的現(xiàn)成的東西,當(dāng)然這個不僅僅可以測顏值,還可以測年齡,性別啊等等。可以參考官方文檔:http://ai.baidu.com/ai-doc/FACE/yk37c1u4t
要想使用人臉檢測這款產(chǎn)品首先要注冊成為百度賬戶才可以。步驟是:
成為開發(fā)者
創(chuàng)建應(yīng)用
獲取密鑰,進(jìn)入應(yīng)用中獲取密鑰
生成簽名,這個要依賴你上面創(chuàng)建應(yīng)用的AppID、API Key及Secret Key三個值,進(jìn)行Access Token(用戶身份驗(yàn)證和授權(quán)的憑證)的生成。
參考鏈接:https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu
官方給出的Python API使用文檔,代碼如下:
class BaiduPicDetect:
def __init__(self):
self.AK = "你的API Key"
self.SK = "Secret Key"
self.headers = {
"Content-Type": "application/json; charset=UTF-8"
}
# 通過AK和SK得到access_token值
def get_access_token(self):
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + self.AK + '&client_secret=' + self.SK
response = requests.get(host, headers=self.headers)
json_result = json.loads(response.text)
return json_result['access_token']
啟動開發(fā),目前AI產(chǎn)品主要有兩種方式使用:API與SDK,您可以選擇各產(chǎn)品的文檔
篇幅原因,具體使用請參考:http://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjgn3
百度人臉檢測API目前支持三種圖片數(shù)據(jù)類型:一種就是BASE64;第二種是URL,也就是在線的圖片源地址;第三種是FACE_TOKEN。
我們是將圖片下載到了本地,所以我們需要將圖片轉(zhuǎn)成BASE64
# 注意下面兩個方法也是BaiduPicDetect類中的方法
# 要將識別的圖片轉(zhuǎn)成base64格式
def img_to_base64(slef, path):
with open(path, 'rb') as f:
base64_data = base64.b64encode(f.read())
return base64_data
# 開始檢測每一張圖片
def detect_face(self, img_src):
..... # 代碼太多回復(fù)給源碼
return age, beauty, gender
類我們封裝完畢之后,我們開始遍歷我們下載的圖片進(jìn)行顏值測評了,并且我們把測評的數(shù)據(jù)保存到csv文件中。
def beauty_check(path):
...... # 遍歷path文件夾并將測評數(shù)據(jù)保存到DataFrame中,其中df即DataFrame對象
return df
if __name__ == '__main__':
# 當(dāng)前py文件與girl文件夾在同級,而圖片都在girl文件夾中(僅是美女的圖片哦!也可以創(chuàng)建boy的文件夾放帥哥)
path = 'girl'
result = beauty_check(path)
result.to_csv('./girl/顏值測評.csv', index=False)
print('finish!')
整體結(jié)構(gòu)是這樣的:
下載后的csv數(shù)據(jù)如下(溫馨提示這個也跟圖片有關(guān))哈哈哈年齡好年輕啊!
數(shù)據(jù)分析
下面就開始我們的數(shù)據(jù)分析部分啦!代碼很簡單了。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 處理中文問題 我是Mac系統(tǒng)
data= pd.read_csv('./girl.csv',error_bad_lines=False)
由于我們獲取了多位美女的多張圖片,所以我們要求一下每位美女的顏值平均值,所以我們按照名字進(jìn)行分組,并求顏值的平均值。
下面的代碼我們進(jìn)行了一下排序:
beauty = data.groupby('name')['beauty'].mean().sort_values(ascending=False)
對分組求平均值后的數(shù)據(jù)進(jìn)行可視化展示
sns.barplot(x=beauty.index,y=beauty.values,palette=sns.color_palette('husl'))
結(jié)果出來了:
由于篇幅問題,有些代碼省略了,有需要的朋友!可以索要源碼哦!