여의도에서 근무하는 친구가 찾아보기 귀찮다고 해서 만들어줬다. 코딩한 기간은 땡땡하게 해서 이주정도 걸린거 같다.
크롤링 라이브러리는 beautifulsoup 를 사용했다.
상한가 종목은 naver finance 에서 긁어오고, 그 종목 상한가 원인은 구글 클라우드 플랫폼으로 검색해서 이유를 찾았다.
챗GPT 는 초기사용자 무료 크레딧으로 연결해서 만들었다. 알림은 API가 잘나오는 텔레그램으로 진행했다.
자세한 사항은 링크 들어가보면 어떻게 사용해야 하는지 잘 써있다.
그렇게 모듈은 총 4개정도 쓴거 같다. 다음은 각 모듈별로 까다로웠던 부분 개선점을 얘기해 보겠다.
naver finance API
tables = soup.find_all('table', {'class': 'type_5'})
# Check if the second table exists
if len(tables) > 1:
# Get the second table
result_tables.append(tables[0])
result_tables.append(tables[1])
네이버증권은 코스피 코스닥 table class 명이 같은데 이건 tables 로 받아서 각각을 따로 진행해주면 된다.
테스트코드 진행할때는 __main__ 을 활용해주면 참 편하다
if __name__ == "__main__":
main(stocks)
구글 검색 API
얘는 무슨 모듈이냐면 그날 주식의 상한가 이유를 주식별로 구글에서 뉴스 앞제목을 따오는 모듈이다.
얘는 api_key, engine_id 로 key 를 잡아서 키워드만 넣어주면 되는 간단한 사용법을 가졌다.
url = f"https://www.googleapis.com/customsearch/v1?key={API_KEY}&cx={ENGINE_ID}&q={stock}{HIGH}"
response = requests.get(url)
상한가 원인을 잡는 keyword 를 뭐로 할지가 고민이 좀 되었다. 그런데 그냥 XXX(주식이름) 상한가 라고만 치고 키워드 위주로 답변해달라고 gpt 한테 얘기하는게 제일 깔끔한 것 같았다.
config.py의 중요성을 디렉토리 처리하다 참 많이 느꼈다. 아직 해두진 않았지면 리팩토링할일이 생기면 꼭 해둬야지...
안해두면 진짜 개복잡해짐...
if response.status_code == 200:
data = response.json()
os.makedirs(f"{LOG_PATH}/{today_date}", exist_ok=True)
with open(f"{LOG_PATH}/{today_date}/{today_date}_news_{stock}.txt", "w", encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=2)
챗GPT API
주식별로 구글에서 뉴스 앞제목을 따왔으면 XXX 주식에 대해서 요약을 부탁하는 워딩을 쳐야한다.
난 지금 이 주식이 오늘 상한가를 기록한 이유를 키워드 중심으로 요약해줄 수 있어? 를 쓴다.
예전에는 '키워드중심' 을 안썼는데 이거 쓰고 안쓰고 차이가 가독성과 품질에 꽤 큰 차이가 있다. 이게 생각보다 중요하다.
GPT API 를 쓰는 방법은 버전별로 조금씩 다른데 24년 1월기준에는 이렇게 쓰고있다.
우선 API KEY 를 넣는 client 객체를 하나 만든다.
client = OpenAI(
# This is the default and can be omitted
api_key='XXX'
)
그리고 create 객체에 필요한 넣고자 하는 질문을 이렇게 넣으면 된다
chat_completion = client.chat.completions.create(
messages=[
{
"role": "user",
"content": f"{input_sliced_datas[stock_idx]}\n\n{GPT_CMD}",
}
],
model="gpt-3.5-turbo",
stream=True,
)
텔레그램 API
이제 만든 상한가 원인분석 메시지를 매일 오후 4시 장이 끝나는 시간에 텔레그램으로 받아보는 모듈을 만들어야 한다.
처음엔 카카오톡으로 진행하고 싶었는데 쉽지 않아서 텔레그램 API 로 진행했다.
텔레그램은 심지어 송신 뿐만이 아니라 메시지 수신까지 가능해서 활용도가 무궁무진 할 것 같다.
얘기가 조금 새지만 수신하는 부분 코드를 보면 await 로 업데이트 여부를 잡아서 진행할 수 있다.
async def main():
TELEGRAM_TOKEN = '6377969316:AAEKc2q_6u60iFM3idaw0VEihIeC9vXKpTY'
bot = telegram.Bot(token=TELEGRAM_TOKEN)
updates = await bot.get_updates()
for update in updates:
print(update.message)
첨에 단톡방 ID 가져오는게 조금 낯설었는데 텔레그램이 되게 잘해둬서 생각보다 애먹진 않았다.
처음에는 bot 을 하나 계정을 파야하고 해당 bot 의 토큰은 텔레그램 UI 에 나와있다.
BOT_TOKEN = "6377969316:AAEKc2q_6u60iFM3idaw0VEihIeC9vXKpTY"
그 bot 이 추가된 단톡방을 만들고 그 단톡방 ID 를 해당 URL 에서 가져오면 된다.
#https://api.telegram.org/bot6377969316:AAEKc2q_6u60iFM3idaw0VEihIeC9vXKpTY/getUpdates
그리고 가져온 BOT_TOKEN 과 CHAT_ID 를 24.2 기준으로 이렇게 하면 메시지를 보낼 수 있다.
response = requests.post(
'https://api.telegram.org/bot%s/%s' % (BOT_TOKEN, 'sendMessage'),
data={
"chat_id": CHAT_ID,
"text": message,
}
)
TODO
GPT API 에서 프롬프트 엔지니어링 부분을 보완해도 좋겠다.
1. 상황 설명 2. input form 제공 3. output form 제공 정도가 있다는데 이쪽을 더 공부해서 깎아도 좋겠다.
또 친구가 트위터 팔로워 추가시 알람 보내주는 봇 만들어달라 해서 찾아봤는데,,, 머스크가 산 이후로 트위터 api 생태계가 박살이 났다...
최소한 50$ 씩은 한달에 줘야지 쓸 수 있는것 같았다...
rendering 순서를 Javascript 로 동적으로 만져서 twitter 같은 것들은 bsoup로 크롤링이 안된다... 나쁜머스크... 으잉
이를 해결한 라이브러리가 분명히 있을 것이다... 결국 HTML 은 유저가 받기는 해야지 뜨니깐... 고수님들 아시는분 댓글 달아주세용...
정안되면 딥러닝을 써서 웹브라우저 이미지에서 찾는 것도 가능할텐데... 이론상 분명 가능하다.