재입고 알림 봇 만들기-4 실행하기

시리즈의 마지막 글입니다. 지금까지 만든 것들을 엮어줄 메인 프로그램과 그것을 실행하는 방법을 알아보겠습니다.

메인 프로그램

지금까지 만든 프로그램들(스크래핑, 텔레그램 등)은 각각 작은 역할을 하는 부품이라고 볼 수 있습니다. 전체 프로그램의 목표는 주기적으로 스크래핑을 실행하고 구매가능 상태가 되었을 때 사용자에게 알림(텔레그램)을 보내는 것입니다. 스크래핑과 알림은 되었고 그 둘을 엮어줄 프로그램이 필요합니다. 메인 프로그램의 역할은

  • 설정(실행 주기, 텔레그램 ID 등등)을 읽어와 세팅한다.
  • 주기적 실행한다.
    • 스크래핑 프로그램 호출
    • 구매 가능상태 체크
    • 알림 프로그램 호출

입니다.

설정 파일

설정 파일은 프로그램을 심플하게 만들기 위해 사용합니다. 이메일 주소, 텔레그램 ID, 실행 주기(몇분) 등이 프로그램에 들어가 있으면 보기에도 좋지 않고 나중에 변경을 할 때에도 프로그램을 수정해야 하므로 불편함이 있습니다. 이러한 정보들은 설정 파일로 분리하는게 좋습니다.
여기서는 실행 주기와 API를 사용하기 위한 텔레그램 토큰, 알림 메시지를 수신할 텔레그램 ID를 설정으로 분리했습니다.
설정 파일들은 메인 프로그램에서 읽어와 각 부품 프로그램들에 전달됩니다.

메인 프로그램

  • 9~10 라인 : 위에서 만든 설정 파일을 읽어오는 부분입니다.
  • 15~29 라인 : 스크래핑 결과를 해석하는 함수입니다. 스크래핑 대상이 되는 샵마다 달라지는 부분입니다. 스크래핑 하는 코드는 동일하고 스크래핑 대상마다 다른 것은 그것을 해석하는 부분입니다. 이를 위해 해석하는 부분을 스크래핑 프로그램이 아닌 메인 프로그램에 위치시켰습니다. 만들어진 함수는 39라인에서 재고 확인 클래스(StockCheck)를 생성할 때 전달됩니다. 실제 실행은 재고 확인 클래스에서 이루어지게 됩니다. 여러 샵을 함께 체크할 경우 이런 함수를 여러 개 만들어서 각각 체크 대상 링크와 함께 재고 확인 클래스로 전달해주면 됩니다. 샵을 체크하기 확장을 편하게 하기 위해 들어간 설계요소 입니다. 이렇게 자주 변하는 부분(이 함수)과 자주 변하지 않는 부분(재고 확인 클래스)를 분리해 놓는것이 좋은 프로그래밍 방법으로 생각됩니다.
  • 33 라인 : 메인 프로그램 부분입니다.
  • 34 ~ 35 라인 : 텔레그램 알림 클래스(TelegramBot)를 만들어주고 테스트 메시지를 보냅니다.
  • 37 ~ 39 라인 : 전체 프로그램의 핵심인 재고 확인 클래스를 만들어줍니다. 쉽게 식별하기 위해 이름을 넣어주고 스크래핑 대상이 되는 링크와 해석 함수를 전달했습니다.
  • 41 라인 : 설정으로 읽어온 실행 주기를 세팅합니다.
  • 44 ~ 35 라인 : 이 함수는 여러 개의 아이템을 체크하기 위한 것입니다. 재고 확인 클래스의 배열을 입력받습니다. 각 아이템들을 체크하고 그 결과를 반환합니다. for 와 같은 반복문으로 해도 되지만 그냥 심심해서 함수형으로 만들었습니다. 예를 들어 체크하려는 아이템이 레고, 마스크, 손소독제 3가지 라면 그 3가지 아이템의 재고를 체크(statusChanged 함수의 실행 결과)하고 그 결과를 리스트로 반환하게 됩니다.
  • 48 라인 : 계속 실행되도록 하기 위해 while True 로 무한 루프를 돌게 만들었습니다.
  • 49 라인 : 각 아이템을 체크하고 결과를 받아옵니다. 예제에서는 하나의 아이템만 만들어서 배열에 하나의 요소만 있습니다. 2가지 이상의 아이템을 체크하려면 37~39 라인 처럼 StockCheck 클래스를 만들어주고 check 함수에 전달되는 배열에 추가해주면 됩니다.
  • 51 라인 : 현재 시간과 함께 체크 결과를 출력합니다. 프로그램이 정상적으로 돌아가는지 확인하기 위한 부분입니다.
  • 53 라인 : 사용자 알림을 위해 구매가능 상태가 바뀐 것만 필터링 합니다. 역시 for 반복으로 해도 되지만 심심해서 함수형 스타일로 filter를 써봤습니다.
  • 55 ~ 56 라인 : 53 라인에서 가져온 상태가 변경된 상품 목록에 대해서 알림 메시지를 보냅니다.
  • 58 라인 : 실행 주기를 만들기 위해 잠시 쉬도록 만듭니다. 기본 설정(INTERVAL_MINS)에 따르게 되면 5분 동안 대기하게 됩니다.

이제 준비가 완료되었습니다.

실행하기

메인 프로그램을 실행하면 됩니다.

> python main.py

Monitoring started. 라는 메시지가 텔레그램으로 오고 5분 마다 실행 결과가 출력되면 정상적으로 프로그램이 실행되는 것입니다.

실행 환경

어떤 컴퓨터에서 실행할지에 따라 실행 방법에 차이가 조금 있습니다. 기본적으로 파이썬과 스크래핑, 텔레그램 등의 패키지가 설치된 환경에서 main.py 프로그램을 실행하면 됩니다. 각 프로그램들(스크래핑, 텔레그램 등)과 설정 파일은 main.py 프로그램과 동일한 디렉토리에 위치시켜주면 됩니다.

아나콘다가 설치된 윈도우의 경우에는 Anaconda Prompt를 실행하고 커맨드 라인에서 python main.py 로 실행하면 됩니다.

시놀로지와 같은 NAS에서 docker를 기반으로 실행한다면 우선 도커 > 컨테이너 > (아나콘다 컨테이너 선택) > 터미널 에 들어갑니다.
터미널 입력창에 # python main.py 로 실행하면 됩니다. 창을 닫은 상태로도 계속 실행되게 하려면 nohup 을 사용하시면 됩니다.

정리

여기까지 인터넷 쇼핑몰에 품절 상품이 구매 가능해지면 알림을 보내도록 하는 프로그램을 만들어봤습니다. 처음 글을 쓰고 나서 쉽게 써달라는 요청이 많아서 최대한 자세하게 작성해봤습니다. 전에 작성했던 프로그램을 보자니 부족한 부분이 많이 보입니다. 프로그래밍을 잘 모르시는 분들도 따라하실 수 있게 만들었지만 쉽게 쓰는게 역시 쉽지 않네요..

이런 요구사항이 많다는 것도 알게 되어서 서비스화하면 어떨까 생각이 들기도 합니다. 사용자가 간단히 URL만 등록하면 알아서 체크하고 알림을 보내게 해주는거죠. 이건 나중에 만들어봐야겠습니다. 잘 안되시는 부분 있으면 댓글이나 메일, 텔레그램 ID tldrsam 으로 문의 주세요. 긴 글 봐주셔서 감사합니다.

재입고 알림 봇 만들기-4 실행하기”의 10개의 생각

  1. 하얀소망 답글

    대단한 정성이 담긴 글 잘 보았습니다. 저도 시놀로지 나스에서 뭔가 돌려보려고 하는데, 큰 도움이 될 것 같습니다.

    • samsee 글쓴이답글

      감사합니다 🙂 시놀로지 이런저런 용도로 활용하기 좋은 것 같아요. 제가 올린 것도 그 일부가 될 수 있을 것 같네요.

  2. chi 답글

    더 나아가 재입고가 될때 물건이 너무 빨리 빠지는데 입력한 정보로 자동 주문하는것까지는 구현이 가능할까요?

    보안이나 기타 이슈로 구현 자체가 힘들지, 혹은 법적인 테두리(오토프로그램)로 인해 힘들지 의견이 궁금합니다 ㅎㅎ..

    가능하다면 블로그를 보고 한번 공부하며 만들어보고싶네요!

    컴공은 아니지만 다른 과에서 파이썬을 주로 사용해와서 재밌는 도전이 될 것 같습니다.

    • samsee 글쓴이답글

      자동으로 주문까지 하는 부분은 Python 스크립트만 사용해서는 좀 어렵습니다. selenium 과 같은 headless 브라우저를 사용하거나 RPA 프로그램을 쓰면 가능은 할 것 같습니다. 하지만 결제 페이지가 조금만 바뀌어도 프로그램이 동작하지 않을 가능성이 높습니다. 큰 사이트의 경우 자동주문을 방지하는 기능도 있는 걸로 알고 있습니다.
      재고가 적은 상품을 매점매석하고 프리미엄을 붙여 리셀하는 것은 피해자를 만들기도 하구요. 좋지 못한 행위라고 생각합니다.

  3. Choi 답글

    이 방법은 5분에 한번씩 업데이트 되는건가요?
    실시간으로 초단위로 업데이트 받으려면 어떻게 해야하나요?

    • samsee 글쓴이답글

      설정 파일의 인터벌(INTERVAL_MINS)을 줄이면 체크하는 주기를 줄일 수 있습니다. 하지만 너무 많은 요청을 발생시키면 DDoS 공격으로 탐지되어 IP가 차단될 위험이 있습니다. IP가 차단되면 브라우저를 통한 정상적인 접근도 막히게 되죠.
      이런 것까지 고려하면 AWS Lambda 같은 Serverless 환경에서 실행되도록 하는게 안전(?)합니다. IP가 계속 바뀌도록 하는거죠. 문제는 클라우드 비용이 발생하게 되는 것이겠죠.

  4. 김준 답글

    안녕하세요.

    미국사이트에서 구매하고 싶은 운동화가 있습니다.
    하지만 큰사이즈를 제외하고 항상 품절이네요.
    사이즈별 간헐적 재입고가 심심치 않게 되는곳이라 근 몇주간 간간히 확인하는 것으로는 운이 안따라 주네요.
    텔레그램알림봇이라는 존재는 알고 있었기에 재입고때 알림을 받을 수 있는 방법이 없을까 싶어 검색에 검색을 거듭하다 SAMSEE님의 블로그까지 방문하게 되었습니다.

    이런 자세한 글을 발견한 것 만으로도 저에게는 행운이기에 며칠에 걸쳐 시간이 허락하는 대로 몇번이고 정독하였으나 비전공자인 저에겐 너무 어렵네요.
    친절한 설명덕에 큰범위의 개념과 방법은 이해가 가지만 사용되는 도구나 언어 하나하나가 처음 듣는 것이다보니 더이상 엄두가 나질 않습니다.
    사고자 하는 페이지의 개발자도구를 클릭하여 품절상품과 재고상품의 차이까지는 알게됐습니다.

    https://www.newbalance.com/pd/mens-made-in-us-993/MR993V1-M.html

    재고가 있는 사이즈는 [data-url=”해당 사이즈의 url”]
    재고가 없는 사이즈는 [data-url=”null”]
    로 차이를 보입니다.

    근데 여기까지입니다.
    설명을 보고 이해를 했으니 구체화 시키면 되는데 코드 부분은 정말 모르겠습니다.
    글자 하나만 틀려도 작동하지 않는데 내가 원하는 기능의 명령어가 무엇 인지조차 알 수가 없습니다.
    마치 외계언어 같습니다. ^^;

    댓글을 확인해도 일정 수준 이상의 분들의 대화인지라 제가 이리 댓글을 남겨도 되는지 조심스럽습니다.

    제가 원하는 기능은 제가 원하는 사이즈를 설정하고 그 사이즈가 재입고 되었을때 텔레그램으로 메시지가 전송되는 것입니다.

    자동구매 기능 같은 것은 원치 않습니다.
    그 이후부턴 제 손에 달렸겠지요.

    혹시 시간이 허락하신다면 조언 부탁드립니다.

    초면에 이런 글을 남기게 되어 송구스럽습니다.

    만약 제 글이 무례했다고 느끼신다면 무시하셔도 저는 괜찮습니다.
    주말 잘 보내시고 항상 건강한 하루하루가 되시길 기원합니다.
    감사합니다.

    • samsee 글쓴이답글

      안녕하세요. 코드도 원래 보고 이해하는거랑 실제로 쓰려고 할 때랑 간극이 좀 있습니다 ^^
      사이트 봤을 때 일단 가능한 것으로 보이구요. 사이즈 부분은 button 태그들(사이즈 버튼)에 속성 title 이나 data-attrvalue 라는걸로 읽어올 수 있을 것 같습니다. 값을 읽어오는 것은 beautifulsoup로 해야하는 부분이구요. soup.find(“button”, {“title”:”11″}) # 11 사이즈 button 태그 가져오기.
      대략 이렇게 태그를 찾아오고..
      그 태그의 data-url 이 null 이면 품절로 판단하면 될것 같습니다.
      막히는 부분 있으시면 부담 갖지 마시고 댓글 주세요.
      감사합니다.

  5. Rich 답글

    안녕하세요?
    유용한 글 감사합니다.

    위 내용대로 따라하다보니 제가 원하는 사이트에서는 품절일때와 재고가 있는 경우 구분이 안되어서 혹시 방법이 있나 해서 문의드립니다.

    – 품절 주소 : https://www.breuninger.com/de/marken/canada-goose/daunenweste/1001069636/p/?variant=27a9051515d5cfc53e67ea736914d2b3
    – 재고 주소 : https://www.breuninger.com/de/marken/canada-goose/daunenweste/1001069636/p/?variant=c27ae499f268502fab73aaacecc5b1ca

    사이즈나 색상에 따라 사이트 주소가 달라지는것 같구요..
    html을 읽어온 후 find를 사용해 div class=”bewerten-stock-information”을 찾은 후 하위에 span class를 찾았습니다. 그런데 이때 아래와 같이 품절인 경우와 재고가 있는 경우에 모두 span class가 존재하게 나와서 구분이 불가하더라구요..

    – 품절인 경우 : span class=”bewerten-stock-information__out-of-stock”
    – 재고 있는 경우 : span class=”bewerten-stock-information__availability”

    이 사이트에서 색상이나 사이즈에 따라 품절과 품절이 아닌 경우를 구분할 수 있는 방법이 있을까요??

    그리고 위에 알려주신 코드로 실행하게되면 ‘품절 -> 재고 있음’ 에서 텔레그램으로 알림이 오고, 반대로 ‘재고 있음 -> 품절’에서도 알림이 오더라구요. Status가 True로 바꼈다고 오구요. 품절에서 재고 있음으로 바꼈을때만 알림이 오게 수정하려면 어떻게 해야할까요??

    답변 부탁드립니다! 감사합니다!

    • samsee 글쓴이답글

      사이트 확인해 보았습니다. vue로 작성되어 있는 것 같아요. BeautifulSoup으로는 스크래핑이 어려울 것 같습니다. 스크립트를 실행해야 해서요. selenium 같은 headless browser로 하셔야 가능해 보입니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다