【Python】気になるサイトの更新情報、定期的にチェックしてメール送信を自動化

Python

こんにちは、しらすです。

今回はWebページが更新されたら自動で自分にメールを送ってくれるツールをPythonで作りたいと思います。

これでドラマやアニメの更新情報、Web漫画がUpdateされたときなんかに見逃さずに情報が取得可能になるはず!

Webスクレイピング

RSSフィードの情報を取得していきたいと思います。

以下のサイトからRSSフィードのURLを取得しましょう。

RSSフィード取得・検出ツール - BeRSS.com

RSSのURLは以下のサイトを参考にして使用しました。

【Python】RSSでWebコミック 更新をスクレイピング
Webスクレイピングという技術を使えば、ネット情報を自動で取得することができます。 今回はPythonを使ってWebコミックサイト「となりのヤングジャンプ」をRSSフィードを用いてスクレイピング、最新話が更新されているか自動で確認します。

Gmailの送付設定

Gmailがよく利用されているようなので、まずはGmailで送信する方法を試したいと思います。送信用のコードは以下のサイトから拝借させていただきました。

Pythonでメール送信 | Python学習講座

Googleで送信できない!SMTPAuthenticationError

「SMTPAuthenticationError:」が出る方はこちらを参考に対応してみてください。アプリ用パスワードの発行、もしくはセキュリティの脆弱なアプリからの接続を許可により対応可能です。

Pythonでメール(gmail)を送信できない場合の解決法 | goccaの進捗記録
smtplib.SMTPAuthenticationError: (535, '5.7.8 Username and Password not accepted. Learn more at\n5.7.8 というエラーでメ

メール本文用のテキストをこまごま処理

ここまでできればひな形はほぼ完成です。あとは正直趣味の領域。

ということで、スクレイピングにて取得した情報を、メールで後から読みやすいようにテキスト処理していきたいと思います。

1日1回決まった時間に実行

さて、すべての準備が完了したので、最後は定期実行できるように処理をしていきたいと思います。

※これをやっておかないと、毎回コードを実行しなければいけない。せっかく作ったのにいつか忘れてしまうという悲しいことにならないためにも、定期実行環境を入れておくことをお勧めします

Linux系では「Cron」というものがよくつかわれるそう。私はWindowsなのでよくわかりませんが、Windowsでは「schedule」というライブラリが便利そうです。

動いているかは監視できるようにしよう

scheduleを使うことで定期実行可能になりました。しかし今回のように1日1回しか実行されないようなアプリだと、ほんとに動いているかわからない!ということで現在時刻を1分ごとに出力するようにしておきます。

また、毎度PCを立ち上げるたびに実行するのも面倒なので、デスクトップにbatファイルをおいて起動することにしました。

Pythonで現在時刻・日付・日時を取得 | note.nkmk.me
Pythonで現在時刻を取得するには標準ライブラリのtimeモジュールかdatetimeモジュールを使う。 UNIX時間(エポック秒)で取得したい場合はtimeモジュール、日時(日付と時刻)を表すdatetimeオブジェクトなどで取得 ...

完成版のコード

from email.mime.text import MIMEText
import smtplib
import feedparser
import schedule
import time
import datetime


#"""""""""""""""""""""""""""
Set info to message text
#"""""""""""""""""""""""""""
def get_message_text(list_max, name, list_title):
    message_text = ""
    if list_max == 1:
        message_text = message_text + "\n" + list_title + \
                        "\n" + name.entries[0].title +\
                        "\n" + name.entries[0].updated +\
                        "\n" + name.entries[0].link + "\n"
    else:
        for list_num, ent in enumerate(name.entries):
            if list_num == list_max:
                break
            No = list_num + 1
            message_text = message_text + "\n" + list_title + " " + str(No) +\
                            "\n" + ent.title +\
                            "\n" + ent.updated +\
                            "\n" + ent.link + "\n"
    return message_text

#"""""""""""""""""""""""""""
Get RSS and send e-mail
#"""""""""""""""""""""""""""
def get_RSS_send_email():
    #### Get RSS info in web
    onepunch    = feedparser.parse("https://tonarinoyj.jp/atom/series/13932016480028984490")
    tiempo      = feedparser.parse("https://tonarinoyj.jp/atom/series/10834108156632992433")
    gizmode     = feedparser.parse("https://www.gizmodo.jp/index.xml")
    gigazine    = feedparser.parse("https://gigazine.net/news/rss_2.0/")
    
    #### set message
    message_temp = get_message_text(1, onepunch, "ワンパンマン") +\
                   get_message_text(1, tiempo, "Tiempo") +\
                   get_message_text(5, gizmode, "Gizmode") +\
                   get_message_text(5, gigazine, "Gigazine")
    
    #### mail send
    # SMTP recognition information
    account = "xxx@gmail.com"
    password = "xxxxxxxxxxxxxxxxx"
     
    # To/From for e-mail
    to_email = "yyy@yyyy"
    from_email = "xxx@gmail.com"
     
    # MIME input
    subject = "更新情報"
    message = message_temp
    msg = MIMEText(message)
    msg["Subject"]  = subject
    msg["To"]       = to_email
    msg["From"]     = from_email
     
    # メール送信処理
    server = smtplib.SMTP("smtp.gmail.com", 587)
    server.starttls()
    server.login(account, password)
    server.send_message(msg)
    server.quit()
    print("e-mail have been sent successfully\n")
    
#"""""""""""""""""""""""""""
Main (schedule)
#"""""""""""""""""""""""""""
#AM6:00にjobを実行
schedule.every().day.at("10:00").do(get_RSS_send_email)

while True:
    time_now = datetime.datetime.now()
    print(time_now.strftime('%Y.%m.%d. %H:%M:%S'), "  Probram runnning")
    schedule.run_pending()
    time.sleep(60)

まとめ

いかがでしたでしょうか?

躓きポイントはあるものの、比較的容易に組み上げることができました

ただし私の場合、常時電源がついているPCがないため、定期処理を入れたとしてもPCを作動させないといけません。

サーバー上で自動実行できたりする気はしますが、パスワードなんかも入っているのであまりサーバー側には置きたくないところ。。。。この辺は今後の課題にしていきたいと思います。

また、メールではなくLineで送付する方法もあり、こちらもまた時間があるときに試したいと思います!

【Python】LINEでメッセージを自動で通知させる
以前、Gmailでメッセージを送信する方法を紹介しました。その際に、 GmailとLINEの両方を使い分けることが出来れば良いね。 なんて事を言ったので、今回はLINEでメッセージを自動で通知する方法を紹介します。 LINE Notifyに

コメント