acfun网站400W用户数据分析和pyecharts可视化

首先在这给我心爱的Acfun说句抱歉了,这几天进行的数据爬取如果对猴山产生了不好的影响,请接受我的道歉。
本次所有代码都会上传到GitHub上:爬虫部分和ip搜索部分
sql文件地址:百度云盘 密码:5xov
项目代码分成三个部分:
1、爬取基础数据
2、根据ip地址查询相对应的省市地址
3、统计:将你想查看的html复制下来然后网页打开就能看到效果了

本次实例是通过分析A站获取用户数据的接口,通过scrapy获取每个用户的一些基本资料。包括ip,用户名,最后登录时间,注册时间等。
本次总共获取的详细数据有4302457条,详细数据有:798817。数据丢失量在5%左右,由于A站的多次宕机和高层变动等原因,以及今年上半年‘凉了’的故事,或许对数据有一定的影响。导致本次数据获取与统计,在14年前的统计感觉有失真实性。姑且就先这样吧。
本次统计有:
1、从建站以来到2018-8月每年用户注册数量和消失数量柱状图
2、所有记录中性别比例饼图
3、所有修改了个性签名用户中,出现最频繁的词,生成词云图
4、从2018-01-01以来,所有登录过A站的用户全国省分布图
(正常情况下应该统计的事距离查询完日期后,往前两个月或者一个月仍会登录的用户为活跃用户)
5、每年注册人数和十二个月中,每个月注册人数折线图和柱状图
本次所有统计生成工具为pyecharts。
为了方便展示,我在用pycharts生成文件时,生成了png,其实这个生成html所形成的效果图是最直观的。页面上会有一些动态操作可以进行。
统计1:
在这里插入图片描述
从图中可以看出,17年的各种动荡和视频内容的不完善与落后,让许多Acer的脚步停留在了17年里。
而18年的“A站已凉”更是加剧了这种显现的出现。一直到几年8月份,A站活跃用户和新增的数量也往往不及前两年。

统计2:
在这里插入图片描述

对,相信自己的眼睛,这大部分都是女性。 事实上是真的嘛? 不是的。今年上半年有一次数据调整,猴子在修改还是转移数据的时候,将大部分人的性别修改成了女性
统计3:
词云图生成可以看:
在这里插入图片描述
虽然A站的用户以基佬遍天下而乐于自嘲,但是在个签上能体现出的真不多,大多数是up主的一些微博微信qq群啥的,但是由此也能看到一些正常的感悟人生和个人兴趣。
统计4:
在这里插入图片描述
由图中可看出,A站用户主要还是分布在中部和东部地区。
在数据统计当中,还有国外的数据未统计在地图中,计划是在世界地图中展示,然而pyecharts的作者们没有添加世界地图国家经纬度搜索,需要手动进行。有时间再做吧。需要一个个查坐标的。。
但是看在控制台输出的数据中,各个发达国家和日本韩国登录用户较多,也就是说大多数都是留学生出国在外的人访问的多。(还有一些战乱国家也有登录的,大兄弟!牛逼!)
统计5:
在这里插入图片描述
在这里插入图片描述
由这个统计可以看出来,每年的秋冬季节是注册人数的高峰期,或许是因为天气变冷,大家都不想出门,开始存膘过冬的习性,宅家里进行一些网上娱乐就变多了。而春夏季节,则是减少的。春天了,又到了交配的季节了。。。你懂的,多出门约小姐姐,解决终身大事吧。
统计的相关代码:

# -*- coding: utf-8 -*-
from pyecharts import Bar
from pyecharts import Pie
from pyecharts import Line
from pyecharts import Geo
import urllib.request
import urllib.parse
import json
import pymysql


# 获取指定区间内男女比例
def create_gender_round():
    sql = "select gender,count(*) from user_info group by gender "
    datas = get_all_data(sql)
    info_name = ['隐藏', '男性', '女性', 'Acer']
    man = 0
    women = 0
    Xman = 0
    acer = 0
    for i in datas:
        if i[0] == -1:
            Xman = i[1]
        elif i[0] == 1:
            man = i[1]
        elif i[0] == 0:
            women = i[1]
        elif i[0] == 2:
            acer = i[1]
    pie = Pie('男女用户比例')
    pie.add('性别比例图', info_name, [Xman, man, women, acer], radius=None, center=None, rosetype='')
    # rosetype 是否展示成南丁格尔图,通过半径区分数据大小,有
    # 'radius'和'area'两种模式。默认为
    # 'radius'
    # radius:扇区圆心角展现数据的百分比,半径展现数据的大小
    # area:所有扇区圆心角相同,仅通过半径展现数据大小
    # pie.render('detail\性别比例图.html')
    pie.render('detail\比例图.png')


# 每年注册人数
def create_bar_year():
    sql = "select regtime from user_info order by regtime"
    data = get_all_data(sql)
    yera = {}
    for i in data:
        y = i[0][0:4]
        if y in yera:
            count = yera.get(y)
            count += 1
            yera[y] = count
        else:
            yera[y] = 0

    bar = Bar("每年注册人数", "按年划分")
    bar.add("", list(yera.keys()), list(yera.values()))
    # 生成折线图
    create_lin('每年注册人数', list(yera.keys()), list(yera.values()), '每年注册人数')
    bar.render(path='detail\注册人数划分_年.html')


# 每个月注册人数
def create_bar_month():
    sql = "select regtime from user_info order by regtime"
    data = get_all_data(sql)
    months = {'01': 0,
              '02': 0,
              '03': 0,
              '04': 0,
              '05': 0,
              '06': 0,
              '07': 0,
              '08': 0,
              '09': 0,
              '10': 0,
              '11': 0,
              '12': 0,
              }
    for i in data:
        regTime = i[0][5:7]
        count = months.get(regTime)
        count += 1
        months[regTime] = count
    create_lin('每个月注册人数', list(months.keys()), list(months.values()), '')
    bar = Bar("每个月注册人数", "按月划分")
    bar.add("", list(months.keys()), list(months.values()))
    #生成折线图
    create_lin('注册人数划分_月',list(months.keys()),list(months.values()),'注册人数划分_月')
    bar.render(path='detail\注册人数划分_月.html')  # 生成本地 HTML 文件


# 根据sql获取指定区间内的数据
def get_all_data(sql):
    conn = pymysql.connect(host="localhost", user="root", passwd="Cs123456.", db="acfun", charset="utf8")
    cursor = conn.cursor()
    cursor.execute(sql)
    data = cursor.fetchall()
    cursor.close()
    conn.close()
    return data


# 注册人数与当年活跃人数对比图
def year_2():
    sql = "select regtime,lastLoginTime from user_info order by regtime"
    data = get_all_data(sql)
    yera = {}
    for i in data:
        y = i[0][0:4]
        y2 = str(i[1])[0:4]
        if y in yera:
            count = yera.get(y)[0]
            count += 1
            yera[y][0] = count

            if y2 in yera:
                count_2 = yera.get(y2)[1]
                count_2 += 1
                yera[y2][1] = count_2

            else:
                yera[y2] = [0, 0]

        else:
            yera[y] = [0, 0]

    bar = Bar("年注册人数与每年最后一次上线人数", "按年划分")
    bar.add("", [k for k in sorted(yera.keys())], [yera[k][0] for k in sorted(yera.keys())])
    bar.add("", [k for k in sorted(yera.keys())], [yera[k][1] for k in sorted(yera.keys())])

    bar.render(path='detail\每年注册人数与每年最后一次上线人数.html')


# 折线图,若想显示两条或多条,自己处理下,就是多加个add的事情
def create_lin(h_name, k, val, line_name):
    line = Line(h_name)
    line.add(line_name, k, val, mark_point=["average"])
    line.render('detail\%s_折线图.html' % h_name)


#全国地图点状图用到的方法
def geo_formatter(params):
    return params.name + ' : ' + params.value[2]


# map图,指定区间内,全国省用户分布图
def Geo_create():
    sql = "select comeFrom,count(*) from user_info where 1=1 and comeFrom is not NULL and comeFrom !='未知' and comeFrom !='' and lastLoginTime >= '2018-01-01 00:00:00' group by comeFrom order by comeFrom"
    datas = get_all_data(sql)

    city = {}
    country = {}
    for data in datas:
		#数据整理
        b = data[0].find(',')
        s = data[0].encode('utf-8').decode('utf-8').find('市')
        sheng = data[0].encode('utf-8').decode('utf-8').find('省')
        zzq = data[0].encode('utf-8').decode('utf-8').find('自治区')
        if b is not -1:
            res, count = get_city_name(data, b, city)
            # print('b',data[0], '---', res, '-----', count, '----', sheng)
            if res in city:
                count = city[res]
                count += data[1]
                # print(res, '---', count)
                city[res] = count
            else:
                city[res] = data[1]
        elif zzq is not -1:
            res, count = get_city_name(data, zzq, city)
            # print('zzq',data[0], '---', res, '-----', count, '----', sheng)
            if res in city:
                count = city[res]
                count += data[1]
                # print(res, '---', count)
                city[res] = count
            else:
                city[res] = data[1]
        elif sheng is not -1:
            res, count = get_city_name(data, sheng, city)
            # print('sheng',data[0], '---', res, '-----', count, '----', sheng)
            if res in city:
                count = city[res]
                count += data[1]
                # print(res, '---', count)
                city[res] = count
            else:
                city[res] = data[1]
        elif s is not -1:
            res, count = get_city_name(data, b, city)
            # print('s',data[0], '---', res, '-----', count, '----', sheng)
            if res in city:
                count = city[res]
                count += data[1]
                # print(res, '---', count)
                city[res] = count
            else:
                city[res] = data[1]
        else:
            # print(data[0],'------',data[1])
            if data[0] in country:
                count = country[data[0]]
                count += data[1]
            else:
                country[data[0]] = data[1]
#去掉不识别的数据
    del city['海外']
    del country['AFRINIC']
    del country['APNIC']
    del country['RIPE']
    del country['IANA']
    del country['运营商级NAT']
    country['中国'] = 0
    for i in city:
        country['中国'] += city[i]
    f_country = {}
    for i in list(country.keys()):
        f_country[fanyi(i)] = country.pop(i)
    # print(city)
    print(f_country)
    create_geo('2018截止8月全国Acer省分布情况', '', city, 'detail/2018截止8月全国Acer省分布情况.html', 'china')
    # create_geo('2018截止8月全世界Acer省分布情况', '', f_country, 'detail/2018截止8月世界Acer省分布情况.html', 'world')

#原本打算做世界地图的,所以做了中文翻译的请求
def fanyi(content):
    url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&sessionFrom=http://fanyi.youdao.com/'
    # 有道翻译查询入口
    data = {  # 表单数据
        'i': content,
        'from': 'AUTO',
        'to': 'AUTO',
        'smartresult': 'dict',
        'client': 'fanyideskweb',
        'doctype': 'json',
        'version': '2.1',
        'keyfrom': 'fanyi.web',
        'action': 'FY_BY_CLICKBUTTION',
        'typoResult': 'false'
    }

    data = urllib.parse.urlencode(data).encode('utf-8')
    # 对POST数据进行编码

    response = urllib.request.urlopen(url, data)
    # 发出POST请求并获取HTTP响应

    html = response.read().decode('utf-8')
    # 获取网页内容,并进行解码解码

    target = json.loads(html)
    # json解析

    return target['translateResult'][0][0]['tgt']

#屏蔽的全国地图的点状图
def create_geo(pname, cname, data, path, map_type):
    # geo = Geo(pname, cname, title_color="#fff", title_pos="center", width=1200, height=600,
    #           background_color="#404a59", )
    # attr, value = geo.cast(data)
    # geo.add("", attr, value, type="heatmap", is_random=True, is_legend_show=False,
    #         maptype=map_type,
    #         tooltip_formatter=geo_formatter,  # 重点在这里,将函数直接传递为参数。
    #         effect_scale=5)
    #
    geo = Geo(
        pname,
        cname,
        title_color="#fff",
        title_pos="center",
        width=1200,
        height=600,
        background_color="#404a59",
    )
    attr, value = geo.cast(data)
    geo.add(
        "",
        attr,
        value,
        type="heatmap",
        maptype=map_type,
        is_visualmap=True,
        visual_range=[0, 300],
        visual_text_color="#fff",
    )

    geo.render(path=path)

#对查询到的城市名称数据进行过滤和数字统计
def get_city_name(data, n_len, city_list):
    res = data[0][0:n_len]
    count = 0
    if res in city_list:
        count = city_list[res]
        count += data[1]
    else:
        count = data[1]

    return res, count


if __name__ == '__main__':
    #create_gender_round()
    #create_bar_month()
    #create_bar_year()
    #year_2()
    Geo_create()

好了。本次统计到此结束。谢谢观看。
pyecharts真的是一个非常方便的数据图形展示工具,我这里只是使用了最简单的几个样板,还有更多更有趣也更科学的关系图形展示,详情请点击:pyecharts中文说明文档

猜你喜欢

转载自blog.csdn.net/qq_38044574/article/details/82847816