-
Python smtplib: 원하는 다나와 제품 가격 매일 알림 만들어보기컴퓨터/파이썬 2021. 1. 9. 17:53728x90반응형
smtplib
결과물 미리 보기
매일 내가 원하는 제품의 최저가로 표시된 가격을 구글 지메일로 보낼 것이다.
0. pip 설치
HTML 스크랩을 편하게 하기 위해 beautifulsoup4를 설치한다.
pip install beautifulsoup4
1. 원하는 제품 최저가 표시 가격 불러오기
원하는 다나와 제품의 링크를 복사한다. 예제는 아래 Razer Basilisk Ultimate
requests를 통해 HTML를 불러와서 BeautifulSoup를 이용해서 element를 pick 한다.
import requests headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 9.10; rv:69.0) Gecko/20100101 Firefox/68.0" } URL = "http://prod.danawa.com/info/?pcode=10129599&cate=112787" # 다나와 링크 def getPrice(url=URL) -> str: result = None try: result = requests.get(URL, headers=headers) result.raise_for_status() except requests.exceptions.HTTPError as http: print("HTTP Error:", http) except requests.exceptions.ConnectionError as conn: print("Connection Error:", conn) except requests.exceptions.Timeout as tm: print("Timeout Error:", tm) except requests.exceptions.RequestException as err: print("Something wrong:", err) assert result is not None soup = BeautifulSoup(result.content, "html.parser", from_encoding="iso-8859-1") price = soup.select_one("a.lwst_prc > em.prc_c") return price.text
2. 메일 보내기
메일을 맨 위 결과처럼 사진과 함께 예쁘게 보내기 위해서,
다나와 제품을 캡처해서 py 파일이 있는 곳에 저장한다. (혹은 제품 사진까지 scrap)
바이트 형식으로 읽어야 하며, 예제에선 basil.png이다. (800x590 크기로 지정됨)
메일 형식은 아래와 같다.
제목: [21/월/일] 오늘 "제품" 가격: 0원"
내용: 사진 + 제품 이름과 제품 링크
smtplib + 이미지 첨부해서 메일 보내기
import smtplib from datetime import datetime from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from pytz import timezone FROM = "자신@gmail.com" TO = "자신@gmail.com" PSWD = "FROM 메일의 비밀번호" def sendMail(mail=FROM, password=PSWD): server = smtplib.SMTP("smtp.gmail.com", 587) server.ehlo() server.starttls() server.ehlo() server.login(FROM, PSWD) prd = "Razer Basilisk Ultimate" now = datetime.now(timezone("Asia/Seoul")) nowPrice = f"오늘 {prd} 가격: {getPrice()}원" subject = now.strftime("[%y/%m/%d] ") msg = MIMEMultipart("related") msg["Subject"] = subject + nowPrice # [21/01/09] 오늘 ~ 가격: ~원 msg["From"] = FROM # 발신 msg["to"] = TO # 수신 # 이미지 크기는 알아서 설정 (width=가로, height=세로) html = f"""\ <html> <head></head> <body> <img src="cid:image1" alt="Logo" style="width:800px;height:590px;"><br> <p><h1 style="text-align: center;font-size:20px;"><a href="{URL}" target="_blank" rel="noopener">{prd}</a></h1></p> </body> </html> """ imgSrc = MIMEText(html, "html") msg.attach(imgSrc) with open("basil.png", "rb") as img: msgImg = MIMEImage(img.read()) msgImg.add_header("Content-ID", "<image1>") msg.attach(msgImg) server.sendmail(FROM, TO, msg.as_string()) server.quit()
3. 매일 실행하기
더보기import smtplib import time from datetime import datetime from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import requests from bs4 import BeautifulSoup from pytz import timezone FROM = "FROM@gmail.com" TO = "TO@gmail.com" PSWD = "PWD" URL = "http://prod.danawa.com/info/?pcode=10129599&cate=112787" headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 9.10; rv:69.0) Gecko/20100101 Firefox/68.0" } def getPrice(url=URL) -> str: result = None try: result = requests.get(URL, headers=headers) result.raise_for_status() except requests.exceptions.HTTPError as http: print("HTTP Error:", http) except requests.exceptions.ConnectionError as conn: print("Connection Error:", conn) except requests.exceptions.Timeout as tm: print("Timeout Error:", tm) except requests.exceptions.RequestException as err: print("Something wrong:", err) assert result is not None soup = BeautifulSoup(result.content, "html.parser", from_encoding="iso-8859-1") price = soup.select_one("a.lwst_prc > em.prc_c") return price.text def sendMail(mail=FROM, password=PSWD): server = smtplib.SMTP("smtp.gmail.com", 587) server.ehlo() server.starttls() server.ehlo() server.login(FROM, PSWD) prd = "Razer Basilisk Ultimate" now = datetime.now(timezone("Asia/Seoul")) nowPrice = f"오늘 {prd} 가격: {getPrice()}원" subject = now.strftime("[%y/%m/%d] ") msg = MIMEMultipart("related") msg["Subject"] = subject + nowPrice # [21/01/09] 오늘 ~ 가격: ~원 msg["From"] = FROM # 발신 msg["to"] = TO # 수신 html = f"""\ <html> <head></head> <body> <img src="cid:image1" alt="Logo" style="width:800px;height:590px;"><br> <p><h1 style="text-align: center;font-size:20px;"><a href="{URL}" target="_blank" rel="noopener">{prd}</a></h1></p> </body> </html> """ imgSrc = MIMEText(html, "html") msg.attach(imgSrc) with open("basil.png", "rb") as img: msgImg = MIMEImage(img.read()) msgImg.add_header("Content-ID", "<image1>") msg.attach(msgImg) server.sendmail(FROM, TO, msg.as_string()) server.quit() if __name__ == "__main__": while True: sendMail() time.sleep(60 * 60 * 24)
AWS EC2를 이용하거나 매일 컴퓨터 켜놓거나, cronjob을 이용해서 컴퓨터 켤 때마다 보내게 하면 된다.
AWS EC2를 이용하게 되면 그냥 아래 명령어로 실행해놓고 끄면 된다.
백그라운드에서 계속 실행
if __name__ == "__main__": while True: sendMail() time.sleep(60 * 60 * 24)
terminal
nohup python danawa.py &
오류 상황
만약 Username and password not accepted 에러가 뜨면, 발신(FROM) 메일의 보안 수준을 낮춰야 한다.
아래 들어가서 사용함으로 변경
728x90'컴퓨터 > 파이썬' 카테고리의 다른 글
Python 3.10 미리보기 (switch case) (0) 2021.01.11 Python: 무료 Cloud Flask 서버 만들기 (AWS EC2 + S3) (3) 2020.12.26 Python: Popen 백그라운드 실행 및 로그 읽기 (linux) (0) 2020.12.22