見出し画像

【アプリ開発日記21】毎朝、天気予報を自動ツイートする with Pixiv

「今日の天気は 雨 です!」

「よし、傘でも用意するか」

 ちゅーりんです。いよいよ梅雨入り、外に出てから「あ、雨降ってる……」って傘を取りに戻るのを繰り返しています。

「先に窓から外の天気見ればいいじゃん」

 その通りなんですが、この人、それさえ面倒に感じます。そもそもカーテンを閉めっぱなしにしている。さらに2階に住んでいることもあり、水たまりの波面が見えなかったり傘を持ってる人が通る道が都合よく隠れていたりと、なんだかんだ言って昨日もおとといも建物を出てから「あ」とわざわざ部屋まで戻ったりしています。

 しかし、そんな生活もかれこれ5年目。

「自分から天気予報見ないんだったら、その通知が来るようにすればいいじゃん」

ということで、前置きが長くなりましたが「毎朝6時に天気予報を自動ツイート」機能を作り、それを他のアカウントで通知オンにすることで二度と同じ過ちを踏まぬようにしていきます。

 もちろん今までのように「LINE Notify」「Slack API」でもできますが、今回は誰でも手軽に使えるようにと、ツイッターの公開アカウントで作成しました。

※Twitter APIでツイートするためには審査が必要になります。同機能を自分でも作ってみたい、という方は以下サイトにその流れをまとめていますので、参考になれば幸いです。

1、天気取得 & ツイート

 主題です。天気を取得するためには

  • APIを使う = なるべくこれ。各サイト専用のAPIが準備されている

  • スクレイピング = ネットから情報をとってくる。そのサイトにアクセスするため、頻回/大量のデータを取得するとサーバーに迷惑をかけるので注意

 天気のAPIといえば「OpenWeatherMap」がメジャーですが、日本の地方の天気は精度がいまいちな気がしたので、ヤフー天気予報に頼ることにしました。が、APIはなかったのでスクレイピングすることに。

 気象庁などの天気予報例もよく見かけました。

 以下、参考にさせていただいたサイトです。

 最終的なコードは以下の通り。

import tweepy
import requests
from bs4 import BeautifulSoup


# Twitter APIを使用するためのConsumerキー、アクセストークン設定
Consumer_key = '' #APIキー
Consumer_secret = '' #APIシークレットキー
Access_token = '' #アクセストークン アカウント・アプリごとに発行 oauth_token config.txtより
Access_secret = '' #アクセスシークレットトークン アカウント・アプリごとに発行 oauth_token_secret config.txtより


# ツイートのテンプレート文
content = """おはようございます!

複数行もOK。
"""

def twitter_auth():
    #Twitter 認証
    auth = tweepy.OAuthHandler(Consumer_key, Consumer_secret)
    auth.set_access_token(Access_token, Access_secret)
    api = tweepy.API(auth, wait_on_rate_limit = True)
    return api

def tweet(api):
    """Tweet contents"""
    # requestsでHTTPリクエスト結果を取得し、BeautifulSoupで扱えるように変換
    r = requests.get('https://weather.yahoo.co.jp/weather/jp/5/3210.html')
    soup = BeautifulSoup(r.content, 'html.parser')
    tenki_today = soup.select_one('#main > div.forecastCity > table > tr > td > div > p.pict')
    str = '秋田市 今日のお日柄は ' + tenki_today.text.replace(' ', '').replace('\n', '')+' です!\n\n今日もまた 素敵な1日になりますように'
    print(content + '\n' + str)
    # ツイート
    api.update_status(content + '\n' + str)

if __name__ == '__main__':
    api = twitter_auth()
    tweet(api)

 ツイートの部分は、先ほどの記事を参考にしていただければと思います。

 さて、これで完成! でもいいんですが、ちょっと内容が味気ない感じがしました。毎朝同じ文句が来ると飽きてきそうというか……

 おみくじ(今日は大吉!みたいな)とか、天気に合った画像も併せてツイートするのはどうかな、とも考えたのですが、これも想像を超えない。

 私の場合、絵が好きなので「Pixivのデイリーランキング1位のイラストもツイートする!」ということにしました。

2、Pixivのデイリーランキング1位のイラストをツイートする

「とはいっても Pixivのスクレイピングすれば行けるでしょ」

これがとんだ大間違い。ややニッチな話になってしまいますが、Pixivの場合

  • ログインしないと見れない

  • 見れたところで、画像をダウンロードしようとすると「403」エラーコードが返ってきてできない(運営側でできないようにしているっぽい)

これには頭を抱えてしまった。が、先人いたり。非公式ながら、Pixiv APIなるものが存在していました。その名も「Pixivpy3」。

ただし、ログインするための

api.login(username=username, password=password)

が現在使えなかったために、

api.auth(refresh_token=REFRESH_TOKEN)

というものに置き換える必要がありました。

 以下、全体の流れです。

  1. 必要なライブラリをインストール(pixivpy3, seleniumなど)

  2. ログインに必要な「REFRESH TOKEN」を以下サイト参考に取得する

  3. 以下の処理を実行する → ダウンロードされる!

# pixivデイリーランキング 上位3つのイラストをダウンロード

from pixivpy3 import *

aapi = AppPixivAPI()
REFRESH_TOKEN = ''
aapi.auth(refresh_token=REFRESH_TOKEN)

json_result = aapi.illust_ranking()
for illust in json_result.illusts[:3]:
    print(illust['title'])
    aapi.download(illust.image_urls.large)

なお、最後から2番目に

illust['title']

とありますが、この中にjson形式でその画像に関する作者、作品名、タグなどの情報が入っています。

 今回は画像に合わせてタイトルと作者名もツイートしたかったので、取得することにしました。

 これで下準備は完了です。

3、画像ごとツイートする

あとは画像付きツイートをするだけです。ただ「update_status_with_media」はうまく使えなかったので、「update_status」にしています。

最終的なコードはこちら。

from pixivpy3 import *
aapi = AppPixivAPI()
REFRESH_TOKEN = ''
aapi.auth(refresh_token=REFRESH_TOKEN)
json_result = aapi.illust_ranking()
for illust in json_result.illusts[:1]:
    title = illust['title']
    artist = illust['user']['name']
    name = str(illust['id']) +'_p0_master1200.jpg'
    aapi.download(illust.image_urls.large)

import tweepy, emoji
import requests
from bs4 import BeautifulSoup
# Twitter APIを使用するためのConsumerキー、アクセストークン設定
Consumer_key = '' #APIキー
Consumer_secret = '' #APIシークレットキー
Access_token = '' #アクセストークン アカウント・アプリごとに発行 oauth_token config.txtより
Access_secret = '' #アクセスシークレットトークン アカウント・アプリごとに発行 oauth_token_secret config.txtより
# ツイートのテンプレート文
content = """おはようございます!
"""
def twitter_auth():
    #Twitter 認証
    auth = tweepy.OAuthHandler(Consumer_key, Consumer_secret)
    auth.set_access_token(Access_token, Access_secret)
    api = tweepy.API(auth, wait_on_rate_limit = True)
    return api
def tweet(api):
    """Tweet contents"""
    # requestsでHTTPリクエスト結果を取得し、BeautifulSoupで扱えるように変換
    r = requests.get('https://weather.yahoo.co.jp/weather/jp/5/3210.html')
    soup = BeautifulSoup(r.content, 'html.parser')
    tenki_today = soup.select_one('#main > div.forecastCity > table > tr > td > div > p.pict')
    str = content + '\n' + '秋田市 今日の予報は ' + tenki_today.text.replace(' ', '').replace('\n', '')+ ' ' + emoji.emojize(':four_leaf_clover:', language='alias') + '\n\n今朝のpixiv DR1位は「'+title+'」by '+artist+'!'
    print(str)
    # ツイート
    #api.update_status(str)
    media = api.media_upload(name)
    api.update_status(status=str, media_ids=[media.media_id])
if __name__ == '__main__':
    api = twitter_auth()
    tweet(api)

 最後にVPS / Ubuntu OS でcrontabを使って毎朝自動実行してもらうようにすれば……

無事ツイートされました!

おわりに

 前半まじめに作っていたものの、振り返れば後半に熱が入っていた…そんな回でした。まあ、面白い方がいいよね(?)

 今回は天気予報でしたが、使う人によって多様な魅力があふれ出るのがTwitter APIです。「こんなの作ったよー!」とあれば飛んで見に行きますので、ぜひ教えてください!

 ではでは!!

いいなと思ったら応援しよう!