You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

308 lines
14 KiB

import telebot
from config import Config
import pdfplumber
import time
import requests
from datetime import datetime
import schedule
from bs4 import BeautifulSoup
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import WebDriverException
import pytz
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from datetime import timedelta
import threading
BOT_TOKEN = '6701395239:AAFE30dqvNihDdni9vYoAbWssO-X5yAmwho'
# BOT_TOKEN = "6746720034:AAEMaoV2FwIZ8pz_PF18-bo2a6gFC1eVtVs"
#BOT_TOKEN = '6589162555:AAHGhrTQ0wYNtIUySMohnfpxQl1d6blr24Q'
def broadcast_message(message:str,chat_id:str):
r = requests.post(f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
json={
"chat_id": chat_id,
"text": message,
},
)
def find_cpi(driver):
try:
driver.get(cpi_url)
print("Open")
date = driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div/div[1]/pre[1]').text.split('\n')[6].split("-")[1].split(" ")[1]
value = driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div/div[1]/pre[1]').text.split('\n')[8:12]
return driver, date, value
except Exception as e:
print(f"Error in find_cpi: {e}")
return driver, None, None
def find_fomc(driver, date:str):
try:
driver.get(fomc_url+date+".htm")
print("Open")
date = driver.find_element(By.CLASS_NAME, 'article__time').text.split(',')[0].split(' ')[0]
value = driver.find_element(By.XPATH, '//*[@id="article"]/div[3]').text.split('.')
value = [item for item in value if 'In support of' in item]
return driver, date, value[0].strip('\n')
except Exception as e:
print(f"Error in find_fomc: {e}")
return driver, None, None
def find_non_farm(driver):
try:
driver.get(nonfarm_url)
print("Open")
date = driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div/div[1]/pre').text.split('\n')[6]
value = driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div/div[1]/pre').text.split('\n')[8:12]
return driver, date, value
except Exception as e:
print(f"Error in find_non_farm: {e}")
return driver, None, None
def find_pce(driver, date_target:str):
try:
driver.get(pce_url+date_target)
print("Successfully accessed the website.")
time.sleep(1)
date = driver.find_element(By.XPATH, '//*[@id="home"]/h1').text.split(' ')[4]
value_1 = driver.find_element(By.XPATH, '//*[@id="home"]/div[2]/div/div/p[2]').text
value_2 = driver.find_element(By.XPATH, '//*[@id="home"]/div[2]/div/div/div[1]/table/tbody/tr[13]').text.strip(' ').split(' ')[-1]
return driver, date, value_1, value_2
except WebDriverException as e:
print(e)
print("Failed to access the website.")
return driver, None, None, None
def find_pmi(driver, date_target:str):
try:
driver.get(pmi_url+date_target+"/")
print("Open")
# time.sleep(4)
agree_button = driver.find_element(By.XPATH, '//*[@id="alert-modal-disclaimer___BV_modal_body_"]/center/input')
agree_button.click()
date = driver.find_element(By.XPATH, '//*[@id="main"]/div[1]/div/div[2]/div/div[1]/div/div/div[1]/div[1]/h1[2]').text.split(' ')[0]
value = driver.find_element(By.XPATH, '//*[@id="main"]/div[1]/div/div[2]/div/div[1]/div/div/div[1]/div[1]/p[3]').text.split('.')[0:4]
#將value list 串起來成一個string
value_str = ".".join(value)+"."
return driver, date, value_str
except Exception as e:
print(f"Error in find_pmi: {e}")
return driver, None, None
def broadcast_all_non_farm(target:str):
startimee = time.time()
driver = webdriver.Chrome(options=options)
driver, date, message = find_non_farm(driver)
while date != target:
driver.refresh()
print("Non Farm Refresh")
driver, date, message = find_non_farm(driver)
message= "\n".join(message)
broadcast_message(message, "-1002033782195")
endtimee = time.time()
broadcast_message(
f"Now :{datetime.fromtimestamp(time.time())} , Spend time :{str(round(endtimee - startimee, 3))} s",
"-1002033782195")
broadcast_message(f"The above is the Non Farm for {target}","-1002033782195")
driver.quit()
return True
def broadcast_all_cpi(target:str):
startimee = time.time()
driver = webdriver.Chrome(options=options)
driver, date , message = find_cpi(driver)
while date != target:
driver.refresh()
print("Cpi Refresh")
driver, date, message = find_cpi(driver)
message= "\n".join(message)
broadcast_message(message, "-1002033782195")
endtimee = time.time()
broadcast_message(
f"Now :{datetime.fromtimestamp(time.time())} , Spend time :{str(round(endtimee - startimee, 3))} s",
"-1002033782195")
broadcast_message(f"The above is the CPI for {target}","-1002033782195")
driver.quit()
return True
def broadcast_all_fomc(target:str,date_target:str): #date_target = "20240131a"
startimee = time.time()
driver = webdriver.Chrome(options=options)
driver, date , message = find_fomc(driver,date_target)
while date != target:
driver.refresh()
print("Fomc Refresh")
driver, date, message = find_fomc(driver,date_target)
broadcast_message(message, "-1002033782195")
endtimee = time.time()
broadcast_message(
f"Now :{datetime.fromtimestamp(time.time())} , Spend time :{str(round(endtimee - startimee, 3))} s",
"-1002033782195")
broadcast_message(f"The above is the FOMC abstract for {target}","-1002033782195")
driver.quit()
return True
def broadcast_all_pce(target:str,date_target:str):
startimee = time.time()
driver = webdriver.Chrome(options=options)
driver, date, message1, message2 = find_pce(driver,date_target)
while date != target:
driver.refresh()
print("PCE Refresh")
driver, date, message1, message2 = find_pce(driver,date_target)
broadcast_message(date+" PCE Data", "-1002033782195")
broadcast_message(message1+'\n\n Percent change from month one year ago : '+f"**{message2}**", "-1002033782195")
endtimee = time.time()
broadcast_message(
f"Now :{datetime.fromtimestamp(time.time())} , Spend time :{str(round(endtimee - startimee, 3))} s",
"-1002033782195")
broadcast_message(f"The above is the PCE for {target}","-1002033782195")
driver.quit()
return True
def broadcast_pmi(date_target:str):
startimee = time.time()
driver = webdriver.Chrome(options=options)
driver, date, value = find_pmi(driver, date_target)
Up_date = date_target.capitalize()
while date != Up_date:
driver.refresh()
print("PMI Refresh")
driver, date, value = find_pmi(driver, date_target)
broadcast_message(Up_date+" PMI Data", "-1002033782195")
broadcast_message(value, "-1002033782195")
endtimee = time.time()
broadcast_message(
f"Now :{datetime.fromtimestamp(time.time())} , Spend time :{str(round(endtimee - startimee, 3))} s",
"-1002033782195")
broadcast_message(f"The above is the PMI for {Up_date}","-1002033782195")
driver.quit()
return True
has_broadcasted = False
def wrapper_function_cpi(target):
global has_broadcasted
time.sleep(55)
result = broadcast_all_cpi(target)
if result:
has_broadcasted = True
def wrapper_function_pce(target,date_target):
global has_broadcasted
time.sleep(55)
result = broadcast_all_pce(target,date_target)
if result:
has_broadcasted = True
def wrapper_function_fomc(target,date_target):
global has_broadcasted
time.sleep(55)
result = broadcast_all_fomc(target,date_target=date_target)
if result:
has_broadcasted = True
def wrapper_function_non_farm(target):
global has_broadcasted
time.sleep(55)
result = broadcast_all_non_farm(target)
if result:
has_broadcasted = True
def wrapper_function_pmi(target):
global has_broadcasted
time.sleep(55)
result = broadcast_pmi(target)
if result:
has_broadcasted = True
def convert_to_utc(date_str, time_str, offset_seconds=0):
local_tz = pytz.timezone('Asia/Taipei')
local_time = datetime.strptime(date_str + " " + time_str, "%Y/%m/%d %H:%M")
local_time = local_time - timedelta(seconds=offset_seconds) # 提前 offset_seconds 秒
local_time = local_tz.localize(local_time)
utc_time = local_time.astimezone(pytz.utc)
return utc_time.strftime("%Y-%m-%d %H:%M")
def print_hello(text):
time.sleep(55)
startime = time.time()
startime = datetime.fromtimestamp(startime)
print("Start Time:" , startime)
print("Hello")
print(text)
return True
schedules = {
convert_to_utc("2024/05/22", "10:33", 5): {"function": print_hello, "args": ["May"]},
convert_to_utc("2024/05/22", "10:34", 5): {"function": print_hello, "args": ["June"]},
convert_to_utc("2024/06/12", "20:30", 5): {"function": wrapper_function_cpi, "args": ["MAY"]},
convert_to_utc("2024/07/11", "20:30", 5): {"function": wrapper_function_cpi, "args": ["JUNE"]},
convert_to_utc("2024/08/14", "20:30", 5): {"function": wrapper_function_cpi, "args": ["JULY"]},
convert_to_utc("2024/09/11", "20:30", 5): {"function": wrapper_function_cpi, "args": ["AUGUST"]},
convert_to_utc("2024/10/10", "20:30", 5): {"function": wrapper_function_cpi, "args": ["SEPTEMBER"]},
convert_to_utc("2024/11/13", "21:30", 5): {"function": wrapper_function_cpi, "args": ["OCTOBER"]},
convert_to_utc("2024/12/11", "21:30", 5): {"function": wrapper_function_cpi, "args": ["NOVEMBER"]},
convert_to_utc("2024/05/31", "20:30", 5): {"function": wrapper_function_pce, "args": ["April", "april-2024"]},
convert_to_utc("2024/06/28", "20:30", 5): {"function": wrapper_function_pce, "args": ["May", "may-2024"]},
convert_to_utc("2024/07/26", "20:30", 5): {"function": wrapper_function_pce, "args": ["June", "june-2024"]},
convert_to_utc("2024/08/30", "20:30", 5): {"function": wrapper_function_pce, "args": ["July", "july-2024"]},
convert_to_utc("2024/09/27", "20:30", 5): {"function": wrapper_function_pce, "args": ["August", "august-2024"]},
convert_to_utc("2024/10/31", "20:30", 5): {"function": wrapper_function_pce, "args": ["September", "september-2024"]},
convert_to_utc("2024/11/27", "21:30", 5): {"function": wrapper_function_pce, "args": ["October", "october-2024"]},
convert_to_utc("2024/12/20", "21:30", 5): {"function": wrapper_function_pce, "args": ["November", "november-2024"]},
convert_to_utc("2024/06/07", "20:30", 5): {"function": wrapper_function_non_farm, "args": ["MAY"]},
convert_to_utc("2024/07/05", "20:30", 5): {"function": wrapper_function_non_farm, "args": ["JUNE"]},
convert_to_utc("2024/08/02", "20:30", 5): {"function": wrapper_function_non_farm, "args": ["JULY"]},
convert_to_utc("2024/09/06", "20:30", 5): {"function": wrapper_function_non_farm, "args": ["AUGUST"]},
convert_to_utc("2024/10/04", "20:30", 5): {"function": wrapper_function_non_farm, "args": ["SEPTEMBER"]},
convert_to_utc("2024/11/01", "20:30", 5): {"function": wrapper_function_non_farm, "args": ["OCTOBER"]},
convert_to_utc("2024/12/06", "21:30", 5): {"function": wrapper_function_non_farm, "args": ["NOVEMBER"]},
convert_to_utc("2024/06/13", "02:00", 5): {"function": wrapper_function_fomc, "args": ["June", "20240613a"]},
convert_to_utc("2024/08/01", "02:00", 5): {"function": wrapper_function_fomc, "args": ["August", "20240801a"]},
convert_to_utc("2024/09/19", "02:00", 5): {"function": wrapper_function_fomc, "args": ["September", "20240919a"]},
convert_to_utc("2024/11/08", "02:00", 5): {"function": wrapper_function_fomc, "args": ["November", "20241108a"]},
convert_to_utc("2024/12/19", "03:00", 5): {"function": wrapper_function_fomc, "args": ["December", "20241219a"]},
convert_to_utc("2024/06/03", "21:07", 5): {"function": wrapper_function_pmi, "args": ["April"]},
}
if __name__ == "__main__":
global nonfarm_url, cpi_url, fomc_url, pce_url, options
options = Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument("--window-size=1920,1080") # 可以根據需要調整這個大小
options.add_argument(
'user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3')
nonfarm_url = "https://www.bls.gov/news.release/empsit.nr0.htm"
cpi_url = "https://www.bls.gov/news.release/cpi.nr0.htm"
fomc_url = "https://www.federalreserve.gov/newsevents/pressreleases/monetary"
pce_url = "https://www.bea.gov/news/2024/personal-income-and-outlays-"#january-2024
pmi_url = "https://www.ismworld.org/supply-management-news-and-reports/reports/ism-report-on-business/pmi/"#+month/
print("Start Time:" , datetime.fromtimestamp(time.time()))
# schedule.every().day.at("10:44").do(wrapper_function_fomc, "March", "20240320a")
for times, task in schedules.items():
func = task["function"]
args = task["args"]
print(f"Schedule {func.__name__} at {times}")
schedule.every().day.at(times.split(" ")[1]).do(threading.Thread(target=func, args=args).start)
while True:
schedule.run_pending()
if has_broadcasted:
print("Broadcast completed")
has_broadcasted = False
time.sleep(0.1) # Check every 0.1 seconds
#NonFarm
# date , message = find_non_farm(nonfarm_url)
# print(date)
# print(message)
#CPI
# find_cpi("FEBRUARY")
#PCE
#broadcast_all_pce("February", "february-2024")
# date, message1, message2 = find_pce("february-2024")
# print(date)
# print(message1)
# print(message2)
#FOMC
# date , message = find_fomc(fomc_url,"20240320a")
# print(date)
# print(message)