前言

上一篇文章完成了从wiki获取排名并保存到本地,接下来要进行数据处理。

思路

网路上已经有很多数据可视化的项目可以用,但是我懒得学,自己凑合写一个算了。
决定使用pillow的画图功能,把每份数据画到图片上,再用opencv生成视频。

代码实现

数据分析

数据都是这个格式,使用readline读入即可。

gjf/ - Fri Aug 30 04:46:42 2019
1 天城
2 俾斯麦
3 大凤
4 埃塞克斯
5 拉菲
6 企业
7 罗恩
8 Z23
9 欧根亲王
10 爱宕
11 巴尔的摩
12 让·巴尔
13 长门
14 齐柏林伯爵
15 圣地亚哥

import

# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import requests
from bs4 import BeautifulSoup
import os,sys
import _thread

获取头像

为了直观显示排名,只有名字是不行的,肯定要显示头像,头像这里还是从wiki获取。

pp = {}
edgeheaders = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362"}
def get_pp(name:str):
    #print(name)
    if name in pp.keys():
        return pp[name]
        #pp[name].show()
    else:
        r = requests.get("http://wiki.joyme.com/blhx/"+name,headers=edgeheaders)
        soup=BeautifulSoup(r.text,'lxml')
        src = soup.body.find(id = "wrapper").find(id = "bodyContent").find(class_ = "jntj").find(rowspan = "2").img.attrs['src']
        r1 = requests.get(src) 
        f = open("temp/"+name+".jpg","wb")
        f.write(r1.content)
        f.close()
        pp[name] = Image.open("temp/"+name+".jpg").resize((100,100))
        return pp[name]
        #pp[name].show()

requests比urllib好用多了。获取到的头像压入字典,之后可以直接调用,避免多次重复请求。

画图

没什么好说的了,把排名和头像用pillow的draw绘制成图片。

def make_pic(path:str):
    print(path,"start")
    filenames = os.listdir(path)
    color = {"gf/":(255, 223, 234),"gjf/":(225, 221, 219),"rf/":(239, 224, 250)}
    title = {"gf/":"国 服","gjf/":"国际服","rf/":"日 服"}
    for log in filenames:
        info = []
        f = open(path+log,"r",encoding='utf-8')
        for line in range(16):
            info.append(f.readline().split())
        f.close()
        #print(info)
        index = [[0, 0], [80, 0], [205, 0], [330, 0], [455, 0], [580, 0], [705, 0], [830, 0], [955, 0], [80, 320], [205, 320], [330, 320], [455, 320], [580, 320], [705, 320], [830, 320], [955, 320]]
        index1 = [12,12,50,124]
        width = 640
        height = 1080
        image = Image.new('RGB', (width, height), color[path])
        draw = ImageDraw.Draw(image)
        font = ImageFont.truetype('simhei.ttf', 36)
        draw.text((280,20),title[path],fill = (255,0,0),font = ImageFont.truetype('simhei.ttf', 40))
        for i in range(1,16):
            image.paste(get_pp(info[i][1]),(index[i][1]+index1[1], index[i][0]+index1[0]))
            draw.text((index[i][1]+index1[3], index[i][0]+index1[2]),info[i][0]+" "+info[i][1],fill = (255,0,0),font = font)
        end = info[0][6]+" "+info[0][3]+" "+info[0][4]
        draw.text((index[16][1]+70,index[16][0]+20),end ,fill = (255,0,0),font = font)
        draw.text((index[16][1]+70,index[16][0]+60),info[0][5],fill = (255,0,0),font = font)
        #image.show()
        image.save("temp2/"+path+log+".jpg")
        print(path+log,"done")
        #break

绘制完的图片是这个效果:mark

运行绘图程序

三线程分别负责三个服务器数据。

if __name__ == '__main__':
    #make_pic("rf/")
    _thread.start_new_thread( make_pic, ("gf/",) )
    _thread.start_new_thread( make_pic, ("gjf/",) )
    _thread.start_new_thread( make_pic, ("rf/",) )

拼接图片

刚才的代码忘了拼接,所以写一个代码拼接图片。

# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import os,sys
if __name__ == '__main__':
    gf = os.listdir("temp2/gf/")
    gjf = os.listdir("temp2/gjf/")
    rf = os.listdir("temp2/rf/")
    for i in range(len(gf)):
        image = Image.new('RGB', (1920, 1080))
        image.paste(Image.open("temp2/gf/"+gf[i]),(0,0))
        image.paste(Image.open("temp2/gjf/"+gjf[i]),(640,0))
        image.paste(Image.open("temp2/rf/"+rf[i]),(1280,0))
        image.save("temp3/"+str(100+i)+".jpg")

效果如下:mark

制作视频

使用opencv压制视频。

# -*- coding: utf-8 -*-
import os,sys
import cv2
if __name__ == '__main__':
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    videoWriter = cv2.VideoWriter('tempvideo.mp4', fourcc, 2.833, (1920, 1080))
    filenames = os.listdir("temp3/")
    for i in filenames:
        img = cv2.imread(filename="temp3/"+i)
        print("temp3/"+i)
        videoWriter.write(img)
        print(i,"done")
    videoWriter.release()

最终效果可以去哔哩哔哩看。


挂科一时爽,一直挂科一直爽。
🀇🀇🀇🀈🀉🀊🀋🀌🀍🀎🀏🀏🀏 🀋