• 俺把所有粉丝显示在地图上啦~【详细教程+完整源码】


    🌲小逼叨


    其实昨天发了一篇文章👉【感恩系列】:说点事儿 以及 我把所有的粉丝放到了中国地图上啦~
    这篇文章是自己的第一篇“情感类”文章,里面讲述了自己的一些经历和感受,其实感觉写这类文章还是有点困难的,因为总有很多想表达的情绪,但又怕文章过于冗长无聊,而自己写这类文章没有太多经验(请大家见谅),本应该是纯纯情感,结果贴了代码上去,然后还没说清楚代码的编写思路和过程。
    于是,今儿,我重新写了一篇,纯纯教学。教你们如何获取所有粉丝的IP所属地,并将他们放在中国地图上显示。
    详细步骤,请各位兄弟姐妹们往下看👇

    🌲爬取所有粉丝的IP所属地


    🌴爬者基本素养:网页分析

    网页分析网页分析,没有网页,何来分析,所以我们需要找到我们的目标网页,也就是个人博客的粉丝页

    网页分析分三步走战略

    • 第一步,以鄙人为例,鼠标悬浮在博客头像,点击粉丝。
      在这里插入图片描述

    • 第二步,进入粉丝页后点击键盘的F12(或者点击鼠标右键,点击网页检查)后会弹出一个进行网页分析的窗口,点击窗口上的网络,然后在筛选输入框中输入:get-fans,接着刷新一下页面,即可看到装有粉丝数据的数据包。

      • 注意:如果不出意外的话那就出意外了😜,这时我们可能只看到一个数据包,出现这种情况别慌,鼠标放在页面上滚动即可,这时就会看到有多个数据包冒出。(拿捏了老铁们儿😎)
        在这里插入图片描述
    • 第三步,点击数据包,点击预览,即可看到粉丝的相关数据,关键来了,这些数据中没有我们想要的IP所属地,你说,这咋整。我说,先别急,先分析分析里面有啥。

      • 经过哥的一整套稀里哗啦的分析,真相只有一……(先别逼叨了)其实发现数据包中有两个主要信息:粉丝博客链接、粉丝的id,这些信息有什么用呢?
        在这里插入图片描述
    • 第四步(哈哈哈,被虚晃了吧),又经过哥的一套叽叽喳喳的分析,发现粉丝博客链接中,也就是粉丝的博客主页有我们想要的IP所属地
      在这里插入图片描述

    • 而id呢,id的作用就是获取下一个数据包的所有粉丝信息。通过分析数据包的链接可以发现,数据包中只有两个地方不同:page值和id值,于是再回到数据包本身,每个粉丝都有id,那么哪一个id是下个数据包链接中的id呢?答案是:最后一个粉丝的id(这时候我应该听到掌声雷动了)
      在这里插入图片描述

    🌴源代码

    根据以上稀里哗啦叽叽喳喳的操作,我们来编写代码。
    代码编写思路

    1. 先对网页分析抓到的第一个数据包发送请求,获取到我们想要的博客链接和id值,然后设置一个page值,它的值自增加一,获取到的id值我们只需要最后一个粉丝的id值,最后拼接链接,重新发送请求,再重复以上步骤。
    2. 等获取了所有的博客链接,我们使用多线程的方式对所有博客链接发送请求,获取IP所属地,最后保存在json文件中。

    注意两点:

    1. https://blog.csdn.net/community/home-api/v2/get-fans-list?page=1&pageSize=20&id={id}&noMore=false&blogUsername=,最后的等号后面写上自己的博客名
    2. ‘User-Agent’: ‘’,使用自己的User-Agent哈

    源码如下👇
    (如有错误,请在评论区中指出哦~😁)

    import requests
    import json
    import threading
    from jsonpath import jsonpath
    import re
    import time
    
    
    # 博客名和博客链接
    def fans_data():
        li_name = []    # 存储博客名
        blogUrl = []   # 存储博客链接
        id = 0
        i = 0
        while True:
            if i == 0:  # 如果是第一页的粉丝数据
                url = f'https://blog.csdn.net/community/home-api/v2/get-fans-list?page=1&pageSize=20&id={id}&noMore=false&blogUsername='
            else:
                url = f'https://blog.csdn.net/community/home-api/v2/get-fans-list?page={i+1}&pageSize=20&id={id}&noMore=false&blogUsername='
            try:
                res = requests.get(url, headers=headers)
                json_data = json.loads(res.text)
                # 获取粉丝博客名
                li_name += jsonpath(json_data, '$..username')
                # 获取粉丝博客链接
                blogUrl += jsonpath(json_data, '$..blogUrl')
                # 获取粉丝博客id
                id = jsonpath(json_data, '$..id')[-1]
                print(id)
            except:
                break
            i += 1
            print(f'第{i}页粉丝数据获取成功!')
        return li_name, blogUrl
    
    
    # 获取粉丝的ip所属地
    def fans_area(url):
        res = requests.get(url, headers=headers)
        try:
            area = re.findall('"region":"IP 属地:(.*?)","msg"', res.text)[0]
        except:
            area = ''
        li_area.append(area)
        print('IP所属地获取成功!')
    
    
    # 将粉丝的所属地和博客名保存到json文件中
    def save_json():
        with open('CSDN粉丝信息.json', 'a', newline="", encoding='utf-8') as f:
            for i in range(len(li_name)):
                data = {'name':li_name[i], 'area':li_area[i]}
                # 将字典转换成json数据
                data_str = json.dumps(data, ensure_ascii=False)
                f.write(data_str + ',' + '\n')
        print('CSDN粉丝信息.json 文件保存成功!')
    
    
    if __name__ == '__main__':
        headers = {
            'User-Agent': ''
        }
        li_area = []    # 存储所有粉丝的所属地
        threads = []
        li_name, blogUrl = fans_data()      # 接收粉丝名和博客链接
        print('-----开始获取粉丝所属地-----')
        for i in blogUrl:
            threads.append(threading.Thread(target=fans_area(i)))
        for t in threads:
            t.start()
        save_json()
        print(len(li_name))
    
    • 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

    效果展示👇
    在这里插入图片描述

    🌲数据清洗和保存


    我们主要的目的就是获取所有粉丝的IP所属地并统计各个省份中的所有粉丝数量,然后在中国地图上展示出来。
    于是我们需要对爬取到的信息进行清洗
    具体思路:使用强大的数据分析工具——pandas,通过它统计各个省份中的所有粉丝数量,然后将爬取的IP所属地信息进行清洗,将省、区、市这些词从IP所属地中删除,比如:将广西省清洗为广西。最后将所有统计和清洗的结果保存在json文件中。

    🌴源代码

    源码如下👇
    (如有错误,请在评论区中指出哦~😁)

    import pandas as pd
    import json
    from jsonpath import jsonpath
    
    # 读取CSDN粉丝信息.json的内容
    def read_file():
        li_area = []
        with open('CSDN粉丝信息.json', 'r', encoding='utf-8') as f:
            # 获取信息库中的json数据,并转换为Python字符串
            data = json.load(f)
            # 获取粉丝名字
            fans_name = jsonpath(data, '$..name')
            # 获取粉丝所属IP地址
            fans_area = jsonpath(data, '$..area')
            # 清洗数据
            for i in fans_area:
                if '省' in i or '市' in i:
                    li_area.append(i[:-1])
                else:
                    li_area.append(i)
            return li_area
    
    
    # 清洗数据,统计各个省份中的粉丝数
    def wash_data(area):
        df = pd.DataFrame({'area': area, 'num': [1 for i in range(len(area))]})
        df = df.groupby('area').sum()   # 将粉丝所属地进行分组统计
        df.reset_index(inplace=True)
        fans_area = df['area'].values   # 统计中的所有IP所属地
        area_num = df['num'].values     # 各个所属地中粉丝的数量
        return list(list(i) for i in zip(fans_area, area_num))   # 使用拉链函数将列表包起来
    
    
    # 文件保存
    def save_file():
        with open('ip所属地统计.json', 'a', newline="", encoding='utf-8') as f:
            for i in range(len(province_list)):
                data = {'area':province_list[i][0], 'num':str(province_list[i][1])}
                # 将字典转换成json数据
                data_str = json.dumps(data, ensure_ascii=False)
                f.write(data_str + ',' + '\n')
    
    
    if __name__ == '__main__':
        fans_area = read_file()
        province_list = wash_data(fans_area)
        save_file()
    
    • 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

    🌲绘制地图


    绘制地图所需要用到的模块就是:pyecharts,其貌不扬的可是数据可视化编程中的利器
    下载方式:pip install pyecharts(这都基操啦)
    具体思路:通过读取我们清洗后的数据信息来进行地图的绘制。需要改的相关设置请看下图👇
    在这里插入图片描述
    实现效果如下👇
    (神奇不,鼠标浮动在地图省份上,会出现粉丝对应省份中粉丝的数量)
    在这里插入图片描述

    🌴源代码

    源码如下👇
    (如有错误,请在评论区中指出哦~😁)

    from pyecharts.charts import Map
    from pyecharts import options as opts
    import json
    from jsonpath import jsonpath
    
    
    # 获取ip所属地统计.json中的信息
    def fans_data():
        with open('ip所属地统计.json', 'r', encoding='utf-8') as f:
            data = json.load(f)
            # 获取ip所属地
            area = jsonpath(data, '$..area')
            # 获取数量
            num = jsonpath(data, '$..num')
    
            li_data = list(list(i) for i in zip(area, num))
            return li_data
    
    
    # 绘制地图
    def draw_map(province_list):
        # 将省份和数量输出
        pieces = [
            {'max': 10, 'label': '10以下', 'color': '#32CD99'},
            {'min': 10, 'max': 50, 'label': '10-50', 'color': '#3232CD'},
            {'min': 50, 'max': 100, 'label': '50-100', 'color': '#6B8E23'},
            {'min': 100, 'max': 200, 'label': '100-150', 'color': '#EAEAAE'},
            {'min': 200, 'max': 300, 'label': '200-300', 'color': '#9370DB'},
            {'min': 300, 'max': 400, 'label': '300-400', 'color': '#426F42'},
            {'min': 400, 'max': 500, 'label': '400-500', 'color': '#7F00FF'},
        ]
    
        c = (
            Map(init_opts=opts.InitOpts(width="1000px", height="600px"))  # 可切换主题
                .set_global_opts(
                title_opts=opts.TitleOpts(title="IT工藤新一的各省份CSDN粉丝分布"),
                visualmap_opts=opts.VisualMapOpts(
                    min_=0,
                    max_=500,
                    range_text=['CSDN粉丝数量区间:', ''],  # 分区间
                    is_piecewise=True,  # 定义图例为分段型,默认为连续的图例
                    pos_top="middle",  # 分段位置
                    pos_left="left",
                    orient="vertical",
                    # split_number=10,  # 分成10个区间
                    pieces=pieces
                )
    
            )
                .add("CSDN粉丝分布图", province_list, maptype="china")
                .render("CSDN粉丝分布图.html")
        )
    
    
    if __name__ == '__main__':
        data = fans_data()
        draw_map(data)
    
    • 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

    🌲结束语

    好了,今天就说到这咯~
    如果喜欢这篇文章,记得 点赞👍 收藏🌈 再来一个小小的关注哦💖
    你们的支持就是我前进的最大动力💪
    咱们下次再见👀
    peace~

  • 相关阅读:
    基于opencv,卡尺工具
    中值滤波,均值滤波,高斯滤波,双边滤波,联合双边滤波介绍
    Redis缓存击穿、雪崩、穿透
    数据结构与算法【Java】08---树结构的实际应用
    Qt-OpenCV学习笔记--人脸识别
    渗透测试信息收集方法笔记
    前端错误监控
    6个tips缓解第三方访问风险
    Ubantu opencv安装
    实现微信扫码自动登陆与注册功能
  • 原文地址:https://blog.csdn.net/Oh_Python/article/details/127949363