본문 바로가기
Python

[프로젝트후기] 모바일 어플마켓 크롤러 개발 후기 근데 슬랙봇을 곁들인

by 돈민찌 2022. 3. 9.
반응형

  • Python 3.10, Django 4.0, MySQL 8(AWS RDS) , Django-ninja, BeautifulSoup4 4.10 사용.

django 4.0 버전을 사용했다. 파이썬을 최최신 버전을 사용했는데, 3.8버전 이후에 생긴 추가 기능이 배포 서버(리눅스 우분투)에서 뻗어버려 당황했던 적이 있었다. 문자열 관련 메소드 중 removesuffix, removeprefix 메소드를 무심코 사용했었다가 그만... 앞자리 숫자가 같은 버전들 사이에서는 처음 겪는 이슈라 좀 당황스러웠는데 겪고 보니 딱히 필수적인 메소드도 아닌데 IDE가 추천해주는 대로 막 쓰면 이런 꼴이 나는구나 하는 교훈을 얻었다.

  • Django ORM을 활용해 객체지향적 프로그래밍. Q, F, Count 등의 서브쿼리 메소드 적극 혼용.

Django ORM은 꽤나 직관적이고 쓰기 편하다. 다만 aggregate, group by 등의 메소드는 직접 구현?해서 사용해야 한다. 이 때 자주 쓰이는 메소드는 .values(), .value_list(), .aggregate(), .annotate() 등이 있고, 서브쿼리를 조작하는 함수는  Q, F, Min, Max, Count 등이 있다. Q는 SQL의 OR, AND를 사용할 수 있게 된다 보면 되고, F는 alias 기능을 제공한다. Min, Max, Count는 이름 그대로의 역할을 한다. 잘 다룰 줄 알아야 고급 장고 개발자라 불릴 수 있을 것 같다.

  • Django DRF 보다 12배 빠른 속도를 보장하는 Django Ninja 사용.
  • Django Ninja: api 반응 속도 뿐만 아니라 swagger ui를 제공해 개발 속도 향상.
  • Django Ninja: pydantic 기반으로 데이터 타입을 제한해 데이터 모델의 일관성 보장.

사실 Fast API와 Django 중에 뭐를 시키실지 꽤나 고민하셨다고 한다. Django Ninja는 Spring에서 한번 써본 적이 있는 Swagger의 UI를 그대로 제공하며, 마찬가지로 테스트 코드 작성 전에 API를 임의 개발해 써보면서 고쳐나갈 수 있게 해준다. 일반 API의 응답 속도 만으로도 DRF보다 빠르다고 하는데, 코드 작성에도 유리한 점이 많아 좋았다. 또한 Django Ninja는 Pydantic에 의존성을 가지고 있다. pydantic은 동적 타입을 가지고 있는 파이썬의 자유분방함을 꽉 잡아주며 API의 캡슐화를 돕는다. 프로젝트가 장기화가 될 수록 이때 쌓아놓은 꼼꼼함이 나중에 빛을 발한다고 하니 신경써야함.

  • Django-crontab을 이용해 EC2 환경에서 정기적으로 requests+bs4 크롤링.

스프링 프로젝트를 할 때 깨달았던 것이지만, 스케줄링(크론) 작업에 셀레니움 같은 복잡하고 무거운 스크래퍼를 두는 것은 꽤나 복잡한 문제를 낳는다. 이번에는 requests로 JSON 혹은 HTML을 받아와 HTML의 경우에만 BeautifulSoup으로 파싱하는 코드를 작성했다. 매시각마다 랭킹을 기록하고, 하루에 한번 그 랭킹들 중 최고 순위를 기록하는 로직을 작성했고, 하루에 한번 내부 데이터베이스로부터 광고 중인 어플리케이션을 불러오는 것까지 구현했다. crontab을 쓰는 프로젝트에서 EB를 사용하면 거북하게 동작한다고 해서(안해봐서 확신은 못함) EC2에 배포했다.

  • Django template을 사용한 데이터 그룹핑 + lodash를 이용한 데이터 그룹핑 적절히 혼합해 사용.

DJango는 Jinja와 비슷한 템플릿 코드를 제공한다. 적당히 써주면 코드 보안이나 렌더링 속도 면에서 나은 점이 많은 것 같다. API를 받아와 JSON에서 값을 꺼내 사용하는 부분들은 대부분 Lodash.js의 손을 거쳤다. 리액트 공부할 때에 쓰로틀, 디바운스 때문에 알게 된 라이브러리지만 그보다 훨씬 유용하게 사용하고 있다.

  • 관계 부서와 계속해서 수집 데이터 형식 및 수집 기간 조율하여 Slack 봇 개설. 애플리케이션 순위 변동 사항 정기 보고.

Slack 봇을 개설했다. slack에서 제공해주는 API를 다루는데 (Slacker라는 라이브러리를 제공한다.) 뭔가 마음대로 잘 안돼서 엔드포인트만 따서 함수로 만들어버렸다. 이렇게 쓰는 거 아닌거 같은데... 잘 작동한다.

from slacker import Slacker

def slack_notify(text=None, channel='#test', username='알림봇', attachments=None):
    token = "xoxb-시크릿키 냠냠쩝쩝"
    slack = Slacker(token)
    slack.chat.post_message(text=text, channel=channel, username=username, attachments=attachments)
    
# 원래 이렇게 생긴 코드인데....

def post_to_slack(text=None):
    import requests
    import json
    url = 'https://hooks.slack.com/services/슬랙에서제공하는/엔드포인트'
    _headers = {'Content-type': 'application/json'}
    body = json.dumps({"text": text})
    req = requests.post(url, headers=_headers, data=body)
    logger.debug(req.headers)
    
# 이렇게 만들어서 사용했다.

 

반응형

댓글