6

我是程序员,我用这种方式铭记历史

 3 years ago
source link: https://segmentfault.com/a/1190000038395405
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
:sparkles: War Of Resistance Live : 记录14年抗战的日日夜夜

:sparkles: 开源地址https://github.com/kokohuang/WarOfResistanceLive

:sparkles: 预览地址https://kokohuang.github.io/WarOfResistanceLive

前言

在目前浮躁的互联网环境下,做一件好事不难,难的是连续8年做一件有意义的事。

在微博上有这样一位博主,从2012年7月7日开始,截至到2020年9月2日,@抗战直播 以图文形式,记录了从 1937年7月7日至1945年8月15日 中华民族全面抗战的这段历史。 2980 天,从未间断,平均每天 12 条,累计 35214 篇。

2020年9月18日7时零7分,沉寂了半个月的@抗战直播 恢复更新,他们将继续以图文的形式记录 1931年9月18日至1937年7月7日 这六年的抗战历史。

下一个 6 年,他们已经在路上。

历史是不能被遗忘的。

作为程序员的我,在历史面前,我能做点什么?

除了敬佩@抗战直播 这么多年来的坚持,我更想做一点自己力所能及且有意义的事情。

在得到博主@抗战直播 的允许与支持后,于是就有了这个项目的诞生。

War Of Resistance Live

├── .github/workflows # 工作流配置文件
├── resources # 微博数据
├── site # 博客源码
└── spider # 微博爬虫

WarOfResistanceLive 是一个主要由 Python 爬虫 + Hexo 博客 + Github Actions 持续集成服务组成的开源项目,开源在 GitHub 上,并且部署于 Github Pages 。目前包含以下功能:

RSS
Github Actions

接下来,我将简单的给大家介绍该项目的一些核心逻辑与实现。

Python 爬虫

该项目使用的爬虫是基于 weibo-crawler 项目的简化及修改实现( 仅供研究使用 ),感谢作者 dataabc

实现原理

  • 通过访问手机版的微博绕过其登录验证,可查看某个博主的大部分微博数据,如: https://m.weibo.cn/u/2896390104
  • 通过开发者工具查看得知,通过 json 接口 https://m.weibo.cn/api/container/getIndex 即可获取微博数据列表:

    def get_json(self, params):
        """获取网页中json数据"""
        url = 'https://m.weibo.cn/api/container/getIndex?'
        r = requests.get(url,
                         params=params,
                         headers=self.headers,
                         verify=False)
        return r.json()

如何使用

安装依赖:

pip3 install -r requirements.txt

使用:

python weibo.py

注意事项

cookie

更多内容可查看 weibo-crawler

Hexo

经过了一番的抉择,最终选择 Hexo + Next 主题作为本项目的博客框架。

Hexo 是一款基于 Node.js 的静态博客框架,依赖少易于安装使用,可以方便的生成静态网页托管在 GitHub Pages 上,还有丰富的主题可供挑选。关于如何安装使用 Hexo 可详细查看官方文档: https://hexo.io/zh-cn/docs/

那么,如何实现 RSS 订阅功能呢?

得益于 Hexo 丰富的插件功能, hexo-generator-feed 可以很方便的帮我们实现。

首先,在博客根目录下安装该插件:

$ npm install hexo-generator-feed --save

接着,在博客根目录下的 _config.yml 文件中添加相关配置:

feed:
  enable: true # 是否启用插件
  type: atom # Feed的类型,支持 atom 和 rss2,默认 atom
  path: atom.xml # 生成文件的路径
  limit: 30 # 生成最大文章数,如果为 0 或 false 则生成所有的文章
  content: true # 如果为 true 则展示文章所有内容
  content_limit: # 文章展示的内容长度,仅当 content 为 false 有效
  order_by: -date # 按照日期排序
  template: # 自定义模板路径

最后,在主题根目录下的 _config.yml 文件中添加 RSS 订阅入口:

menu:
  RSS: /atom.xml || fa fa-rss # atom.xml文件路径地址和图标设置

这样,我们就可以为自己的博客添加 RSS 订阅功能。 WarOfResistanceLive 的订阅地址为:

https://kokohuang.github.io/WarOfResistanceLive/atom.xml

Github Actions 持续集成

Github Actions 是由 Github2018年10月 推出的持续集成服务,在此之前,我们可能更多的使用 Travis CI 来实现持续集成服务。以我个人的感觉来看, Github Actions 功能非常强大,比 Travis CI 的可玩性更高, Github Actions 拥有丰富的 action 市场,将这些 action 组合起来,我们就可以很简单的完成很多很有趣的事情。

我们先来看看 Github Actions 的一些基本概念:

  • workflow :工作流程。即持续集成一次运行的过程。该文件存放于仓库的 .github/workflows 目录中,可包含多个;
  • job :任务。一个 workflow 可包含一个或多个 jobs ,即代表一次集成的运行,可完成一个或多个任务;
  • step :步骤。一个 job 由多个 step 组成,即代表完成一个任务需要哪些步骤;
  • action :动作。每个 step 里面可包含一个或多个 action ,即代表一个步骤内,可执行多个 action 动作。

了解了 Github Actions 的这些基本概念后,我们来看看 WarOfResistanceLive 的持续集成服务是怎样实现的,以下是本项目使用的 workflow 完整实现:

# workflow 的名称
name: Spider Bot

# 设置时区
env:
  TZ: Asia/Shanghai

# 设置工作流触发方式.
on:
  # 定时触发,在 8:00-24:00 间每隔 2 小时更新一次(https://crontab.guru)
  # 由于 cron 设定的时间为 UTC 时间,所以 +8 即为北京时间
  schedule:
    - cron: "0 0-16/2 * * *"

  # 允许手动触发 Actions
  workflow_dispatch:

jobs:
  build:
    # 使用 ubuntu-latest 作为运行环境
    runs-on: ubuntu-latest

    # 将要执行的任务序列
    steps:
      # 检出仓库
      - name: Checkout Repository
        uses: actions/checkout@v2

      # 设置 Python 环境
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: "3.x"

      # 缓存 pip 依赖
      - name: Cache Pip Dependencies
        id: pip-cache
        uses: actions/cache@v2
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('./spider/requirements.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-
      
      # 安装 pip 依赖
      - name: Install Pip Dependencies
        working-directory: ./spider
        run: |
          python -m pip install --upgrade pip
          pip install flake8 pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

      # 运行爬虫脚本
      - name: Run Spider Bot
        working-directory: ./spider  # 指定工作目录,仅对 run 命令生效
        run: python weibo.py

      # 获取系统当前时间
      - name: Get Current Date
        id: date
        run: echo "::set-output name=date::$(date +'%Y-%m-%d %H:%M')"

      # 提交修改
      - name: Commit Changes
        uses: EndBug/add-and-commit@v5
        with:
          author_name: Koko Huang
          author_email: [email protected]
          message: "已同步最新数据(${{steps.date.outputs.date}})"
          add: "./"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      # 推送远端
      - name: Push Changes
        uses: ad-m/github-push-action@master
        with:
          branch: main
          github_token: ${{ secrets.GITHUB_TOKEN }}

      # 设置 Node.js 环境
      - name: Use Node.js 12.x
        uses: actions/setup-node@v1
        with:
          node-version: "12.x"

      # 缓存 NPM 依赖
      - name: Cache NPM Dependencies
        id: npm-cache
        uses: actions/cache@v2
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('./site/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      # 安装 NPM 依赖
      - name: Install NPM Dependencies
        working-directory: ./site
        run: npm install

      # 构建 Hexo
      - name: Build Hexo
        working-directory: ./site # 指定工作目录,仅对 run 命令生效
        run: npm run build

      # 发布 Github Pages
      - name: Deploy Github Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./site/public # 指定待发布的路径地址
          publish_branch: gh-pages # 指定远程分支名称

workflow 文件的配置字段非常多,配置文件中也给出了详细的注释。接下来,我们主要看下以下几个比较重要的配置:

工作流的触发方式

# 设置工作流触发方式.
on:
  # 定时触发,在 8:00-24:00 间每隔 2 小时更新一次(https://crontab.guru)
  # 由于 cron 设定的时间为 UTC 时间,所以 +8 即为北京时间
  schedule:
    - cron: "0 0-16/2 * * *"

  # 允许手动触发工作流程
  workflow_dispatch:

我们可以使用 on 工作流程语法配置工作流程为一个或多个事件运行。支持自动与手动两种方式触发。 schedule 事件允许我们在计划的时间触发工作流程,我们可以使用 POSIX cron 语法 来安排工作流程在特定的时间运行。

计划任务语法有五个字段,中间用空格分隔,每个字段代表一个时间单位:

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
│ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
│ │ │ │ │                                   
│ │ │ │ │
│ │ │ │ │
* * * * *

我们可以使用 https://crontab.guru 来生成计划任务语法,你也可以查看更多的 crontab guru 示例

另外,我们还可以通过配置 workflow_dispatchrepository_dispatch 字段来实现手动触发工作流程。

on 字段也可以配置为 push ,即仓库有 push 操作时则触发工作流的执行,详细的触发工作流配置可以查看 配置工作流程事件

步骤序列

从配置文件中我们可以看到,该项目的一次持续集成的运行包含了以下步骤:

3mqIbaM.jpg!mobile

检出仓库 --> 设置 Python 环境 --> 缓存 pip 依赖 --> 安装 pip 依赖 --> 运行爬虫脚本 --> 获取当前时间 --> 提交修改 --> 推送远端 --> 设置 Node.js 环境 --> 缓存 NPM 依赖 --> 安装 NPM 依赖 --> 构建 Hexo --> 发布 Github Pages

本项目的 workflow 主要有以下几个要点:

  • 运行环境 :整个工作流运行在虚拟环境 ubuntu-latest 。还可以指定其他虚拟环境,如 Windows ServermacOS 等;
  • 缓存依赖 :通过对依赖的缓存,可提升安装相关依赖的速度。具体使用可查看: 缓存依赖项以加快工作流程
  • 获取当前时间 :后续 提交修改 步骤中的 commit message 中使用到了该步骤中获取到当前时间,这里就使用到了 step 上下文 的相关概念,我们可以为 step 指定一个 id ,后续 step 中我们就可以通过 steps.<step id>.outputs 来获取已经运行的步骤相关信息;
  • 构建 Hexo :即执行 hexo generate 命令生成静态网页;
  • 工作流程中的身份验证 :提交推送及发布步骤需要进行身份验证。 GitHub 提供一个令牌,可用于代表 GitHub Actions 进行身份验证。我们所需要做的就是创建一个命名为 GITHUB_TOKEN 的令牌。具体步骤如下: Settings --> Developer settings --> Personal access tokens --> Generate new token ,命名为 GITHUB_TOKEN ,并勾选中你所需要的的权限,然后就可以在 step 中通过使用 ${{ secrets.GITHUB_TOKEN }} 进行身份验证。

更多 Action 可在 Github 官方市场 查看。

结语

最后,引用博主@抗战直播 的一段话:

“我们直播抗战,并非为了鼓动仇恨等负面的情绪,而是想适度唤起遗忘,当我们时刻牢记祖辈们蒙受的苦难、恐惧和屈辱时;当我们体味祖辈们是如何在国家民族危亡之际抛弃前嫌,实现民族和解时,当我们目睹着祖辈们是如何从容慷慨的走向死亡,以身体为这个国家献祭之时,相信我们对于现实将有更加成熟和理性的思考。”

铭记历史,砥砺奋进。

勿忘国耻,吾辈自强。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK