LoginSignup
0
0

【LIVE】全国の日の出日の入り時刻を毎日配信してみた

Last updated at Posted at 2020-01-15

Motive

気がついたら家にずっといて夕方になることがよくあるので、明るい時に行動したいっすよね。
てことなので冬季特有のうつ病予防対策として、全国の日の出日の入りの時刻を毎日更新して表示させてみます。

Method

日の出日の入りですが, おはこん番地は!?APIを使っています。

スクリプトですが、、、

  • Qiita記事を作成する

  • Qiita記事をapiを使って更新する

の二つに分割し、cron を使ってだいたい午前12時くらいにrunさせる設定にします。

Development

Qiita記事を作成するスクリプト

import requests
import datetime
from bs4 import BeautifulSoup
from collections import namedtuple
import asyncio
import os

State = namedtuple('State', ['name', 'id', 'lat', 'lng'])

#dataset
states = [
	State("札幌市",    1, 43.06417,141.34694),
	State("青森市",    2, 40.82444,140.74),
	State("盛岡市",    3, 39.70361,141.1525),
	State("仙台市",    4, 38.26889,140.87194),
	State("秋田市",    5, 39.71861,140.1025),
	State("山形市",    6, 38.24056,140.36333),
	State("福島市",    7, 37.75,140.46778),
	State("水戸市",    8, 36.34139,140.44667),
	State("宇都宮市",   9, 36.56583,139.88361),
	State("前橋市",    10, 36.39111,139.06083),
	State("さいたま市", 11, 35.85694,139.64889),
	State("千葉市",    12, 35.60472,140.12333),
	State("新宿区",    13, 35.68944,139.69167),
	State("横浜市",    14, 35.44778,139.6425),
	State("新潟市",    15, 37.90222,139.02361),
	State("富山市",    16, 36.69528,137.21139),
	State("金沢市",    17, 36.59444,136.62556),
	State("福井市",    18, 36.06528,136.22194),
	State("甲府市",    19, 35.66389,138.56833),
	State("長野市",    20, 36.65139,138.18111),
	State("岐阜市",    21, 35.39111,136.72222),
	State("静岡市",    22, 34.97694,138.38306),
	State("名古屋市",  23, 35.18028,136.90667),
	State("津市",     24, 34.73028,136.50861),
	State("大津市",   25, 35.00444,135.86833),
	State("京都市",   26,35.02139,135.75556),
	State("大阪市",   27,34.68639,135.52),
	State("神戸市",   28,34.69139,135.18306),
	State("奈良市",   29,34.68528,135.83278),
	State("和歌山市",  30, 34.22611,135.1675),
	State("鳥取市",   31,35.50361,134.23833),
	State("松江市",   32,35.47222,133.05056),
	State("岡山市",   33,34.66167,133.935),
	State("広島市",   34,34.39639,132.45944),
	State("山口市",   35,34.18583,131.47139),
	State("徳島市",   36,34.06583,134.55944),
	State("高松市",   37,34.34028,134.04333),
	State("松山市",   38,33.84167,132.76611),
	State("高知市",   39,33.55972,133.53111),
	State("福岡市",   40,33.60639,130.41806),
	State("佐賀市",   41,33.24944,130.29889),
	State("長崎市",   42,32.74472,129.87361),
	State("熊本市",   43,32.78972,130.74167),
	State("大分市",   44,33.23806,131.6125),
	State("宮崎市",   45,31.91111,131.42389),
	State("鹿児島市", 46,31.56028,130.55806),
	State("那覇市",   47,26.2125,127.68111)
]

async def get_time_sun_rise_set(year, month, day, state):
    url = 'http://labs.bitmeister.jp/ohakon/api/?'
    payload = {'mode':'sun_moon_rise_set', 'year':year, 'month':month, 'day':day, 'lat':state.lat, 'lng':state.lng}
    response = requests.get(url, params=payload)
    soup = BeautifulSoup(response.content, "html.parser")
    await asyncio.sleep(1)

    sunrise = datetime.datetime.strptime(soup.sunrise_hm.text,'%H:%M')
    sunset = datetime.datetime.strptime(soup.sunset_hm.text,'%H:%M')

    diff_seconds = (sunset - sunrise).total_seconds()
    diff_hours = int(diff_seconds // (60 * 60))
    diff_minutes = int((diff_seconds - diff_hours * (60 * 60)) / 60)

    return state.name, soup.sunrise_hm.text, soup.sunset_hm.text, "{:02d}:{:02d}".format(diff_hours, diff_minutes)

def write_session(foutobj, path):
	with open(path, "r", encoding='utf-8') as fin:
		foutobj.write(fin.read())	


if __name__ == "__main__":
	now = datetime.datetime.now()
	output = "./article.md"
	base_folder = "./templates/"

	loop = asyncio.get_event_loop()
	cors = [get_time_sun_rise_set(now.year, now.month, now.day, s) for s in states]
	result = loop.run_until_complete(
			asyncio.gather(*cors)
		)
	build_parts = ["motive.md", "method.md", "development.md", "contents.md", "future.md", "reference.md"]

	with open("./templates/contents.md", "w", encoding='utf-8') as fout:
		fout.write("# Sunrize/Sunset\n\n")
		fout.write("{}\n\n".format(datetime.datetime.now().strftime("【%Y/%m/%d %H:%M時更新】")))
		fout.write("|city|sunrize|sunset|hours of sunlight|\n")
		fout.write("|:--|:--|:--|:--|\n")
		for r in result:
			fout.write("|{}|{}|{}|{}|\n".format(*r))
		fout.write("\n\n")

	with open(output, "w", encoding='utf-8') as fout:
		for p in build_parts:
			write_session(fout, os.path.join(base_folder, p))

get_time_sun_rise_set() でAPIを使って日の出日の入りの時間を出力しています。リクエストを設定するときは payload = {'mode':'sun_moon_rise_set', 'year':year, 'month':month, 'day':day, 'lat':state.lat, 'lng':state.lng} の通り日付と緯度経度のパラメータを用います。

あと、それぞれのapi取得を安定的に取得するために念のため 非同期処理 asyncio を使っています。

	loop = asyncio.get_event_loop()
	cors = [get_time_sun_rise_set(now.year, now.month, now.day, s) for s in states]
	result = loop.run_until_complete(
			asyncio.gather(*cors)
		)

また、あとあとで編集しやすいために各セクションの文章を分割して、最終的に集約させています。
単純にファイルを読み書きするときは open(path, 'r') でよかったのですが cron で実行する場合は文字コードでエラーになります。
それで 引数に明示的に encoding='utf-8' にする必要があります。(ファイルI/O由来でUnicodeDecodeErrorが出た時の対処法 を参照)

	build_parts = ["motive.md", "method.md", "development.md", "contents.md", "future.md", "reference.md"]
	with open(output, "w", encoding='utf-8') as fout:
		for p in build_parts:
			write_session(fout, os.path.join(base_folder, p))

Qiita記事をapiを使って更新する

import json
import requests

if __name__ == "__main__":
	BASE_URL = "https://qiita.com/api/v2/items/"
	TOKEN = "--アクセストークン--"
	headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type":"application/json"}

	sentence = ""
	with open("article.md", "r", encoding='utf-8') as fin:
		sentence = fin.read()

	contents = {"title": "【LIVE】全国の日の出日の入り時刻を毎日配信してみた",
				"tags": [{"name": "Python"},
						{"name":"cron"},
						{"name":"asyncio"},
						{"name":"QiitaAPI"},
						{"name":"api"}],
				"body": sentence,
				"id":"ada82beb3b747b99a05e"
				}

	res = requests.patch(BASE_URL + contents["id"], headers=headers, json=contents)
	print(res)

QiitaAPIを使うにはアクセストークンの発行が必要で、requestsでAPIをリクエストするときに必要です。
requests.patch({コンテンツのURL}, {ヘッダー}, {コンテンツの内容}) で内容を更新することができます。

Sunrize/Sunset

【2023/10/01 01:00時更新】

city sunrize sunset hours of sunlight
札幌市 5:30 17:17 11:47
青森市 5:32 17:20 11:48
盛岡市 5:30 17:19 11:49
仙台市 5:31 17:21 11:50
秋田市 5:34 17:23 11:49
山形市 5:33 17:23 11:50
福島市 5:32 17:23 11:51
水戸市 5:32 17:23 11:51
宇都宮市 5:34 17:25 11:51
前橋市 5:38 17:29 11:51
さいたま市 5:35 17:26 11:51
千葉市 5:33 17:24 11:51
新宿区 5:35 17:26 11:51
横浜市 5:35 17:26 11:51
新潟市 5:38 17:28 11:50
富山市 5:45 17:36 11:51
金沢市 5:47 17:38 11:51
福井市 5:49 17:40 11:51
甲府市 5:39 17:31 11:52
長野市 5:41 17:32 11:51
岐阜市 5:47 17:38 11:51
静岡市 5:40 17:32 11:52
名古屋市 5:46 17:37 11:51
津市 5:47 17:39 11:52
大津市 5:50 17:42 11:52
京都市 5:51 17:42 11:51
大阪市 5:51 17:43 11:52
神戸市 5:53 17:44 11:51
奈良市 5:50 17:42 11:52
和歌山市 5:53 17:45 11:52
鳥取市 5:57 17:48 11:51
松江市 6:01 17:53 11:52
岡山市 5:58 17:49 11:51
広島市 6:04 17:55 11:51
山口市 6:07 17:59 11:52
徳島市 5:55 17:47 11:52
高松市 5:57 17:49 11:52
松山市 6:02 17:54 11:52
高知市 5:59 17:51 11:52
福岡市 6:12 18:04 11:52
佐賀市 6:12 18:04 11:52
長崎市 6:13 18:06 11:53
熊本市 6:10 18:03 11:53
大分市 6:07 17:59 11:52
宮崎市 6:07 18:00 11:53
鹿児島市 6:10 18:04 11:54
那覇市 6:21 18:17 11:56

Future

全国の日の出日の入り時間を出力してみると時間差が約30分から約60分くらいあり、日照時間は約30分から60分くらいの差があることがわかります。

Reference

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0