淘宝、拼多多、抖音主播颜值大比拼

淘宝、拼多多、抖音主播颜值大比拼

今年的 618,各大在线购物网站主打网络直播,如:淘宝、拼多多、抖音。在直播视频中每个主播都是高颜值的帅哥美女,那谁家的主播颜值最高呢?让我们用 Python 打造一款颜值排行利器吧。

技术点

使用 ADB(Android Debug Bridge)技术用 Python 代码控制手机截取直播的屏幕再发送到电脑后,使用百度 AI 开放平台的 人脸检测 API 请求得出颜值,最后使用 pyecharts 画出图表

使用的技术点有:

  1. ADB 命令
  2. 百度 AI 开放平台人脸检测 API
  3. pyecharts 画出图表

ADB

第一步需要在电脑端安装 ADB,大家可以自行百度或 google 一下。下面介绍一下需要用到的 ADB 命令

截取屏幕

将截取屏幕的图片放到 /sdcard/zhubo/taobao/xxxx.png

1
adb shell /system/bin/screencap -p /sdcard/zhubo/taobao/xxxx.png
滑动屏幕

将截取屏幕的图片放到 /sdcard/zhubo/taobao/xxxx.png

1
adb shell input swipe 1000 300 1000 10
发送文件到电脑

把文件从手机的移动到电脑

1
adb pull /sdcard/zhubo/taobao/xxxx.png /Users/xx/Desktop/zhubo/taobao/xxxx.png,
列出手机文件夹中的文件

列出 taobao 文件夹下的所有文件

1
adb shell ls /sdcard/zhubo/taobao
在 python 中的使用

在 Python 代码中使用 subprocess 模块调用 ADB 命令,总共有三个函数分别为:__init__函数、screen函数、pull函数。

__init__ 函数在类初始化的时候判断是否连接了手机设备 screen 函数截取手机屏幕,将图像保存在手机的文件夹中 pull 函数将截取的图像发送到电脑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import subprocess

mobile_root = "/sdcard/zhubo/"
computer_root = "/Users/xx/Desktop/zhubo/"
except_file = "/Users/xx/Desktop/zhubo/except.txt"


def __init__(self):
    '''
    查看连接的手机,没有手机连接则抛出异常
    '''

    connect = subprocess.Popen("adb devices",
                                stderr=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                shell=True)
    stdout, stderr = connect.communicate()  # 获取返回命令
    # 输出执行命令结果结果
    stdout = stdout.decode("utf-8")

    if len(stdout) <= 26:
        raise Exception("没有连接到手机")
    print("成功连接手机!")


def screen(self, platform):
    '''
    截取屏幕,保存到手机中的 /sdcard/zhubo/ + platform 文件夹中
    :param platform: 平台,如:taobao、pdd、jingdong
    '''

    for i in range(1, 618):
        time.sleep(3)
        pic_name = platform + '_' + str(int(time.time() * 1000)) + '.png'
        
        # 截屏
        screencap = subprocess.Popen('adb shell /system/bin/screencap -p /sdcard/zhubo/' + platform + '/' + pic_name,
                                    stderr=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    shell=True)
        
        # 滑动屏幕
        swipe = subprocess.Popen('adb shell input swipe 1000 300 1000 10',
                                    stderr=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    shell=True)
        print(str(i) + '    ' + pic_name)
    

def pull(self, platform):
    '''
    发送到电脑
    '''
    
    # 列出所有图像
    connect = subprocess.Popen('adb shell ls /sdcard/zhubo/' + platform,
                                stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
    stdout, stderr = connect.communicate()
    stdout = stdout.decode("utf-8")
    pics = stdout.split('\n')

    for pic_name in pics:
        # 发送到电脑 /Users/xx/Desktop/zhubo/platform 文件夹下
        connect = subprocess.Popen('adb pull /sdcard/zhubo/' + platform + '/' + pic_name  + ' /Users/xx/Desktop/zhubo/'+platform + '/' + pic_name,
                                    stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
    print('手机中的图像成功发送到电脑')

示例结果

淘宝、拼多多、抖音每个平台都截取了将近 800 张图片,过滤掉一些没有人像的图片,文章中每个平台将使用 618 张图片。

人脸检测

人脸检测我们使用百度 AI 开放平台的 API(https://ai.baidu.com/tech/face/detect),大家都知道百度 AI 开放平台的 API 需要登录百度账号后获取 AK 和 SK 取得 token 值才能得到调用。

获取 access_token

import time import requests

1
2
3
4
5
6
7
8
9
10
11
12
13
def getAccessToken(self):
    '''
    获取百度 AI 开放平台的 access_token
    :return: access_token
    '''
    
    ak = 'ak'
    sk = 'sk'

    host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + ak + '&client_secret=' + sk
    response = requests.get(host)
    if response:
        return response.json()['access_token']

获取颜值

获取颜值需要用到人脸检测的 API 也是相当的简单,必要的参数只需传入 image 为 base64 位的图片、指定图片类型 image_type 为 base64 以及返回的结果 face_field 为 beauty(颜值),外加上面获取到的 access_token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def image2base64(self, pic_path):
    '''
    图片转base64
    :param image_path: 图片地址
    :return: base64
    '''

    with open(pic_path, 'rb') as f:
        base64_data = base64.b64encode(f.read())
        s = base64_data.decode()
        return s

def beauty_detect(self, access_token, platform):
    '''
    人脸检测
    :param access_token: access_token
    :param platform: 平台,如:taobao、pdd、jingdong
    :return: 文件
    '''

    # 人脸检测 url
    request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"

    # 为了防止请求百度发生意外事故,将颜值结果写入文件
    filename = self.computer_root + platform + '.txt'

    index = 0
    # 循环所有图片
    for root, dirs, files in os.walk(self.computer_root + platform ):
        for pic in files:
            index = index + 1
            base64img = self.image2base64(root + '/' + pic)
            
            params = "{\"image\":\"" + base64img + "\",\"image_type\":\"BASE64\",\"face_field\":\"beauty\"}"
            request_url = request_url + "?access_token=" + access_token
            headers = {'content-type': 'application/json'}
            
            # 免费 API QPS只有2个,可以使用多个账号,注意:这里容易异常
            response = requests.post(request_url, data=params, headers=headers)
            
            print(response)
            if response:
                json = response.json()
                print(json)
                # 解析获取颜值i
                if json['error_msg'] == 'SUCCESS':
                    face_list = json['result']['face_list']
                    beauty_list = []
                    for face in face_list:
                        beauty_list.append(face['beauty'])
                        beauty = max(beauty_list)

                        with open(filename, 'a') as f:
                            f.write(str(index) + ',' + pic + ',' + str(beauty) + '\n')

示例结果(部分):

图表

在上一节中已经计算出了每一张图片上美女、帅哥的颜值,在这一节将统计颜值在 [“90-100”, “80-89”, “70-79”, “60-69”, “50-59”, “40-49”, “30-39”, “20-29”, “10-19”, “0-9”]分值阶段的个数并使用 pyecharts 模块统计成柱状图和饼图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from pyecharts.charts import Bar, Pie
from pyecharts import options as opts

def calc(self, platform):
'''
统计颜值区间的个数
:param platform: 平台,如:taobao、pdd、douyin
:return: 颜值区间汇总、颜值字典
'''

beauty_sum_dir = {"90-100": 0, "80-89": 0, "70-79": 0, "60-69": 0, "50-59": 0, "40-49": 0, "30-39": 0,
                    "20-29": 0, "10-19": 0, "0-9": 0}
beauty_dir = {}

beauty_areas = ["90-100", "80-89", "70-79", "60-69", "50-59", "40-49", "30-39", "20-29", "10-19", "0-9"]

filename =  self.computer_root + platform + '.txt'

with open(filename) as f:
    lines = f.readlines()

if lines == None or len(lines) == 0:
    raise Exception(filename + '中没有颜值数据')


index = 0
for line in lines:
    # 只取 618 个图像
    index = index + 1
    if index > 618:
        break

    l = line.rstrip()
    result = l.split(',')
    beauty = float(result[2])

    beauty_area = beauty_areas[int((beauty // 10 * -1) - 1)]
    beauty_sum_dir[beauty_area] = beauty_sum_dir.get(beauty_area) + 1

    beauty_dir[result[1]] = result[2]

return beauty_sum_dir, beauty_dir

def bar(self, taobao_beauty_sum_dir = {}, pdd_beauty_sum_dir = {}, douyin_beauty_sum_dir = {}):
    '''
    柱状图
    :param taobao_beauty_sum_dir: 淘宝颜值区间汇总
    :param pdd_beauty_sum_dir: 拼多多颜值区间汇总
    :param douyin_beauty_sum_dir: 抖音颜值区间汇总
    :return: 
    '''
    
    bar = (
        Bar()
            .add_xaxis(list(taobao_beauty_sum_dir.keys()))
            .add_yaxis('淘宝', list(taobao_beauty_sum_dir.values()))
            .add_yaxis("拼多多", list(pdd_beauty_sum_dir.values()))
            .add_yaxis("抖音", list(douyin_beauty_sum_dir.values()))
            .set_global_opts(title_opts=opts.TitleOpts(title="主播颜值柱状图"))

    )
    bar.render("颜值柱状图.html")

def pie(self, platform, beauty_sum_dir = {}):
    '''
    饼图
    :param platform:  平台,如:taobao、pdd、douyin
    :param beauty_sum_dir: 颜值区间汇总
    :return: 
    '''
    
    c = (
        Pie()
            .add(
            "",
            [list(z) for z in zip(beauty_sum_dir.keys(), beauty_sum_dir.values())],
            center=["35%", "50%"],
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(title=platform + '主播颜值饼图'),
            legend_opts=opts.LegendOpts(pos_left="15%"),
        )
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}({d}%)"))
            .render(platform + "颜值饼图.html")
    )

示例结果

从图表中可以看出,抖音主播的颜值最高在[60-89]分值区域人数最多,分值在[50-59]区域拼多多三者都相差不大,拼多多以一点点的优势胜出,[49-0]分值区域淘宝主播人数最多。可以得出结论如果只是冲主播颜值去看直播抖音是个第一选择。

前三颜值主播

最后按颜值倒序排列一下,欣赏一下前三的颜值主播吧

1
2
def sorted_by_value(self, beauty_dir):
    return beauty_sorted = sorted(beauty_dir.items(), key = lambda kv:(kv[1], kv[0]), reverse=True)

示例结果

总结

使用人脸检测技术得出抖音上高颜值主播的数量要大于淘宝和拼多多。完整的代码在代码示例中,有兴趣的朋友可以跑出来看看各大平台给你推荐的哪位高颜值主播。

示例代码:https://github.com/JustDoPython/python-examples/tree/master/moumoubaimifan/zhubo

Python Geek Tech wechat
欢迎订阅 Python 技术,这里分享关于 Python 的一切。