当前位置:网站首页>我是程序员,我用这种方式铭记历史

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

2020-12-07 19:19:32 InfoQ

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"War Of Resistance Live","attrs":{}},{"type":"text","text":": 记录14年抗战的日日夜夜","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"开源地址","attrs":{}},{"type":"text","text":":","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"https://github.com/kokohuang/WarOfResistanceLive","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"预览地址","attrs":{}},{"type":"text","text":":","attrs":{}},{"type":"link","attrs":{"href":"https://kokohuang.github.io/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"https://kokohuang.github.io/WarOfResistanceLive","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在目前浮躁的互联网环境下,做一件好事不难,难的是连续8年做一件有意义的事。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在微博上有这样一位博主,从2012年7月7日开始,截至到2020年9月2日,","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@抗战直播","attrs":{}}]},{"type":"text","text":" 以图文形式,记录了从","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1937年7月7日至1945年8月15日","attrs":{}},{"type":"text","text":"中华民族全面抗战的这段历史。","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"2980","attrs":{}},{"type":"text","text":" 天,从未间断,平均每天 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"12","attrs":{}},{"type":"text","text":" 条,累计 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"35214","attrs":{}},{"type":"text","text":" 篇。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2020年9月18日7时零7分,沉寂了半个月的 ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@抗战直播","attrs":{}}]},{"type":"text","text":" 恢复更新,他们将继续以图文的形式记录","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1931年9月18日至1937年7月7日","attrs":{}},{"type":"text","text":"这六年的抗战历史。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下一个 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"6","attrs":{}},{"type":"text","text":" 年,他们已经在路上。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"历史是不能被遗忘的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作为程序员的我,在历史面前,我能做点什么?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除了敬佩 ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@抗战直播","attrs":{}}]},{"type":"text","text":" 这么多年来的坚持,我更想做一点自己力所能及且有意义的事情。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在得到博主 ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@抗战直播","attrs":{}}]},{"type":"text","text":" 的允许与支持后,于是就有了这个项目的诞生。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"War Of Resistance Live","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"├── .github/workflows # 工作流配置文件\n├── resources # 微博数据\n├── site # 博客源码\n└── spider # 微博爬虫","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"WarOfResistanceLive","attrs":{}}]},{"type":"text","text":" 是一个主要由 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Python","attrs":{}}],"attrs":{}},{"type":"text","text":" 爬虫 + ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" 博客 + ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":"持续集成服务组成的开源项目,开源在 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub","attrs":{}}],"attrs":{}},{"type":"text","text":" 上,并且部署于 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Pages","attrs":{}}],"attrs":{}},{"type":"text","text":"。目前包含以下功能:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每日定时自动同步更新数据","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查看博主目前所有的微博数据","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":"订阅功能","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基于","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":"的持续集成服务","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"...","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下来,我将简单的给大家介绍该项目的一些核心逻辑与实现。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Python 爬虫","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"该项目使用的爬虫是基于 ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/dataabc/weibo-crawler","title":""},"content":[{"type":"text","text":"weibo-crawler","attrs":{}}]},{"type":"text","text":" 项目的简化及修改实现(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"仅供研究使用","attrs":{}},{"type":"text","text":"),感谢作者 [dataabc](https://github.com/dataabc)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"实现原理","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过访问手机版的微博绕过其登录验证,可查看某个博主的大部分微博数据,如:","attrs":{}},{"type":"link","attrs":{"href":"https://m.weibo.cn/u/2896390104","title":""},"content":[{"type":"text","text":"https://m.weibo.cn/u/2896390104","attrs":{}}]}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过开发者工具查看得知,通过 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"json","attrs":{}}],"attrs":{}},{"type":"text","text":" 接口 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"https://m.weibo.cn/api/container/getIndex","attrs":{}}],"attrs":{}},{"type":"text","text":" 即可获取微博数据列表:","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" ```python","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" def get_json(self, params):","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" \"\"\"获取网页中json数据\"\"\"","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" url = 'https://m.weibo.cn/api/container/getIndex?'","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" r = requests.get(url,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" params=params,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" headers=self.headers,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" verify=False)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" return r.json()","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" ```","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"如何使用","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"安装依赖:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"pip3 install -r requirements.txt","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"python weibo.py","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"注意事项","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"速度过快容易被系统限制:可通过加入随机等待逻辑,可降低被系统限制的风险;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"无法获取全部微博数据:可通过添加 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"cookie","attrs":{}}],"attrs":{}},{"type":"text","text":" 逻辑获取全部数据;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"更多内容可查看 ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/dataabc/weibo-crawler","title":""},"content":[{"type":"text","text":"weibo-crawler","attrs":{}}]},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Hexo","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"经过了一番的抉择,最终选择 ","attrs":{}},{"type":"link","attrs":{"href":"https://hexo.io/zh-cn/","title":""},"content":[{"type":"text","text":"Hexo","attrs":{}}]},{"type":"text","text":" + [Next](https://github.com/theme-next/hexo-theme-next) 主题作为本项目的博客框架。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" 是一款基于 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Node.js","attrs":{}}],"attrs":{}},{"type":"text","text":" 的静态博客框架,依赖少易于安装使用,可以方便的生成静态网页托管在 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub Pages","attrs":{}}],"attrs":{}},{"type":"text","text":" 上,还有丰富的主题可供挑选。关于如何安装使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" 可详细查看官方文档:","attrs":{}},{"type":"link","attrs":{"href":"https://hexo.io/zh-cn/docs/","title":""},"content":[{"type":"text","text":"https://hexo.io/zh-cn/docs/","attrs":{}}]},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那么,如何实现 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":" 订阅功能呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"得益于 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" 丰富的插件功能,","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/hexojs/hexo-generator-feed","title":""},"content":[{"type":"text","text":"hexo-generator-feed","attrs":{}}]},{"type":"text","text":" 可以很方便的帮我们实现。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先,在博客根目录下安装该插件:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"$ npm install hexo-generator-feed --save","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着,在博客根目录下的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_config.yml","attrs":{}}],"attrs":{}},{"type":"text","text":" 文件中添加相关配置:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"feed:\n enable: true # 是否启用插件\n type: atom # Feed的类型,支持 atom 和 rss2,默认 atom\n path: atom.xml # 生成文件的路径\n limit: 30 # 生成最大文章数,如果为 0 或 false 则生成所有的文章\n content: true # 如果为 true 则展示文章所有内容\n content_limit: # 文章展示的内容长度,仅当 content 为 false 有效\n order_by: -date # 按照日期排序\n template: # 自定义模板路径","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最后,在主题根目录下的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_config.yml","attrs":{}}],"attrs":{}},{"type":"text","text":" 文件中添加 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":" 订阅入口:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"menu:\n RSS: /atom.xml || fa fa-rss # atom.xml文件路径地址和图标设置","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这样,我们就可以为自己的博客添加 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":" 订阅功能。","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"WarOfResistanceLive","attrs":{}}]},{"type":"text","text":" 的订阅地址为:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"https://kokohuang.github.io/WarOfResistanceLive/atom.xml","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Github Actions 持续集成","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" 是由 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github","attrs":{}}],"attrs":{}},{"type":"text","text":" 于 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"2018年10月","attrs":{}}],"attrs":{}},{"type":"text","text":" 推出的持续集成服务,在此之前,我们可能更多的使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Travis CI","attrs":{}}],"attrs":{}},{"type":"text","text":" 来实现持续集成服务。以我个人的感觉来看,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" 功能非常强大,比 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Travis CI","attrs":{}}],"attrs":{}},{"type":"text","text":" 的可玩性更高,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" 拥有丰富的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":" 市场,将这些 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":" 组合起来,我们就可以很简单的完成很多很有趣的事情。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们先来看看","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" 的一些基本概念:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"workflow","attrs":{}},{"type":"text","text":":工作流程。即持续集成一次运行的过程。该文件存放于仓库的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":".github/workflows","attrs":{}}],"attrs":{}},{"type":"text","text":" 目录中,可包含多个;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"job","attrs":{}},{"type":"text","text":":任务。一个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" 可包含一个或多个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"jobs","attrs":{}}],"attrs":{}},{"type":"text","text":",即代表一次集成的运行,可完成一个或多个任务;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"step","attrs":{}},{"type":"text","text":":步骤。一个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"job","attrs":{}}],"attrs":{}},{"type":"text","text":" 由多个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" 组成,即代表完成一个任务需要哪些步骤;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"action","attrs":{}},{"type":"text","text":":动作。每个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" 里面可包含一个或多个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":",即代表一个步骤内,可执行多个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":" 动作。","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"了解了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" 的这些基本概念后,我们来看看 ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"WarOfResistanceLive","attrs":{}}]},{"type":"text","text":" 的持续集成服务是怎样实现的,以下是本项目使用的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" 完整实现:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"# workflow 的名称\nname: Spider Bot\n\n# 设置时区\nenv:\n TZ: Asia/Shanghai\n\n# 设置工作流触发方式.\non:\n # 定时触发,在 8:00-24:00 间每隔 2 小时更新一次(https://crontab.guru)\n # 由于 cron 设定的时间为 UTC 时间,所以 +8 即为北京时间\n schedule:\n - cron: \"0 0-16/2 * * *\"\n\n # 允许手动触发 Actions\n workflow_dispatch:\n\njobs:\n build:\n # 使用 ubuntu-latest 作为运行环境\n runs-on: ubuntu-latest\n\n # 将要执行的任务序列\n steps:\n # 检出仓库\n - name: Checkout Repository\n uses: actions/checkout@v2\n\n # 设置 Python 环境\n - name: Setup Python\n uses: actions/setup-python@v2\n with:\n python-version: \"3.x\"\n\n # 缓存 pip 依赖\n - name: Cache Pip Dependencies\n id: pip-cache\n uses: actions/cache@v2\n with:\n path: ~/.cache/pip\n key: ${{ runner.os }}-pip-${{ hashFiles('./spider/requirements.txt') }}\n restore-keys: |\n ${{ runner.os }}-pip-\n \n # 安装 pip 依赖\n - name: Install Pip Dependencies\n working-directory: ./spider\n run: |\n python -m pip install --upgrade pip\n pip install flake8 pytest\n if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n\n # 运行爬虫脚本\n - name: Run Spider Bot\n working-directory: ./spider # 指定工作目录,仅对 run 命令生效\n run: python weibo.py\n\n # 获取系统当前时间\n - name: Get Current Date\n id: date\n run: echo \"::set-output name=date::$(date +'%Y-%m-%d %H:%M')\"\n\n # 提交修改\n - name: Commit Changes\n uses: EndBug/add-and-commit@v5\n with:\n author_name: Koko Huang\n author_email: huangjianke@vip.163.com\n message: \"已同步最新数据(${{steps.date.outputs.date}})\"\n add: \"./\"\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n # 推送远端\n - name: Push Changes\n uses: ad-m/github-push-action@master\n with:\n branch: main\n github_token: ${{ secrets.GITHUB_TOKEN }}\n\n # 设置 Node.js 环境\n - name: Use Node.js 12.x\n uses: actions/setup-node@v1\n with:\n node-version: \"12.x\"\n\n # 缓存 NPM 依赖\n - name: Cache NPM Dependencies\n id: npm-cache\n uses: actions/cache@v2\n with:\n path: ~/.npm\n key: ${{ runner.os }}-node-${{ hashFiles('./site/package-lock.json') }}\n restore-keys: |\n ${{ runner.os }}-node-\n\n # 安装 NPM 依赖\n - name: Install NPM Dependencies\n working-directory: ./site\n run: npm install\n\n # 构建 Hexo\n - name: Build Hexo\n working-directory: ./site # 指定工作目录,仅对 run 命令生效\n run: npm run build\n\n # 发布 Github Pages\n - name: Deploy Github Pages\n uses: peaceiris/actions-gh-pages@v3\n with:\n github_token: ${{ secrets.GITHUB_TOKEN }}\n publish_dir: ./site/public # 指定待发布的路径地址\n publish_branch: gh-pages # 指定远程分支名称","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" 文件的配置字段非常多,配置文件中也给出了详细的注释。接下来,我们主要看下以下几个比较重要的配置:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"工作流的触发方式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"# 设置工作流触发方式.\non:\n # 定时触发,在 8:00-24:00 间每隔 2 小时更新一次(https://crontab.guru)\n # 由于 cron 设定的时间为 UTC 时间,所以 +8 即为北京时间\n schedule:\n - cron: \"0 0-16/2 * * *\"\n\n # 允许手动触发工作流程\n workflow_dispatch:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"on","attrs":{}}],"attrs":{}},{"type":"text","text":" 工作流程语法配置工作流程为一个或多个事件运行。支持自动与手动两种方式触发。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"schedule","attrs":{}}],"attrs":{}},{"type":"text","text":" 事件允许我们在计划的时间触发工作流程,我们可以使用 ","attrs":{}},{"type":"link","attrs":{"href":"https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag2025_07","title":""},"content":[{"type":"text","text":"POSIX cron 语法","attrs":{}}]},{"type":"text","text":" 来安排工作流程在特定的时间运行。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"计划任务语法有五个字段,中间用空格分隔,每个字段代表一个时间单位:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"┌───────────── minute (0 - 59)\n│ ┌───────────── hour (0 - 23)\n│ │ ┌───────────── day of the month (1 - 31)\n│ │ │ ┌───────────── month (1 - 12 or JAN-DEC)\n│ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)\n│ │ │ │ │ \n│ │ │ │ │\n│ │ │ │ │\n* * * * *","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以使用 ","attrs":{}},{"type":"link","attrs":{"href":"https://crontab.guru","title":""},"content":[{"type":"text","text":"https://crontab.guru","attrs":{}}]},{"type":"text","text":" 来生成计划任务语法,你也可以查看更多的 [crontab guru 示例](https://crontab.guru/examples.html)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外,我们还可以通过配置 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow_dispatch","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"repository_dispatch","attrs":{}}],"attrs":{}},{"type":"text","text":"字段来实现手动触发工作流程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"on","attrs":{}}],"attrs":{}},{"type":"text","text":" 字段也可以配置为 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"push","attrs":{}}],"attrs":{}},{"type":"text","text":",即仓库有 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"push","attrs":{}}],"attrs":{}},{"type":"text","text":" 操作时则触发工作流的执行,详细的触发工作流配置可以查看 ","attrs":{}},{"type":"link","attrs":{"href":"https://docs.github.com/cn/free-pro-team@latest/actions/reference/events-that-trigger-workflows#配置工作流程事件","title":""},"content":[{"type":"text","text":"配置工作流程事件","attrs":{}}]},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"步骤序列","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从配置文件中我们可以看到,该项目的一次持续集成的运行包含了以下步骤:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c9/c9e9f5749753b67a57fd516b989c4978.jpeg","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"检出仓库 --> 设置 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Python","attrs":{}}],"attrs":{}},{"type":"text","text":" 环境 --> 缓存 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"pip","attrs":{}}],"attrs":{}},{"type":"text","text":" 依赖 --> 安装 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"pip","attrs":{}}],"attrs":{}},{"type":"text","text":" 依赖 --> 运行爬虫脚本 --> 获取当前时间 --> 提交修改 --> 推送远端 --> 设置 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Node.js","attrs":{}}],"attrs":{}},{"type":"text","text":" 环境 --> 缓存 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"NPM","attrs":{}}],"attrs":{}},{"type":"text","text":" 依赖 --> 安装 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"NPM","attrs":{}}],"attrs":{}},{"type":"text","text":" 依赖 --> 构建 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" --> 发布 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Pages","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本项目的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" 主要有以下几个要点:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"运行环境","attrs":{}},{"type":"text","text":":整个工作流运行在虚拟环境 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ubuntu-latest","attrs":{}}],"attrs":{}},{"type":"text","text":"。还可以指定其他虚拟环境,如 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Windows Server","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"macOS","attrs":{}}],"attrs":{}},{"type":"text","text":" 等;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"缓存依赖","attrs":{}},{"type":"text","text":":通过对依赖的缓存,可提升安装相关依赖的速度。具体使用可查看:","attrs":{}},{"type":"link","attrs":{"href":"https://docs.github.com/cn/free-pro-team@latest/actions/guides/caching-dependencies-to-speed-up-workflows","title":""},"content":[{"type":"text","text":"缓存依赖项以加快工作流程","attrs":{}}]},{"type":"text","text":";","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"获取当前时间","attrs":{}},{"type":"text","text":":后续","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"提交修改","attrs":{}},{"type":"text","text":"步骤中的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"commit message","attrs":{}}],"attrs":{}},{"type":"text","text":" 中使用到了该步骤中获取到当前时间,这里就使用到了 ","attrs":{}},{"type":"link","attrs":{"href":"https://docs.github.com/cn/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions#steps-上下文","title":""},"content":[{"type":"text","text":"step 上下文","attrs":{}}]},{"type":"text","text":" 的相关概念,我们可以为 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" 指定一个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"id","attrs":{}}],"attrs":{}},{"type":"text","text":",后续 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" 中我们就可以通过 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"steps..outputs","attrs":{}}],"attrs":{}},{"type":"text","text":" 来获取已经运行的步骤相关信息;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"**构建 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":"**:即执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"hexo generate","attrs":{}}],"attrs":{}},{"type":"text","text":" 命令生成静态网页;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"工作流程中的身份验证","attrs":{}},{"type":"text","text":":提交推送及发布步骤需要进行身份验证。","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub","attrs":{}}],"attrs":{}},{"type":"text","text":" 提供一个令牌,可用于代表 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" 进行身份验证。我们所需要做的就是创建一个命名为 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GITHUB_TOKEN","attrs":{}}],"attrs":{}},{"type":"text","text":" 的令牌。具体步骤如下:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Settings","attrs":{}}],"attrs":{}},{"type":"text","text":" --> ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Developer settings","attrs":{}}],"attrs":{}},{"type":"text","text":" --> ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Personal access tokens","attrs":{}}],"attrs":{}},{"type":"text","text":" --> ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Generate new token","attrs":{}}],"attrs":{}},{"type":"text","text":",命名为 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GITHUB_TOKEN","attrs":{}}],"attrs":{}},{"type":"text","text":" ,并勾选中你所需要的的权限,然后就可以在 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" 中通过使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"${{ secrets.GITHUB_TOKEN }}","attrs":{}}],"attrs":{}},{"type":"text","text":" 进行身份验证。","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"更多 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Action","attrs":{}}],"attrs":{}},{"type":"text","text":" 可在 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github","attrs":{}}],"attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/marketplace?type=actions","title":""},"content":[{"type":"text","text":"官方市场","attrs":{}}]},{"type":"text","text":" 查看。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"结语","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最后,引用博主 ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@抗战直播","attrs":{}}]},{"type":"text","text":" 的一段话:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“我们直播抗战,并非为了鼓动仇恨等负面的情绪,而是想适度唤起遗忘,当我们时刻牢记祖辈们蒙受的苦难、恐惧和屈辱时;当我们体味祖辈们是如何在国家民族危亡之际抛弃前嫌,实现民族和解时,当我们目睹着祖辈们是如何从容慷慨的走向死亡,以身体为这个国家献祭之时,相信我们对于现实将有更加成熟和理性的思考。”","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"铭记历史,砥砺奋进。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"勿忘国耻,吾辈自强。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/9608b38aab533ecb152fc6371?utm_source=rss&utm_medium=article