PythonでWebサイトの新着ニュースをメールで自動送信するには?【2022年版】
ここでは
「
Hacker News」
のサイトから新着ニュースを取得してメール(Gmail)で自動送信する方法を解説します。
「Hacker News」サイトから新着ニュースを取得するにはPythonのWeb Scrapingライブラリ「BeautifulSoup」を使用します。
取得した新着ニュースはGoogleの「Gmail」に送信します。
なお、PythonからGmailにメールを送信するには
Googleの
「セキュリティ」
サイトから「安全性の低いアプリのアクセス」を「オン」に設定する必要があります。
この仕様は2022年に変更になったので2段階認証を行って新規のパスワード(16桁)を取得する必要があります。
新規のパスワードの取得は以下の手順で行います。
-
Googleの
「セキュリティ」
サイトに移動したら「2段階認証プロセス」が「オン」になっているか確認します。
「オフ」になっているときは、「オン」にします。
Googleの指示に従って2段階認証の処理を完了させます。
-
「2段階認証プロセス」が「オン」になっていることを確認したら「アプリパスワード」をクリックします。
パスワードを入力する画面が表示されたら「パスワード」を入力して「次へ」のボタンをクリックします。
【図A】
-
「アプリパスワード」の画面に移動したら「アプリを選択」のドロップダウンリストをクリックして「その他(名前を入力)」を選択します。
「名前」のテキストボックスにはアプリの名前「GMO bot」を入力して[生成]ボタンをクリックします。
【図B】
-
すると16桁のパスワードが表示されるのでコピペして保存します。
最後に[完了]ボタンをクリックして閉じます。
【図C】
-
「アプリパスワード」の一覧に今回追加した「GMO bot」が表示されます。
【図D】
ここではVisula Studio Code(VS Code)の「
Python Interactive window」
を使用してJupter Notebookのような環境で説明します。
VSCを通常の環境からインタラクティブな環境に切り換えるにはコードを記述するときコメント「# %%」を入力します。
詳しい、操作手順については「
ここ」
を参照してください。
インタラクティブな環境では、Pythonの「print(), plt.show()」などを使う必要がないので掲載しているコードでは省略しています。
VSCで通常の環境で使用するときは、必要に応じて「print(), plt.show()」等を追加してください。
この記事では、Pandas、Matplotlibのライブラリを使用しますので
「
記事(Article001) |
記事(Article002) |
記事(Article003) |
記事(Article004)」
を参照して事前にインストールしておいてください。
Pythonのコードを入力するときにMicrosoftのVisula Studio Codeを使用します。
まだ、インストールしていないときは「
記事(Article001)」を参照してインストールしておいてください。
説明文の左側に図の画像が表示されていますが縮小されています。
画像を拡大するにはマウスを画像上に移動してクリックします。
画像が拡大表示されます。拡大された画像を閉じるには右上の[X]をクリックします。
画像の任意の場所をクリックして閉じることもできます。
「Hacker News」サイトの新着ニュースをメールで自動送信する
-
Pythonの「gmail_config.py」ファイルを作成してGoogleのGmailのアカウント情報を定義する
Visual Studio Code(VSC)を起動したら新規ファイル「gmail_config.py」を作成して行1-6をコピペします。
行4-6を自分のメールアドレスとパスワードに置換したら保存ください。
行2-3は固定ですから置換する必要はありません。
PythonからGmailにメールを送信するには「安全性の低いアプリのアクセス」を「オン」に設定する必要があります。
手順は図1の説明を参照してください。
# gmail_config.py
GMAIL_SERVER = 'smtp.gmail.com' # your smtp server
GMAIL_PORT = 587 # your port number
GMAIL_FROM = '****@gmail.com' # your from email id
GMAIL_TO = '****@gmail.com' # your to email ids # can be a list
GMAIL_PASS = '**********' # your email id's password
図1はGoogle Accountの「Security」画面です。
この画面から「セキュリティ」を選択して「安全性の低いアプリのアクセス」を「オン」に設定してください。
-
新規ファイルを作成してPythonのライブラリを取り込む
新規ファイルを作成したら行1-7をコピペします。
行1-6ではPythonのライブラリを取り込んでいます。
行7では前出で作成した「gmail_config.py」を取り込んでいます。
import requests
from bs4 import BeautifulSoup
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import datetime
import gmail_config
図2はVisual Studio Code(VSC)の画面です。
右側のインタラクティブ・ウィンドウからgmail_config.pyで定義した
「GMAIL_SERVER」と「GMAIL_PORT」の内容を表示しています。
-
Hacker Newsサイトから新着ニュースを取得する
行3では現在の日時を取得しています。
行10-20では関数「extract_news()」を定義しています。
引数urlには「Hacker News」サイトのURLを指定します。
戻り値としてHacker Newsサイトの新着ニュースのコンテンツを返します。
行22では関数extract_news()を呼び出してHacker Newsサイトから新着ニュースを取得しています。
行23-25ではメールで送信する本文を生成しています。
なお、メールはHTML形式で送信します。
### send email using gmail
# get current date/time
now = datetime.datetime.now()
# email content placeholder
content = ''
# extracting Hacker News Stories
def extract_news(url):
print('Extracting Hacker News Stories...')
cnt = ''
cnt += ('<b>Hacker News Top Stories:</b>\n' + '<br />' + '-'*50 + '<br />')
response = requests.get(url)
content = response.content
soup = BeautifulSoup(content,'html.parser')
for i,tag in enumerate(soup.find_all('td',attrs={'class':'title','valign':''})):
cnt += ((str(i+1) + ' :: ' + tag.text + '\n' + '<br />') if tag.text != 'More' else '')
#print(tag.prettify) #find_all('span',attrs={'class':'sitestr'}))
return(cnt)
cnt = extract_news('https://news.ycombinator.com/')
content += cnt
content += ('<br />------<br />')
content +=('<br /><br />End of Message')
図3では関数「extract_news()」からの戻り値を表示しています。
画面にはHacker Newsの新着ニュースが表示されています。
-
取得した新着ニュースをメールで送信する
行8-12ではgmail_config.pyファイルに定義したGmailのアカウント情報を取得して変数に保存しています。
行14ではMIMEMultipart(Multipurpose Internet Mail Extensions)のインスタントを生成しています。
行16-18ではMIMEにメールの「Subject(件名)」「FROM (Gmail address」「TO (eMail address)」を設定しています。
行20ではMIMEにメールの本文を設定しています。
行24ではSMTP(Simple Mail Transfer Protocol) Serverのインスタントを生成しています。
行26ではSMTP ServerのDebug情報を表示するように設定しています。
「0」を設定するとDebug情報の表示を抑止します。
行27-31ではSMTP Serverに接続&ログインしてメールを送信しています。
行27ではSMTP Serverのグリーティングに対して挨拶を返しています。
行28ではSMTP Serverに対して安全でない接続からTLSを使用して安全な接続にアップグレードすることを通知しています。
行29ではSMTP Serverにログインしています。
行31ではメールを送信しています。
行35ではSMTP Serverを切断しています。
### send the email
print('Composing Email...')
# update your email details
# make sure to update the Google Low App Access settings before
SERVER = gmail_config.GMAIL_SERVER # your smtp server
PORT = gmail_config.GMAIL_PORT # your port number
FROM = gmail_config.GMAIL_FROM # your from email id
TO = gmail_config.GMAIL_TO # your to email ids # can be a list
PASS = gmail_config.GMAIL_PASS # your email id's password
msg = MIMEMultipart()
msg['Subject'] = 'Top News Stories HN [Automated Email] ' + now.strftime('%Y/%m/%d')
msg['From'] = FROM
msg['To'] = TO
msg.attach(MIMEText(content, 'html'))
print('Initiating Server...')
server = smtplib.SMTP(SERVER, PORT)
server.set_debuglevel(1) # 0-suppress debug info, 1-display debug info
server.ehlo()
server.starttls()
server.login(FROM, PASS)
# We could not login successfully. Return result of last attempt.
server.sendmail(FROM, TO, msg.as_string())
print('Email Sent...')
server.quit()
図4-1はGmailにメールを送信したときの画像です。
Hacker Newsのサイトから取得した新着ニュースが表示されています。
図4-2はGoogleのGmailの画像です。
Hacker Newsのサイトから取得した新着ニュースが送信されています。
-
ここで解説したコードをまとめて掲載
最後にここで解説したすべてのコードをまとめて掲載しましたので参考にしてください。
import requests # http requests
from bs4 import BeautifulSoup # web scraping
# Send the mail
import smtplib
# email body
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# system date and time manipulation
import datetime
import gmail_config
# %%
### send email using gmail
# get current date/time
now = datetime.datetime.now()
# email content placeholder
content = ''
### extracting Hacker News Stories
def extract_news(url):
print('Extracting Hacker News Stories...')
cnt = ''
cnt +=('<b>Hacker News Top Stories:</b>\n'+'<br />'+'-'*50+'<br />')
response = requests.get(url)
content = response.content
soup = BeautifulSoup(content,'html.parser')
for i,tag in enumerate(soup.find_all('td',attrs={'class':'title','valign':''})):
cnt += ((str(i+1)+' :: '+tag.text + "\n" + '<br />') if tag.text!='More' else '')
#print(tag.prettify) #find_all('span',attrs={'class':'sitestr'}))
return(cnt)
cnt = extract_news('https://news.ycombinator.com/')
content += cnt
content += ('<br />------<br />')
content +=('<br /><br />End of Message')
# %%
### lets send the email
print('Composing Email...')
# update your email details
# make sure to update the Google Low App Access settings before
SERVER = gmail_config.GMAIL_SERVER # "your smtp server"
PORT = gmail_config.GMAIL_PORT # your port number
FROM = gmail_config.GMAIL_FROM # "your from email id"
TO = gmail_config.GMAIL_TO # "your to email ids" # can be a list
PASS = gmail_config.GMAIL_PASS # "your email id's password"
msg = MIMEMultipart()
# msg.add_header('Content-Disposition', 'attachment', filename='empty.txt')
msg['Subject'] = 'Top News Stories HN [Automated Email] ' + now.strftime('%Y/%m/%d')
msg['From'] = FROM
msg['To'] = TO
msg.attach(MIMEText(content, 'html'))
print('Initiating Server...')
server = smtplib.SMTP(SERVER, PORT)
#server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.set_debuglevel(1) # 0-suppress error, 1-display error
server.ehlo()
server.starttls()
server.login(FROM, PASS)
# We could not login successfully. Return result of last attempt.
server.sendmail(FROM, TO, msg.as_string())
print('Email Sent...')
server.quit()