1分に1回、タスクスケジューラ等で呼ぶこと前提。
import asyncio
from datetime import datetime, timedelta
import pytz
import requests
from bs4 import BeautifulSoup
import discord
import aiohttp
# Discordボットのトークン
DISCORD_TOKEN = 'Discordボットのトークン'
CHANNEL_ID = '投稿したいチャンネルのID'
def parse_time(date_str, time_str):
try:
# 日付と時間を結合
datetime_str = f"{date_str} {time_str}"
# 26:00 のような表記を処理
if ':' in time_str:
hours, minutes = map(int, time_str.split(':'))
if hours >= 24:
date_obj = datetime.strptime(date_str, "%m/%d")
date_obj += timedelta(days=1)
hours -= 24
datetime_str = f"{date_obj.strftime('%m/%d')} {hours:02d}:{minutes:02d}"
event_date = datetime.strptime(datetime_str, "%m/%d %H:%M")
event_date = event_date.replace(year=datetime.now().year)
return pytz.timezone('Asia/Tokyo').localize(event_date)
except ValueError as e:
print(f"Error parsing date/time: {e} for {date_str} {time_str}")
return None
async def get_hirose_events():
url = "https://hirose-fx.co.jp/contents/ecclndr/"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as response:
print(f"Status Code: {response.status}")
html_content = await response.text()
print(f"Content length: {len(html_content)}")
soup = BeautifulSoup(html_content, 'html.parser')
events = []
rows = soup.select('table.layout-top.row-data.font-small tr')
current_date = None
for row in rows:
cells = row.select('td')
if len(cells) >= 6:
date_cell = cells[0].text.strip()
time = cells[1].text.strip()
currency = cells[2].find('img')['title'] if cells[2].find('img') else ''
event_name = cells[3].text.strip()
if date_cell:
current_date = date_cell.split()[0]
if current_date and time and currency in ['日本', '米国']:
event_date = parse_time(current_date, time)
if event_date:
events.append({
"name": f"{currency} - {event_name}",
"time": event_date
})
print(f"Total JPY and USD events found: {len(events)}")
return events
async def report_upcoming_events():
fx_events = await get_hirose_events()
now = datetime.now(pytz.timezone('Asia/Tokyo'))
target_time = now + timedelta(minutes=30)
upcoming_events = []
for event in fx_events:
time_until_event = event['time'] - now
if timedelta(minutes=29) <= time_until_event <= timedelta(minutes=30):
upcoming_events.append(event)
if upcoming_events:
message = "30分後に予定されている日本と米国のイベント:\n"
for event in upcoming_events:
message += f"{event['time'].strftime('%Y-%m-%d %H:%M')} - {event['name']}\n"
# Discordに接続してメッセージを送信
client = discord.Client(intents=discord.Intents.default())
@client.event
async def on_ready():
try:
channel = await client.fetch_channel(CHANNEL_ID)
await channel.send(message)
print(f"Message sent to channel {CHANNEL_ID}")
finally:
await client.close()
await client.start(DISCORD_TOKEN)
else:
print("No events scheduled in the next 30 minutes.")
async def main():
await report_upcoming_events()
if __name__ == "__main__":
asyncio.run(main())