头图:https://cdn.naraku.cn/imgs/Github_CVE_Wechat-0.jpg
摘要:公众号上看到的小脚本,拿下来做了一些修改,当Python练手啦~

前言

最近在@洛米唯熊公众号中看到一篇对Github新CVE的监控并推送到微信的文章,其结合Github的API获取CVE的相关数据,并通过itchat库推送到微信。但是使用这个库登录的微信时,是不能再在PC端登录微信的,否则会被挤下线。虽然可以使用小号微信来运行脚本,但是感觉还是不方便,因为偶尔小号也可能会需要登录PC端。因此对这部分代码进行了改写,使用Server酱来进行消息的推送。

数据获取

  • 这里进行了一点改动,将获取到的数据通过JSON库转换成字典类型返回,便于后续匹配。并通过CVE-{当前年份}来获取今年的CVE,这样就不用每年都改了(如果这个脚本能跑上几年…)

    1. import json
    2. import requests
    3. def getNews():
    4. year = time.strftime("%Y", time.localtime(time.time()))
    5. try:
    6. api = f"https://api.github.com/search/repositories?q=CVE-{year}&sort=updated"
    7. response = requests.get(api).text
    8. data = json.loads(response)
    9. return data
    10. except Exception as e:
    11. print(e, "Github链接不通")
    12. if __name__ == '__main__':
    13. data = getNews()

    数据解析

  • 获取到的数据使用itemgetter()函数进行关键字排序,通过比较total的变化来判断是否需要推送

    • 参考:Python3 - 通过关键字排序字典列表
      1. from operator import itemgetter
      2. def parseData(index):
      3. item = items[index]
      4. cve_name = item['name']
      5. cve_url = item['svn_url']
      6. cve_des = item['description']
      7. if not cve_des: # 描述为空时会返回None
      8. cve_des = "Null"
      9. content = f"{cve_name}: {cve_url}, Des: {cve_des}"
      10. return content
      11. if __name__ == '__main__':
      12. total = 0 # 初始化为0
      13. data = getNews()
      14. if total != data['total_count']:
      15. total = data['total_count']
      16. items = sorted(data['items'], key=itemgetter('id'), reverse=True) # 根据items中的id进行排序
      17. content = parseData(0) # 返回最新的1条

      推送信息

  • 使用Server酱很轻松就可以实现消息的推送

    1. def sendMsg(content):
    2. send_url = f"https://sc.ftqq.com/{SCKEY}.send"
    3. data = {
    4. "text": "CVE监控提醒",
    5. "desp": content
    6. }
    7. r = requests.post(send_url, data=data)
    8. if __name__ == '__main__':
    9. SCKEY = "Your_SCKEY"
    10. total = 0 # 初始化
    11. data = getDic()
    12. if total != data['total_count']:
    13. total = data['total_count']
    14. items = sorted(data['items'], key=itemgetter('id'), reverse=True) # 根据items中的id进行排序
    15. content = parseData(0) # 返回最新的1条
    16. sendMsg(content)

    推送效果

    获取Github最新CVE - 图1
    获取Github最新CVE - 图2

    完整代码

  • 最后引入time()函数,每隔一段时间运行一次即可

    1. # -*- coding:utf-8 -*-
    2. """
    3. @Author: Naraku
    4. @File: Github_CVE_Wechat.py
    5. """
    6. import time
    7. import json
    8. import requests
    9. from operator import itemgetter
    10. def getNews():
    11. year = time.strftime("%Y", time.localtime(time.time()))
    12. try:
    13. api = f"https://api.github.com/search/repositories?q=CVE-{year}&sort=updated"
    14. response = requests.get(api).text
    15. data = json.loads(response)
    16. return data
    17. except Exception as e:
    18. print(e, "Github链接不通")
    19. def parseData(index):
    20. item = items[index]
    21. cve_name = item['name']
    22. cve_url = item['svn_url']
    23. cve_des = item['description']
    24. if not cve_des: # 描述为空时会返回None
    25. cve_des = "Null"
    26. content = f"{cve_name}: {cve_url}, Des: {cve_des}"
    27. return content
    28. def sendMsg(content):
    29. send_url = f"https://sc.ftqq.com/{SCKEY}.send"
    30. data = {
    31. "text": "CVE监控提醒",
    32. "desp": content
    33. }
    34. r = requests.post(send_url, data=data)
    35. if __name__ == '__main__':
    36. SCKEY = "Your_SCKEY"
    37. total = 0 # 初始化
    38. while True:
    39. data = getNews()
    40. if total != data['total_count']:
    41. total = data['total_count']
    42. items = sorted(data['items'], key=itemgetter('id'), reverse=True) # 根据items中的id进行排序
    43. content = parseData(0) # 返回最新的1条
    44. sendMsg(content)
    45. time.sleep(60)