본문 바로가기

MLOps/Development

[Update] 미 증권 뉴스 스크래핑 : 클라우드타입(CloudType - Paas)

[Update] 미 증권 뉴스 스크래핑 : 클라우드타입(CloudType - Paas) 

 

이런 내용입니다.

API를 주기적으로 호출하기 위해 Github Action을 사용했지만 큰 변수가 있었고,

변수를 해결하기 위해 국내 PaaS 클라우드 호스팅 서비스를 사용한 내용이다.

 

큰 변수?

그것은 Github Action에 사용량 제한이 있어서 10분마다 API를 호출하는 나한테는 2000분으로는 부족하다.

그래서 나는 이 부분을 CloudType의 힘을 빌리기로 했다.


동작 흐름


1. CloudType

CloudTyped은 국내 PaaS 클라우드 호스팅 서비스이다.

 

모두의 플랫폼팀, 클라우드타입

클라우드타입은 클라우드 기반 애플리케이션을 빠르게 개발하고 배포할 수 있는 클라우드 애플리케이션 플랫폼입니다.

cloudtype.io

 

각 언어마다 템플릿을 제공해 주는데 나는 Slack-Bot(Python)을 사용했다.

처음에는 Slack-Bot을 선택했지만, 404 Not Found 에러가 발생했지만

하지만 여기서 CloudType의 장점이 나왔다.


CloudType의 장점

바로 "국내 서비스"라서 문서도 한글이고 디스코드도 운영하고 있다.

그래서 디스코드에 도움을 요청했고 매우 빠르게 해결됐다. 최고다 ㄷㄷ


2. Slack Bolt

특별하지는 않고 단순 스케줄링 코드만 집어넣었다.

여기서 Slack Bolt를 사용했는데 기존 Slack API 랑 차이점은

Slack Bolt는 Slack 앱 빌드를 간소화하는 상위 수준 프레임 워크라고 생각하면 될 것 같다. 매우 편하다

# Create an instance of the Slack app
app = App(token=SLACK_BOT_TOKEN)

def scrape_data_and_send_to_slack():
    print("start scraping")
    response = requests.post(url, json=data, headers={'api-key': api_key})

    if response.status_code == 200:
        scraped_data = response.json()
        current_time = get_current_time()
        blocks = []
        
        # Iterate through the scraped data and build blocks for each article
        for article in scraped_data:
            title = article['title']
            paragraphs = "\n".join(article['paragraphs'])

            # Add a section block with the article title and date
            blocks.append({
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": f"*{title}*\n{current_time}"
                }
            })

            # Add a section block with the article paragraphs
            blocks.append({
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": paragraphs
                }
            })

            # Add a divider block for visual separation
            blocks.append({
                "type": "divider"
            })

        # Send a message to the Slack bot with the blocks
        app.client.chat_postMessage(
            channel=SLACK_CHANNEL_ID, 
            text="Scraped data summary", 
            blocks=blocks
        )
    else:
        app.client.chat_postMessage(
            channel=SLACK_CHANNEL_ID, 
            text=f"Request failed with status code {response.status_code}: {response.text}"
        )

코드가 너무 지저분한데.. 저기 Blocks 뭐죠?

메시지를 전송할 때 템플릿을 구성하는 부분이다. 

  • 템플릿 사용 전

 

  • 템플릿 사용 후

 

Building with Block Kit

String the atoms together into molecules and inject them into messages and modals.

api.slack.com


3. 전체 코드

 

GitHub - heohyunjun/slackbot-py

Contribute to heohyunjun/slackbot-py development by creating an account on GitHub.

github.com


4. 남아있는 문제점

인스턴스 사양의 제한을 좀 극복하기 위해서 스크래핑 섹션 영역을 변경하면서 데이터 양을 최소화를 계속 시도했지만 가끔 죽어버리긴 한다.


5. 결론 및 마무리

좋은 무료 클라우드 서비스를 아깝게 쓰는 것 같다 ㅋㅋㅋ