ネット中心で生活していると、どうしても自分の興味があることに情報閲覧が偏ってしまって、興味のない事柄に触れる機会が減ってしまいます。なので、1日1回、強制的に知らない言葉を自分にインプットするためにWikipediaの記事をランダムに1件取得してツイートするTwitterのbotを作りました。
#開発したTwitter bot
個人的には、朝一で脳みそのちょっとした刺激になることがあります。
#環境
- AWS Lambda
- python3.7
#ポイント
- Wikipediaの記事をランダムに1件取得するのに、MediaWiki APIを利用しました。
- 1日1回の起動は、AWS Lambdaの関数をAmazon CloudWatch Eventsのcron式で定期的に実行することで実現しました。(AWS Lambdaでの関数の作り方はたくさんの解説があるのでここでの説明は割愛します。)
- Twitterのbotを開発するためには、アカウント取得に加えてTwitter Appへの登録が必要です。(Twitter Appについてもたくさんの解説があるのでここでの説明は割愛します。)
#Wikipediaの記事の取得について
Wikipediaの記事をランダムに1件取得するのに、MediaWiki APIを利用しました。
記事のタイトルを取得するだけでは味気ないので、最初にランダムに記事を1件取得し、その記事のID(pageid)を使って内容を取り出すということをしています。
TwitterのTweetは140文字以内という制限があるので、Tweetするメッセージは、
記事の内容(冒頭部分) + Wikipediaの記事へのリンク
という形式で140文字に収まるように作っています。「収まるようにする」あたりに少々工夫があるので、時間を作って改めて解説してみたいと思っています。
import json
import sys
import urllib.parse
import urllib.request
import os
# Wikipedia API
WIKI_URL = "https://ja.wikipedia.org/w/api.php?"
# 記事を1件、ランダムに取得するクエリのパラメータを生成する
def set_url_random():
params = {
'action': 'query',
'format': 'json',
'list': 'random', #ランダムに取得
'rnnamespace': 0, #標準名前空間を指定する
'rnlimit': 1 #結果数の上限を1にする(Default: 1)
}
return params
# 指定された記事の内容を取得するクエリのパラメータを生成する
def set_url_extract(pageid):
params = {
'action': 'query',
'format': 'json',
'prop': 'extracts', #記事の文章を取得
'exsentences': 5, #5行分取り出す
'explaintext': '',
'pageids': pageid #記事のID
}
return params
#ランダムな記事IDを取得
def get_random_wordid():
try:
request_url = WIKI_URL + urllib.parse.urlencode(set_url_random())
html = urllib.request.urlopen(request_url)
html_json = json.loads(html.read().decode('utf-8'))
pageid = (html_json['query']['random'][0])['id']
except Exception as e:
print ("get_random_word: Exception Error: ", e)
sys.exit(1)
return pageid
#記事IDの内容を取得して、140文字以内のTweetの文章を作成
def get_word_content(pageid):
request_url = WIKI_URL + urllib.parse.urlencode(set_url_extract(pageid))
html = urllib.request.urlopen(request_url)
html_json = json.loads(html.read().decode('utf-8'))
explaintext = html_json['query']['pages'][str(pageid)]['extract']
explaintext = explaintext.splitlines()[0] #改行が含まれる場合に最初の要素のみを取得
if len(explaintext) > 128:
explaintext = explaintext[0:124] + "..."
explaintext += "\nhttps://ja.wikipedia.org/?curid=" + str(pageid) #twitterはurlを11.5文字とカウントする仕様
return explaintext
if __name__ == '__main__':
pageid = get_random_wordid()
extract = get_word_content(pageid)
print(extract)
#Twitterでのツイートについて
twitterライブラリを使っています。
import os
from twitter import Twitter, OAuth
#環境変数に設定したTwitter Appで取得したキー情報を取得
API_KEY = os.environ.get("TWITTER_API_KEY")
API_SECRET_KEY = os.environ.get("TWITTER_API_SECRET_KEY")
ACCESS_TOKEN = os.environ.get("TWITTER_ACCESS_TOKEN")
ACCESS_TOKEN_SECRET = os.environ.get("TWITTER_ACCESS_TOKEN_SECRET")
#TwitterのTweetを生成
def TweetMessage(msg):
t = Twitter(auth = OAuth(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, API_KEY, API_SECRET_KEY))
statusUpdate = t.statuses.update(status=msg)
#AWSのlambda_functionについて
一応、書いておきます。
import wiki_random
import tweet
def lambda_handler(event, context):
pageid = wiki_random.get_random_wordid()
msg = wiki_random.get_word_content(pageid)
tweet.TweetMessage(msg)
実行結果がどのようになるかは、こちらを見てみてください。
#AWS LambdaのLayerについて
requests、requests-oauthlib、twitterの3つのPythonのライブラリはAWS Lambdaに標準で組み込まれていないのでLayer機能を使って組み込みました。(Layer機能についてもたくさんの解説があるのでここでの説明は割愛します。)