はじめに
昨年末に実家が空き巣に入られたり、年始早々身体に異変があってメンタル的に疲れているところに自分史上間違えなく上位に入る節々の痛さと突発的高熱、その翌週には、首を盛大に寝違えてキョンシーみたいな姿勢での生活を余儀なくされました。どうもagent bank 開発のhironekoです。
ちなみに巷で流行っているコロナではなく、ただの風邪で2日半くらいで回復して味覚等々を失うことなく今は、元気に業務と麻雀に励んでいます。
前回のブログ
- GitHub Actionsのcronがあるらしいってことでそれを使ってアニメの放送日にSlackへ通知しようぜ!ってのをやりました。
あれから一ヶ月
- おかげさまでアニメを見逃す日がなくなりました!(素晴らしい)
改善点と改善案
GitHub Actionsのcronラグあり過ぎじゃね?問題
- こちらは、無料枠で無料でGiHub様の善意の元リソースを使わせていただいているのでちょっと文句言いたいけどスルーすることにしました
- ただ何かしらのプロダクトには、活用場面なさそうって思いました。
Jsonデータで管理するのだるい問題
- 前回の目的は、見たいアニメの放送を見逃さない。っていう点にしか焦点は当たっておらずデータの収集や管理に関しては、全くの無関心でした
- なので改善点としては、以下になると思います。
改善点挙げておいてなんですが何かと初物や久々(何かを)に触るのがいいと思っていますので、遠い昔に触ったFirebaseでJsonを管理しようかなと考えたんですがクレデンシャルをどう管理すんねんS3か?って考えたんですがこのプロジェクトは、すべてを無料で!を心がけているので却下です。(微々たる金額で済むのも想定できるんですがね)
今回の実装
スクレイピングでJsonデータ作るぞの巻きに決定しました。
やらないこと
前提
import requests from bs4 import BeautifulSoup from os import getenv import json import datetime as dt import calendar today = dt.date.today() dayName = calendar.day_name[today.weekday()] if today.month < 10: month = f'0{today.month}' else: month = today.month weekList = { '月': 'Monday', '火': 'Tuesday', '水': 'Wednesday', '木': 'Thursday', '金': 'Friday', '土': 'Saturday', '日': 'Sunday' } load_url = getenv('SCRAPING_TARGET_URL') html = requests.get(load_url) soup = BeautifulSoup(html.content, "html.parser") animeList = soup.find(class_='week_area').find_all('li') jsonList = [] for e in soup.find(class_='week_area').find_all('li'): week = weekList[e.find(class_="oatime").find(class_='youbi').text] e.find(class_="oatime").find(class_='youbi').decompose() e.find('h4').find('strong').decompose() item = { 'title': e.find('h4').text, 'publish_at': e.find(class_="oatime").text, 'channel': 'TOKYO MX', 'day_of_week': week } jsonList.append(item) with open(f'./data/anime/{today.year}{month}.json', 'w') as f: json.dump(jsonList, f, ensure_ascii=False, indent=4)
前回同様解説していきます
コードを読めばわかるって内容なので解説すべきことはないんですけどね! スクレイピングしたあとのDOM操作に関しては、ほんと愚直な方法しか思いつかなかったので誰かいい方法があったら教えて欲しいです
- あーどうしよっておもったDOM操作が下記のようなHTMLでした
<div class="oatime"><p class="youbi">火</p>25:05~ </div>
- こんな形のHTMLだと
class="oatime"
直下のテキストを抜くと火
と25:05〜
が改行付きで取得できてしまう。なので先に曜日だけ取得して曜日のクラスのDOMを削除して時刻の取得を行うってことをしました。- 下記のような処理
week = weekList[e.find(class_="oatime").find(class_='youbi').text] e.find(class_="oatime").find(class_='youbi').decompose()
さきに最終的なJsonファイルをどうぞ
[ { "title": "\n7SEEDS\n", "publish_at": "22:30~ ", "channel": "TOKYO MX", "day_of_week": "Monday" }, { "title": "\nたとえばラストダンジョン前の村の少年が序盤の街で暮らすような物語\n", "publish_at": "23:00~ ", "channel": "TOKYO MX", "day_of_week": "Monday" }, ...... ]
- 最終的に前回手動で作成したJsonファイルと同じような形式をとることにしました。(処理をわざわざ変えるのもなーっておもったので)
- ファイル名に関しては、前回ファイル名を取得する際の方法で生成した
yyyymm
の形式にしました。
- ファイル名に関しては、前回ファイル名を取得する際の方法で生成した
新たな問題点
- TOKYO MXしか見ねー的なノリで始めたんですが、推しキャラの二乃がいる
五等分の花嫁
や約束のネバーランド
がT◯Sやフ◯TVじゃないですか。 これに関しては、それ以外の取得に関して考えて、結果マージしたデータでSlackに飛ばすようにするんだろうなってうっすら考えてます。まぁどちらもアマプラでいつでも見れるんですけどね!
いつcronで動かすよ問題!
- 1クール単位がいいんですがー言うてそんな設定できるんか?基準日を考慮できないと思うのでn日毎には実行難しそう。
- ってことでこちらは、月次で実行させておそらくPython側で判定する形にするでしょう!
反省
Pythonのお作法わからずだぁーって書いてしまっているので、リファクタリングとmodule化等を行っていきたいと思います。年末年始、特に年末が何してたかわからんくらいな状態だったので何もできなかったのでこれから平日含め学習をする癖がつくことただただ願います。
最後に独り言
アニメの通知ってamebaTVでできません?やアルっていう漫画サービスで発売日通知できますよって会社の同僚に言われました。「そそそそそうだったの」って内心思ったのは、内緒です。