newsexpress--利用github_actions建立自动运行爬取学校官网通知并自动发送邮件的小玩意

早上起来刷博客, 看到了一个很有意思的东西---Github Actions, 作者利用Github Actions制作了一个定时发送天气邮件的玩意儿, 一下子来了兴趣, 想了一会决定先写个小爬虫试试水~

然后一下午过去了, 目前做成了这个 :

https://github.com/Lincest/newsexpress

效果长这样 :

1592305508508

好啦, 接下来大概介绍下过程吧 :

Github Actions

首先简单介绍下Github Actions这玩意

GitHub Actions 是一个 CI/CD(持续集成/持续部署)工具,但也可用作代码运行环境

官方文档 : https://help.github.com/en/actions

功能非常强大, 文档我也只看了一些最基本的配置方面的内容, 我只用到了其中一点点

我把它理解为一个可以自动执行你放在仓库里项目的东西

配置方法

首先在github下建个仓库, 然后只要你建立这么一条路径以及一个action.yml文件就可以自动触发github actions

1592306046835

关于workflow文件 ( .yml文件 ) 的配置, 这里大概介绍一下 :

1592307289115

这里的on表示执行的时间, 比如我这里是每次push之后和每天的10,21点( 国际事件, 换成北京时间是早上5点和晚上6点 )执行, schedule的设置遵循POSIX cron 语法, 这里 是它的使用方法

1592307401626

这里表示运行的系统为ubuntu最新版, python版本是3.8, 然后安装根目录下的依赖 ( 比如爬虫中的requests和beautifulsoup, 自己是不带的, 需要在运行机里pip安装 )

1592307563111

这里是发送邮件的机制, 我本来用的是163的smtp服务器, 然后下午push了五十多次后IP被封了(((

1592307638171

(我....)

这里的username和password要在setting里自己设置, 具体可以参考官方文档

然后在我写完脚本之后发现一个问题, 就是我的脚本需要依赖于update.txt文件判断信息是否更新, 而每次在处理机上运行的时候它不会帮我更新我的仓库, 所以还得自己写github的update方案:

百度了好大一圈, 最后这么实现了 :

1592307840237

注意这里的uses和上面的uses大概可以理解为别人写的actions, 你只需要按他所说的设定规则就好.

这里 是github的官方市场, 里面都是别人写好的actions

爬虫

其实到上面基本就结束了, 毕竟github actions的使用才是重点, 至于我这个爬虫... 我只能说达到了目的, 但是代码写的稀烂, 毕竟只是写个demo, 重点在于了解actions的使用以后如果还想干别的肯定还会写其他脚本的.

# coding=utf-8
import requests
import re
from bs4 import BeautifulSoup as bs

def geturl(url):
    try:
        requ = requests.get(url, headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36'})
        requ.encoding = requ.apparent_encoding
        req = requ.text
        return req
    except:
        print("wrong")


if __name__ == '__main__':
    x = 0
    flag = 0
    cnt = 0
    retry=0
    body = []
    while(x <= 50) :
        try:
            url = 'https://jwc.xidian.edu.cn/'
            text = geturl(url)
            regex = re.compile(r'<a href="(.*?)" class="c49782"')
            body = regex.findall(text)
            print("successful")
            x=100
        except:
            x+=1
            continue

    print(body)
    with open("./update.txt", "r", encoding="utf-8") as f:
        date = f.read()
    newbody = []
    if(date == body[0]):
        flag = 1

    for i in body:
        if(date == i):
            break  # 到此为止, 之后的为之前内容
        else:
            newbody.append(i)
    date = body[0]
    body = newbody

    with open("./update.txt", "w", encoding="utf-8") as f:
        f.write(date)

    if(flag==0):
        with open("./text.html", "w", encoding="utf-8") as f:
            f.write(r"<h1>今日更新内容 :<br><br><br> </h1>")
            for i in body:
                retry = 0
                while(retry < 100):               
                    try:
                        url = 'https://jwc.xidian.edu.cn/' + i
                        html = geturl(url)
                        soup = bs(html, 'html.parser')
                        title = soup.find(name="td", attrs={"class" : "titlestyle49757"})
                        text = soup.find(name="div", attrs={"class" :"v_news_content"})
                        #print(str(title))
                        # print(str(text))
                        f.write(r"<h1>"+str(title)+r"</h1>"+r"&nbsp url : <a href="+url+r">" + url + r"</a>")
                        f.write(str(text))
                        f.write(r"<br><br><br><br><br><br><br>")
                        retry = 1000
                    except:
                        retry+=1  # 重复尝试
    else:
        with open("./text.html", "w", encoding="utf-8") as f:
            f.write(r"<h1>今天没有更新哦~~~</h1>")


    f.close()
    print("successful")

关于爬虫网上参考资料一堆

本来想直接用正则表达式提取字段展示就完了, 奈何re不给力半天没写好匹配, 就查了查beautifulsoup的使用方法然后用beautifulsoup十分钟解决了两小时没解决的问题

----好工具是十分重要的

然后在网页的请求上, 为了防止请求出错, 我设置了一个retry和一个x字段都是为了在出错时循环尝试的

然后就是update.txt了, 这里存的是网站最后一个通知的url链接, 下次一调用脚本时先打开update.txt, 判断当前最新的url是否与其是否相等, 如果相等就是没更新, 不相等的话就继续遍历当前的url集合, 直到找到更新的最后一条消息为止, 然后再把update更新一波就完了, 这俺想到的比较简单的解决方案

大概就扯这么多吧


原文地址:https://www.cnblogs.com/roccoshi/p/13144078.html