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

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

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

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

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

一、拆解逻辑

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

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

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

二、数据获取

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

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

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

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

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

01 | 用户基础数据

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

i. 开发思路

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

ii. 代码实现

python 复制代码
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. 代码实现

python 复制代码
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 到本地就能用。

项目地址:github.com/Trade-Offf/...

执行方法:

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

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

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

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

四、可视化容器(TODO)

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

参考文档:让 web 再次伟大------用 canvaskit 实现超级丝滑的原神地图(已开源)

相关推荐
90后的晨仔8 分钟前
在macOS上无缝整合:为Claude Code配置魔搭社区免费API完全指南
前端
沿着路走到底38 分钟前
JS事件循环
java·前端·javascript
爱笑的眼睛111 小时前
超越 `cross_val_score`:深度解析Scikit-learn交叉验证API的架构、技巧与陷阱
java·人工智能·python·ai
子春一21 小时前
Flutter 2025 可访问性(Accessibility)工程体系:从合规达标到包容设计,打造人人可用的数字产品
前端·javascript·flutter
白兰地空瓶1 小时前
别再只会调 API 了!LangChain.js 才是前端 AI 工程化的真正起点
前端·langchain
smj2302_796826522 小时前
解决leetcode第3782题交替删除操作后最后剩下的整数
python·算法·leetcode
jlspcsdn2 小时前
20251222项目练习
前端·javascript·html
gCode Teacher 格码致知2 小时前
Python基础教学:Python 3中的字符串在解释运行时的内存编码表示-由Deepseek产生
python·内存编码
行走的陀螺仪2 小时前
Sass 详细指南
前端·css·rust·sass
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ2 小时前
React 怎么区分导入的是组件还是函数,或者是对象
前端·react.js·前端框架