Django博客来访人员地域分布大数据可视化---echarts绘图geoip2获取地理位置

Posted 大聪明Smart

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django博客来访人员地域分布大数据可视化---echarts绘图geoip2获取地理位置相关的知识,希望对你有一定的参考价值。

Django博客来访人员地域分布大数据可视化—echarts绘图、geoip2获取地理位置

今天,萌生一个想法。就是想把我的个人博客来访的人员地域分布进行一个可视化作图,并显示在我的留言板上。话不多说,就开始了掉头发的征程。。。。

效果

首先,还是来展示一下效果怎么样吧:

image-20210528204105383

生成的是一份中国地图,这里只统计了国内来访人员。鼠标放在相应的省份会弹出数据(如上所示),人数不同,显示的颜色深度不同。不可以放大缩小等。具体可以去我的博客查看(欢迎留言噢~):

https://www.liboer.top/messages/

echarts作图

这里使用百度的echarts

首先在留言页面先画出一个中国地图分布,先用假数据代替。后边再改为ajax从后端数据库拿数据。

去echarts官网下载两个js文件:echarts.js、echarts.min.js,此外还需要一个js,就是用来话中国地图的china.js

在此,有找不到的可以直接在此下载,我分享一下我的百度云,失效的话评论区联系我。

链接:https://pan.baidu.com/s/12cUE25QsxXTmi-Qu9zPWqw
提取码:9vzg
复制这段内容后打开百度网盘手机App,操作更方便哦

在我的留言页面引入,后用jq操作画图:

# 容器,图片显示的位置
<div id="main" style="width: 600px;height:400px;"></div>


{% block js %}	
	<script src="{% static 'js/echarts.js' %}"></script>
    <script src="{% static 'js/echarts.min.js' %}"></script>
    <script src="{% static 'js/china.js' %}"></script>


    <script>
        var optionMap = {
            backgroundColor: '#FFFFFF',
            backgroundColor: 'transparent',  // 背景透明色
            title: {
                text: '全国来访人员地域分布大数据',
                subtext: '',
                x:'center',
                textStyle:{
                    color: '#CFB53B',
                    fontfamily:'Microsoft YaHei'
                }
            },
            tooltip : {
                trigger: 'item'
            },

            //左侧小导航图标
            visualMap: {
                show : false,
                x: 'left',
                y: 'center',
                splitList: [
                    {start: 500, end:600},{start: 400, end: 500},
                    {start: 300, end: 400},{start: 200, end: 300},
                    {start: 100, end: 200},{start: 0, end: 100},
                ],
                color: ['#5475f5', '#9feaa5', '#85daef','#74e2ca', '#e6ac53', '#9fb5ea']
            },

            //配置属性
            series: [{
                name: '数据',
                type: 'map',
                mapType: 'china',
                roam: true,
                label: {
                    normal: {
                        show: true  //省份名称
                    },
                    emphasis: {
                        show: false
                    }
                },
                data:mydata  //数据
            }]
        };
        //初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        //使用制定的配置项和数据显示图表
        myChart.setOption(optionMap);
    </script>
 {% endblock %}

data数据

[
    {
        "name": "北京",
        "value": 104
    },
    {
        "name": "天津",
        "value": 31
    },
    {
        "name": "上海",
        "value": 432
    },
    {
        "name": "重庆",
        "value": 51
    },
    {
        "name": "河北",
        "value": 15
    },
    {
        "name": "河南",
        "value": 85
    },
    {
        "name": "云南",
        "value": 13
    },
    {
        "name": "辽宁",
        "value": 86
    },
    {
        "name": "黑龙江",
        "value": 22
    },
    {
        "name": "湖南",
        "value": 57
    },
    {
        "name": "安徽",
        "value": 231
    },
    {
        "name": "山东",
        "value": 212
    },
    {
        "name": "新疆",
        "value": 98
    },
    {
        "name": "江苏",
        "value": 561
    },
    {
        "name": "浙江",
        "value": 79
    },
    {
        "name": "江西",
        "value": 67
    },
    {
        "name": "湖北",
        "value": 63
    },
    {
        "name": "广西",
        "value": 16
    },
    {
        "name": "甘肃",
        "value": 65
    },
    {
        "name": "山西",
        "value": 3
    },
    {
        "name": "内蒙古",
        "value": 76
    },
    {
        "name": "陕西",
        "value": 22
    },
    {
        "name": "吉林",
        "value": 22
    },
    {
        "name": "福建",
        "value": 78
    },
    {
        "name": "贵州",
        "value": 189
    },
    {
        "name": "广东",
        "value": 345
    },
    {
        "name": "青海",
        "value": 52
    },
    {
        "name": "西藏",
        "value": 78
    },
    {
        "name": "四川",
        "value": 47
    },
    {
        "name": "宁夏",
        "value": 88
    },
    {
        "name": "海南",
        "value": 89
    },
    {
        "name": "台湾",
        "value": 83
    },
    {
        "name": "香港",
        "value": 33
    },
    {
        "name": "澳门",
        "value": 99
    }
]

此时,在页面中已经显示啦,但是静态的数据。我们要在后端把他动态化。

geoip2获取地理位置

geoip2可以获取ip所在的地理位置,我测试了一下,并不是所有的ip都能正常的得到地理位置,目前没找到好的替代品,先用这个吧。

安装

pip3 install geoip2

geoip2需要一个GeoLite2数据库文件,大家可以自行去官网下载。前边的百度与我也分享了。

# Django获取ip
request.META.get("REMOTE_ADDR")
# 拿到地理位置市
import geoip2.database
from BlogLee import settings
reader = geoip2.database.Reader(settings.GEOIP_PATH)
response = reader.city(ip)
city = response.city.names['zh-CN']
print(city)
# settings.GEOIP_PATH是GeoLite2数据库文件地址
# GEOIP_PATH = os.path.join(BASE_DIR, 'static', 'GeoLite2-City.mmdb')

我的Django博客所有的功能都已经实现,现在又有新的功能需要。我不可能再去查找改动。所以就写个装饰器吧!

此装饰器实现获取ip,拿到地理位置省份。并把数据存储到数据库中。之后把所有的视图中get方法用此装饰器装饰即可。

def ip_addr(func):
    def wrapper(request, *args, **kwargs):
        # print('meta', request.META)

        # print('测试', request.geo_data.ip_address)
        # print('request', request)
        ip = request.META.get("REMOTE_ADDR")
        # print(request.META.get("HTTP_X_FORWARDED_FOR"))
        print(ip)
        provence = provence

        reader = geoip2.database.Reader(settings.GEOIP_PATH)
        # response = reader.city(ip)

        day = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        try:
            # response = reader.city(ip)
            response = reader.city('88.5.237.10')
            city = response.city.names['zh-CN']
            print(city)
            flag = False
            pro = ''
            for k in provence.keys():
                for c in provence[k]:
                    if c == city + '市':
                        if k[-1] == '省':
                            pro = k[:-1]
                        else:
                            pro = k
                        flag = True
                        break
                if flag:
                    break
            print(pro)
            obj = models.Provence.objects.filter(name=pro).first()
            print(obj)
            if obj:
                obj.viewed()
            logs = f'ip正常。\\nip:{ip}\\n访问时间:{day}\\n\\n'
            path = 'uploads' + '/' + 'iplog' + '/' + 'normal_ip' + '.log'
            file_add(path, logs)
        except:
            path = 'uploads' + '/' + 'iplog' + '/' + 'anomaly_ip' + '.log'
            logs = f'ip异常,可能使用了代理。\\nip:{ip}\\n访问时间:{day}\\n\\n'
            file_add(path, logs)
            # print('ip异常')
        # print(response.country.names['zh-CN'], response.city.names['zh-CN'])
        res = func(request, *args, **kwargs)
        return res

    return wrapper

省份数据

{
            "河南省": [
                "郑州市",
                "洛阳市",
                "焦作市",
                "商丘市",
                "信阳市",
                "周口市",
                "鹤壁市",
                "安阳市",
                "濮阳市",
                "驻马店市",
                "南阳市",
                "开封市",
                "漯河市",
                "许昌市",
                "新乡市",
                "济源市",
                "灵宝市",
                "偃师市",
                "邓州市",
                "登封市",
                "三门峡市",
                "新郑市",
                "禹州市",
                "巩义市",
                "永城市",
                "长葛市",
                "义马市",
                "林州市",
                "项城市",
                "汝州市",
                "荥阳市",
                "平顶山市",
                "卫辉市",
                "辉县市",
                "舞钢市",
                "新密市",
                "孟州市",
                "沁阳市",
                "郏县"
            ],
            "安徽省": [
                "合肥市",
                "亳州市",
                "芜湖市",
                "马鞍山市",
                "池州市",
                "黄山市",
                "滁州市",
                "安庆市",
                "淮南市",
                "淮北市",
                "蚌埠市",
                "宿州市",
                "宣城市",
                "六安市",
                "阜阳市",
                "铜陵市",
                "明光市",
                "天长市",
                "宁国市",
                "界首市",
                "桐城市",
                "潜山市"
            ],
            "福建省": [
                "福州市",
                "厦门市",
                "泉州市",
                "漳州市",
                "南平市",
                "三明市",
                "龙岩市",
                "莆田市",
                "宁德市",
                "龙海市",
                "建瓯市",
                "武夷山市",
                "长乐市",
                "福清市",
                "晋江市",
                "南安市",
                "福安市",
                "邵武市",
                "石狮市",
                "福鼎市",
                "建阳市",
                "漳平市",
                "永安市"
            ],
            "甘肃省": [
                "兰州市",
                "白银市",
                "武威市",
                "金昌市",
                "平凉市",
                "张掖市",
                "嘉峪关市",
                "酒泉市",
                "庆阳市",
                "定西市",
                "陇南市",
                "天水市",
                "玉门市",
                "临夏市",
                "合作市",
                "敦煌市",
                "甘南州"
            ],
            "贵州省": [
                "贵阳市",
                "安顺市",
                "遵义市",
                "六盘水市",
                "兴义市",
                "都匀市",
                "凯里市",
                "毕节市",
                "清镇市",
                "铜仁市",
                "赤水市",
                "仁怀市",
                "福泉市"
            ],
            "海南省": [
                "海口市",
                "三亚市",
                "万宁市",
                "文昌市",
                "儋州市",
                "琼海市",
                "东方市",
                "五指山市"
            ],
            "河北省": [
                "石家庄市",
                "保定市",
                "唐山市",
                "邯郸市",
                "邢台市",
                "沧州市",
                "衡水市",
                "廊坊市",
                "承德市",
                "迁安市",
                "鹿泉市",
                "秦皇岛市",
                "南宫市",
                "任丘市",
                "叶城市",
                "辛集市",
                "涿州市",
                "定州市",
                "晋州市",
                "霸州市",
                "黄骅市",
                "遵化市",
                "张家口市",
                "沙河市",
                "三河市",
                "冀州市",
                "武安市",
                "河间市",
                "深州市",
                "新乐市",
                "泊头市",
                "安国市",
                "双滦区",
                "高碑店市"
            ],
            "黑龙江省": [
                "哈尔滨市",
                "伊春市",
                "牡丹江市",
                "大庆市",
                "鸡西市",
                "鹤岗市",
                "绥化市",
                "齐齐哈尔市",
                "黑河市",
                "富锦市",
                "虎林市",
                "密山市",
                "佳木斯市",
                "双鸭山市",
                "海林市",
                "铁力市",
                "北安市",
                "五大连池市",
                "阿城市",
                "尚志市",
                "五常市",
                "安达市",
                "七台河市",
                "绥芬河市",
                "双城市",
                "海伦市",
                "宁安市",
                "讷河市",
                "穆棱市",
                "同江市",
                "肇东市"
            ],
            "湖北省": [
                "武汉市",
                "荆门市",
                "咸宁市",
                "襄阳市",
                "荆州市",
                "黄石市",
                "宜昌市",
                "随州市",
                "鄂州市",
                "孝感市",
                "黄冈市",
                "十堰市",
                "枣阳市",
                "老河口市",
                "恩施市",
                "仙桃市",
                "天门市",
                "钟祥市",
                "潜江市",
                "麻城市",
                "洪湖市",
                "汉川市",
                以上是关于Django博客来访人员地域分布大数据可视化---echarts绘图geoip2获取地理位置的主要内容,如果未能解决你的问题,请参考以下文章

如何将全国各省份人口数据绘制成地域分布图?Python 轻松解决

Django+Echarts实现数据可视化

Python第一个微信小项目

django——文本编辑器

第一个微信小项目

大数据应用实例