✨ War Of Resistance Live: 记录14年抗战的日日夜夜
在目前浮躁的互联网环境下,作一件好事不难,难的是连续8年作一件有意义的事。python
在微博上有这样一位博主,从2012年7月7日开始,截至到2020年9月2日,@抗战直播 以图文形式,记录了从1937年7月7日至1945年8月15日中华民族全面抗战的这段历史。2980 天,从未间断,平均天天 12 条,累计 35214 篇。git
2020年9月18日7时零7分,沉寂了半个月的 @抗战直播 恢复更新,他们将继续以图文的形式记录1931年9月18日至1937年7月7日这六年的抗战历史。程序员
下一个 6 年,他们已经在路上。github
历史是不能被遗忘的。shell
做为程序员的我,在历史面前,我能作点什么?express
除了敬佩 @抗战直播 这么多年来的坚持,我更想作一点本身力所能及且有意义的事情。npm
在获得博主 @抗战直播 的容许与支持后,因而就有了这个项目的诞生。json
├── .github/workflows # 工做流配置文件 ├── resources # 微博数据 ├── site # 博客源码 └── spider # 微博爬虫
WarOfResistanceLive 是一个主要由 Python
爬虫 + Hexo
博客 + Github Actions
持续集成服务组成的开源项目,开源在 GitHub
上,而且部署于 Github Pages
。目前包含如下功能:
RSS
订阅功能Github Actions
的持续集成服务接下来,我将简单的给你们介绍该项目的一些核心逻辑与实现。
该项目使用的爬虫是基于 weibo-crawler 项目的简化及修改实现(仅供研究使用),感谢做者 dataabc。
经过开发者工具查看得知,经过 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 + 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
于 2018年10月
推出的持续集成服务,在此以前,咱们可能更多的使用 Travis CI
来实现持续集成服务。以我我的的感受来看,Github Actions
功能很是强大,比 Travis CI
的可玩性更高,Github Actions
拥有丰富的 action
市场,将这些 action
组合起来,咱们就能够很简单的完成不少颇有趣的事情。
咱们先来看看Github Actions
的一些基本概念:
.github/workflows
目录中,可包含多个;workflow
可包含一个或多个 jobs
,即表明一次集成的运行,可完成一个或多个任务;job
由多个 step
组成,即表明完成一个任务须要哪些步骤;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: huangjianke@vip.163.com 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_dispatch
和 repository_dispatch
字段来实现手动触发工做流程。
on
字段也能够配置为 push
,即仓库有 push
操做时则触发工做流的执行,详细的触发工做流配置能够查看 配置工做流程事件。
从配置文件中咱们能够看到,该项目的一次持续集成的运行包含了如下步骤:
检出仓库 --> 设置 Python
环境 --> 缓存 pip
依赖 --> 安装 pip
依赖 --> 运行爬虫脚本 --> 获取当前时间 --> 提交修改 --> 推送远端 --> 设置 Node.js
环境 --> 缓存 NPM
依赖 --> 安装 NPM
依赖 --> 构建 Hexo
--> 发布 Github Pages
本项目的 workflow
主要有如下几个要点:
ubuntu-latest
。还能够指定其余虚拟环境,如 Windows Server
、macOS
等;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
官方市场 查看。
最后,引用博主 @抗战直播 的一段话:
“咱们直播抗战,并不是为了鼓动仇恨等负面的情绪,而是想适度唤起遗忘,当咱们时刻牢记祖辈们蒙受的苦难、恐惧和屈辱时;当咱们体味祖辈们是如何在国家民族危亡之际抛弃前嫌,实现民族和解时,当咱们目击着祖辈们是如何从容慷慨的走向死亡,以身体为这个国家献祭之时,相信咱们对于现实将有更加成熟和理性的思考。”
铭记历史,砥砺奋进。
勿忘国耻,吾辈自强。