Github Actions:推送掘金热门文章

478 阅读3分钟

「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

前面说过了 Github Actions 可以用来自定义一些执行步骤,并且支持很多触发方式,比如: 定时任务、git push 等。我们现在来尝试通过它来实现一个定时推送掘金热门文章的功能。

1 爬取掘金热门文章

通过 Chrome 浏览器的检查检查功能,抓取到获取热门的文章的 API 链接是:

https://api.juejin.cn/recommend_api/v1/article/recommend_all_feed?

测试通过 Python 实现一个简单的爬虫:

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"
}

url = "https://api.juejin.cn/recommend_api/v1/article/recommend_all_feed"
payload = {
    "sort_type": 200,
    "limit": 20,
    "cursor": "0",
    "id_type": 2,
    "client_type": 2608
}

res = requests.post(url, json=payload, headers=headers)
data = res.json().get("data", [])

articles = []
for i in data:
    if i["item_type"] == 2:
        title = i["item_info"]["article_info"]["title"]
        url = "https://juejin.cn/post/{}".format(i["item_info"]["article_id"])
    elif i["item_type"] == 14:
        title = i["item_info"]["title"]
        url = i["item_info"]["url"]
    else:
        title = i["item_info"]["article_info"]["title"]
        url = i["item_info"]["article_info"]["url"]
    articles.append({
        "title": title,
        "url": url
    })

输出:

[{'title': ' 来吧,用代码“吸猫” !🏆 技术专题征文第13期投稿开启',
  'url': 'https://juejin.cn/post/7024369534119182367?utm_source=web_feed1&utm_medium=banner&utm_campaign=catcat_2021111'},
 {'title': '[机器学习]认识你的猫', 'url': 'https://juejin.cn/post/7029217562600669221'},
 {'title': 'localStorage灵魂五问。 5M?? 10M !!!',
  'url': 'https://juejin.cn/post/7030585901524713508'},
 {'title': '【灵魂拷问】当面试官问你JavaScript预编译',
  'url': 'https://juejin.cn/post/7030370931478364196'},
 {'title': '2021最后一次更文挑战,玩法升级奖品多,全新体验等你来', 'url': 'https://zjsms.com/RLGH68Y/'},
 {'title': '以自家猫猫为原型,做一款跳跳猫小游戏',
  'url': 'https://juejin.cn/post/7030666347272994823'},
 {'title': '把收藏力拉满,前端 50 个优质 Web 在线资源~',
  'url': 'https://juejin.cn/post/7030572979868139551'},
 {'title': 'IntelliJ IDEA竟然出了可以在云端编码的功能?',
  'url': 'https://juejin.cn/post/7030621203824033799'},
 {'title': '50 行代码 React Hooks 中使用富文本编辑器',
  'url': 'https://juejin.cn/post/7030584414652334093'},
 {'title': '【小Y学算法】⚡️每日LeetCode打卡⚡️——47.存在重复元素',
  'url': 'https://juejin.cn/post/7030418271270600740'},
 {'title': '我与DevUI的开源故事', 'url': 'https://juejin.cn/post/7030414733295484935'},
 {'title': '新手向:前端程序员必学基本技能——调试JS代码',
  'url': 'https://juejin.cn/post/7030584939020042254'},
 {'title': 'web前端大作业--艺术培训机构网页设计(HTML+CSS+JavaScript)【源码分享】',
  'url': 'https://juejin.cn/post/7030588458297098270'},
 {'title': 'Python matplotlib 绘制直方图',
  'url': 'https://juejin.cn/post/7030405486860042276'},
 {'title': '面试官疯了吗,问我为什么浮点数不精确?',
  'url': 'https://juejin.cn/post/7030619927274848287'},
 {'title': 'Flask 入门系列之 response 对象!',
  'url': 'https://juejin.cn/post/7030400306454200333'},
 {'title': '用21张图,把Git 工作原理彻底说清楚',
  'url': 'https://juejin.cn/post/7030409006258585637'},
 {'title': '我去,Java IO 也太上头了,,,',
  'url': 'https://juejin.cn/post/7030599694300479518'},
 {'title': '掘力计划月度榜单|2021年10月Top作者榜公布',
  'url': 'https://juejin.cn/post/7028026854669811749'},
 {'title': '【预热|沸点杯模拟公司挑战赛】',
  'url': 'https://juejin.cn/pin/7030629015060742151?utm_source=web20&utm_medium=banner&utm_campaign=business '},
 {'title': '那些容易混淆的设计模式,了解一下~',
  'url': 'https://juejin.cn/post/7030415720676589581'},
 {'title': '面试官:谈谈你了解的Js正则表达式',
  'url': 'https://juejin.cn/post/7030418904392400926'},
 {'title': '算法:557. 反转字符串中的单词 III',
  'url': 'https://juejin.cn/post/7030388857233211405'}]

有人会问:为啥我输出的 Json 内容这么好看?

这是因为我用了pprint函数

from pprint import pprint
pprint(articles)

Json 内容还是太朴素了,我们来把他转换成 html 页面吧!在 Python 中,可以使用 jinjia 库来通过渲染模板的方式来做。 我们先来定义一个模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
<!--    <title>{% block title %}{% endblock %}</title>-->
</head>
<body>
    <ul>
        {% for article in articles %}
        <li>
            <a href="{{ article.url }}">{{ article.title }}</a>
        </li>
        {% endfor %}
    </ul>
</body>
</html>

可以发现,模板中有一些内容有点像 Python 代码,这就是 Jinja 的优势,可以在在渲染是对数据内容进行一些遍历、条件判断之类的处理。

接下来是将数据与模板融合

from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader("./"))
template = env.get_template("template.html")
with open("hot_article.html", "w") as f:
	f.write(template.render(articles=get_articles()))

最后输出的结果就是:

image.png

2 配置 Github Actions

在项目中创建目录.github/workflows,然后创建一个action.yml:

name: 'juejinG Bot'

on:
  push:
  # 定时每天早上8点40收到推送
  schedule:
    - cron: '40 0 * * *'

jobs:
  bot:
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout codes'
        uses: actions/checkout@v1
      - name: 'prepare'
        run: pip install -r requirements.txt
      - name: 'run bot'
        run: python spider.py
      - name: 'Get Date'
        run: echo "REPORT_DATE=$(TZ=':Asia/Shanghai' date '+%Y-%m-%d %T')" >> $GITHUB_ENV
      - name: 'Send mail'
        uses: dawidd6/action-send-mail@master
        with:
          server_address: smtp.163.com
          server_port: 465
          username: ${{ secrets.MAILUSERNAME }}
          password: ${{ secrets.MAILPASSWORD }}
          subject: Juejin Hot Articles Report (${{env.REPORT_DATE}})
          body: file://hot_articles.html
          to: *******@163.com
          from: GitHub Actions
          content_type: text/html

然后将邮箱的信息配置在 Secret

image.png