개발자식

[크롤링] BeautifulSoup, Wadis 마감 상품 재고 체크 & 메일 발송 크롤링 본문

Data/Python

[크롤링] BeautifulSoup, Wadis 마감 상품 재고 체크 & 메일 발송 크롤링

밍츠 2022. 3. 30. 00:21

Wadis 상품 목록에서 마감 상품 재고를 확인하고, 

재고가 있다면 메일을 발송하는 실습 예제이다.

 

크롤링 사이트 : https://www.wadiz.kr/web/campaign/detail/140132

 

킥스타터 20억 달성ㅣ하루4분, 1시간 런닝효과! 다이어트혁명 몽키360

단 4분만에 완성하는 다이어트 루틴/따라만하면 되는 너무 쉬운 앱/미국 NO.1 펀딩 플랫폼 킥스타터에서 20억을 달성하고 한국에 상륙한 MONKII 360을 지금 만나보세요!

www.wadiz.kr


1. 사이트 분석

 

 

 

사이트를 보면 오른쪽에 펀딩 할 수 있는 항목들이 보인다.

판매가 불가능한 항목들은 마우스를 갖다 대면 "제한수량이 모두 펀딩 되었습니다."라고 뜨고,

가능한 항목들은 "이 리워드 펀딩하기"라고 뜬다.

 

 

 

 

2. 웹 크롤링

 

import time
from urllib.request import urlopen 
from bs4 import BeautifulSoup

 

url = 'https://www.wadiz.kr/web/campaign/detail/140132'

webpage = urlopen(url)
source = BeautifulSoup(webpage, 'html.parser')

 

- print(url)을 실행하면 url로 바로 접속할 수 있는 링크가 뜬다.

- html.parser로 파싱을 진행한다.

 

 

펀딩 항목들을 크롬 개발자 모드로 분석해보면 각 항목들은 button 태그로 이루어져 있다.

 

#버튼 전체
target = source.find_all('button', {'class':'rightinfo-reward-list'})
print("button태그 개수 : ",len(target))
print(target[0])

 

결과 :

 

button태그 개수 :  7
<button class="rightinfo-reward-list ing" onclick="backMoney('332629', 'false')">
<div class="top-info">
<dl class="reward-info">
<dt>
                        199,000원 펀딩
                      </dt>
<dd>
<p class="reward-name">[슈퍼 얼리버드] MONKII 360 본체+악세사리+APP (그린)</p>
<p>미국 출시가 : 299달러 (370,000원) <br/>와디즈가 : 199,000원<br/>--&gt;약 50% 혜택을 놓치지 마세요 !<br/><br/><br/>MONKII 360 본체 x 1 (그린)<br/>DynaForce 번지 x 2 (스타터 번지 x 1 + 카디오 번지 x 1)<br/>MassCore 2파운드 (0.91kg)<br/>MONKII 어플 (21 days Habit/36 days Challenge/36 days Cardio 외 여러가지 운동 프로그램) </p>
</dd>
</dl>
<ul class="data-info">
<li class="shipping" style="width: 100%; margin-bottom: 5px;">
                        배송비
                        
                          
                          
                            <em>3,000원</em>
</li>
<li class="date" style="width: 100%;">리워드 발송 시작일
                      
                      
                        <em>2022년 06월 중순 (11~20일) 예정</em>
</li>
</ul>
<p class="reward-qty">제한수량 <strong>150</strong>개   <em>현재 81개 남음!</em></p>
<p class="reward-soldcount">총 <strong>69</strong>개 펀딩완료</p>
</div>
<p class="hover-text">이 리워드 펀딩하기</p>
</button>

 

button 태그가 7개로 사이트 펀딩 항목 개수와 같다.

펀딩 항목은 판매 여부에 따라 위치가 바뀌기 때문에 인덱스로 접근하는 것은 정확하지 않다.

 

펀딩 항목들을 보면 각 가격(슈퍼 얼리버드, 얼리버드 등)과, 색깔로 구분할 수 있다.

-> 가격 & 색깔로 크롤링 해보자

 

 

 

 

가격 : button태그 내의 dt 태그

색깔 : button태그 내의 p 태그

완판 여부 : button 태그의 class 속성 3개 (soldout 속성 추가됨)

 

 

 

 

가격 : 179,000 & 색깔 : 블루 상품을 판매하는지 확인하는 코드 

 

for item in target:
    if "179,000" in item.find("dt").get_text().strip():
        if '블루' in item.find("p").get_text().strip():
            if len(item.attrs["class"]) == 2:
                print("판매합니다")

 

-> target은 bs4.element.ResultSet으로 반복문을 이용해서 하나씩 접근하지 않으면 "ResultSet object has no attribute ~~" 에러가 뜬다.

 

 

참고 :

for item in target:
    print("가격 : ",item.find("dt").get_text().strip())
    print("색깔 : ",item.find("p").get_text().strip())
    print(item.attrs["class"])

 

결과 :

 

가격 :  199,000원 펀딩
색깔 :  [슈퍼 얼리버드] MONKII 360 본체+악세사리+APP (그린)
['rightinfo-reward-list', 'ing']
가격 :  199,000원 펀딩
색깔 :  [슈퍼 얼리버드] MONKII 360 본체+악세사리+APP (블루)
['rightinfo-reward-list', 'ing']
가격 :  199,000원 펀딩
색깔 :  [슈퍼 얼리버드] MONKII 360 본체+악세사리+APP (오랜지)
['rightinfo-reward-list', 'soldout', 'ing']
가격 :  219,000원 펀딩
색깔 :  [얼리버드] MONKII 360 본체+악세사리+APP (블루)
['rightinfo-reward-list', 'ing']
가격 :  179,000원 펀딩
색깔 :  [울트라 얼리버드] MONKII 360 본체+악세사리+APP (그린)
['rightinfo-reward-list', 'soldout', 'ing']
가격 :  179,000원 펀딩
색깔 :  [울트라 얼리버드] MONKII 360 본체+악세사리+APP (블루)
['rightinfo-reward-list', 'soldout', 'ing']
가격 :  179,000원 펀딩
색깔 :  [울트라 얼리버드] MONKII 360 본체+악세사리+APP (오랜지)
['rightinfo-reward-list', 'soldout', 'ing']

 

 

3. 메일 보내기

 

원하는 펀드 상품 조건을 설정하고, 판매한다면 나에게 메일을 보내보자

 

구글 메일을 사용하고 아래와 같은 절차를 진행해야 한다.

  1. 크롬에서 https://myaccount.google.com/security 접속한다.
  2. 구글 계정에 로그인한다. (개인 구글 계정)
  3. 2단계 인증을 활성화하고 앱 비밀번호에서 메일/Windows 컴퓨터로 생성한다.

 

import smtplib
from email.mime.text import MIMEText

def sendMail(sender, receiver, msg):
    smtp = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    smtp.login(sender, '?????') # 위 사전 세팅에서 얻어진 16글자의 [구글 계정 앱 비밀번호]를 '?????'에 입력해주세요.
    
    msg = MIMEText(msg)
    msg['Subject'] = 'Product is available!'
    
    smtp.sendmail(sender, receiver, msg.as_string())
    smtp.quit()

 

-smtplib (SMTP + lib)는 파이썬을 사용하여 SMTP 프로토콜을 사용하여 메일을 보낼 수 있게 해주는 라이브러리-> SMTP : 인터넷에서 메일을 주고받기 위한 전송 규약 및 프로토콜이다.

- smtplib.SMTP_SSL('smtp.gmail.com', 465) : SMTP 인스턴스를 통해 STMP를 연결한다.

- TLS 방식 사용 포트번호 : 587 / SSL 방식 사용 포트번호 : 465 (보안 설정 방식)

 

-MIME : 전자우편을 위한 인터넷 표준 포맷

- smtp.sendmail(sender, receiver, msg.as_string()) :

  • sender : 보내는 이메일 주소
  • receiver : 받는 이메일 주소
  • msg.as_string() : 메일 내용 (본문)

이 들어간다.

 

 

코드를 통해 원하는 메일을 보내보자

 

check_status = 1

while check_status: # check_status == 1, 0이되면 종료

    webpage = urlopen(url)
    source = BeautifulSoup(webpage, 'html.parser')
    target = source.find_all('button', {'class':'rightinfo-reward-list'})

    # item == "button" tag
    for item in target:

        if '179,000' in item.find('dt').get_text().strip():
            # print(item.find('dt').get_text().strip())

            if '블루' in item.find('p').get_text().strip():
                # print(item.find('p').get_text().strip())

                if len(item.attrs['class']) == 2: #매진 : 3, 매진x :2
                    # print(len(item.attrs['class']))
                    sendMail('~~@gmail.com', '~~@gmail.com', '99800 Available \n https://goo.gl/wG8v1F%27')
                    check_status = 0

    time.sleep(10)

 

결과 :

 

 

 

 

Comments