前端可视化 - 赛博斗蛐蛐之群雄割据图(一)

发布于:2024-04-25 ⋅ 阅读:(11) ⋅ 点赞:(0)

前段时间玩「信长之野望·新生」比较上头,特别是开局时候的地图我很喜欢。

各种大名、城池、武将等数据摆放在那里,给赛博斗蛐蛐增添了无尽遐想。所以就有了这样一个念头,把我掘金中关注的朋友一些数值获取到,然后通过地图可视化的方式写一个群雄割据图。

完成这个项目后,我计划将其开源到Github。至于为什么要这么做?

"Just for fun" :创建一个数字世界,像古代英雄争霸割据一样类比社区活跃度,顺便给自己点账号运营动力与趣味性,毕竟今年给自己立了个 Flag:

一、拆解逻辑

首先,核心逻辑经过拆分,比较清晰:拿到数据,实现地图容器,数据映射填入,每天定时更新。

其次,可能需要再锦上添花,实现一些设定逻辑,比如:

  • 掘力值(土地面积)
  • 关注数(兵力值)
  • 名称写个随机颜色映射逻辑(势力颜色)
  • 从评论区拿点有趣点子 ...

二、数据获取

今天是第一篇,所以只基于页面的数据获取开展讨论。

如果我只关注了 5 个人,那其实手动维护数据都可以。

每天点击你主页里,把相关数据 CV 下来更新到数据表里,网站重新部署一下。

但哥们好歹是个工程师,实现方式就别这么 Low 了,况且我本身关注的人也很多,这工作能自动化最好。 以我个人主页为例,需要获取的数据有两类:

  • 用户基础数据:掘力值、关注数、被关注数 ...
  • 关注用户列表:关注了哪些人,这个列表是个动态的

01 | 用户基础数据

用户基础数据相对是比较好获取的,傻瓜一点的方式就是直接抓 html 页面元素值即可:

i. 开发思路

  1. 创建一个 requests 会话
  2. 发起 GET 请求,获取目标网页的内容
  3. 使用 BeautifulSoup 解析获取到的 HTML
  4. 通过 CSS 选择器找到目标元素,提取文本内容
  5. 将数字列表转换为字符串格式并打印

ii. 代码实现

import requests
from bs4 import BeautifulSoup

session = requests.Session()


# 获取关注和关注者数量
def get_followers(url):
    response = session.get(url)
    soup = BeautifulSoup(response.text, "html.parser")

    follow_items = soup.find_all("a", {"class": "follow-item"})
    following = []
    followers = []
    for follow_item_index, follow_item in enumerate(follow_items):
        item_count = int(
            follow_item.find("div", {"class": "item-count"}).get_text().strip()
        )
        if follow_item_index % 2 == 0:
            following.append(item_count)
        else:
            followers.append(item_count)
    following_str = ", ".join(map(str, following))
    followers_str = ", ".join(map(str, followers))
    return following_str, followers_str


# 获取基础数据
def get_baseData(url):
    response = session.get(url)
    soup = BeautifulSoup(response.text, "html.parser")
    baseBlock = soup.find("div", {"class": "block-body"})
    counts = baseBlock.find_all("span", {"class": "count"})
    data = {}
    if len(counts) >= 3:
        data["likes"] = counts[0].get_text().strip()
        data["reads"] = counts[1].get_text().strip()
        data["jueli"] = counts[2].get_text().strip()

    return data


url = "https://juejin.cn/user/1591748568038823"  # 请替换为你关注的作者的页面 URL

following_str, followers_str = get_followers(url)
print(f"following: {following_str}")
print(f"followers: {followers_str}")

baseData = get_baseData(url)
print(baseData)

02 | 关注列表数据

这个难度稍微高一点,因为掘金关注列表有滚动加载,所以需要模拟用户翻页的行为才能获取到全部关注。用 Network 查接口也行,但字段太多不想查了。

有知道实现方式的老哥欢迎评论区分享,大家一起讨论下。

i. 开发思路

  1. 用户输入的 URL
  2. 使用 selenium 库启动 Chrome 浏览器并打开指定的 URL
  3. 通过滚动和检查页面高度变化来加载所有关注用户
  4. 使用 CSS 选择器定位并提取关注用户的信息
  5. 将提取到的用户信息保存到新文件中

ii. 代码实现

import argparse
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By


# 获取用户关注列表(处理加载与翻页)
def get_my_following(url):
    # 设置WebDriver路径
    webdriver_service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=webdriver_service)

    driver.get(url)

    # 滚动页面直到没有新的用户加载
    last_height = driver.execute_script("return document.body.scrollHeight")
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(2)  # 等待新的用户加载
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:  # 如果没有新的用户加载,停止滚动
            break
        last_height = new_height

    following_users = driver.find_elements(By.CSS_SELECTOR, "ul.tag-list a.username")
    following_list = [user.text for user in following_users]

    driver.quit()

    return following_list


# 新建or覆盖,保存用户关注列表
def save_following_to_file(following_list, filename):
    with open(filename, "w") as f:
        for user in following_list:
            f.write(user + "\n")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Get the list of users you are following on Juejin."
    )
    parser.add_argument("url", help="The URL of your following list on Juejin.")
    args = parser.parse_args()

    following_list = get_my_following(args.url)
    length = len(following_list)
    print("关注用户数:", length)

    # 保存关注的用户到文件
    save_following_to_file(following_list, "following.txt")

三、功能封装

python 依赖和环境一个个安装挺麻烦,所以我这里对模块使用做了一层封装。感兴趣的朋友你 pull 到本地就能用。

项目地址:

执行方法:

  • 添加脚本权限: chmod +x install_and_run.sh

clone 仓库后只用执行一次,脚本有了执行权限,你就可以直接运行它,无需再次使用 chmod 命令。

  • 导出关注列表: ./install_and_run.sh (URL-待替换)

其中 URL 是需要导出的关注页,如:https://juejin.cn/user/1591748568038823/following

四、可视化容器(TODO)

下一节实现地图容器,看了这个原神哥的文章,大受启发:

参考文档: