아내가 sony 카메라를 엄청 갖고 싶어 하는데 최근 반도체 이슈 때문에 물량이 없어서 구할 수가 없었다..
물론 플미가에 사면 가능하지만 그 정도로 급한 건 아니기에 포기 상태였다
고민하다가 크롤링을 공부도 할겸 입고 알림봇을 만들어보게 되었다
파이썬이 아무래도 요즘 잘나간다고하니 Java는 잠시 내려놓고 파이썬으로 개발해보았다
처음 써보는 언어라 구조나 문법도 잘 몰라서 굉장히 허접하게 완성되었...
그래도 뭐 언어가 다 비슷비슷해서 실행만 되는 수준으로 만들기에는 어려운 점은 딱히 없었다
찾아보니 알림봇은 텔레그램으로 많이 해서 고민하다가 난 잘 쓰지도 않는 앱이고 카톡으로 알림 받는 게 더 편할 것 같아서 카톡으로 결정했다
카카오톡 개발자 설정은 다 패스하고 본 코드만 업로드 정리하려고 한다
1. 라이브러리 선언
import json
import requests
import datetime
# 크롤링
from bs4 import BeautifulSoup
# 크롤링 시 페이지 로드 완료 후 가져올 수 있도록
from selenium import webdriver
# 스케쥴러
from apscheduler.schedulers.blocking import BlockingScheduler
2. 상품 구매 가능 여부 정보 크롤링
# 주문 가능 여부 확인
def stock_check(name, url):
chrome_driver_dir = './chromedriver'
# 옵션 생성
options = webdriver.ChromeOptions()
# 창 숨기는 옵션 추가
options.add_argument("headless")
# 크롬 driver 실행
driver = webdriver.Chrome(chrome_driver_dir, options=options)
driver.implicitly_wait(10) # 버튼이 로딩 후 변경되므로 여유있게 10초 기다리기
driver.get(url)
html = driver.page_source
# 해당 url의 html문서를 soup 객체로 저장
soup = BeautifulSoup(html, 'html.parser')
search_result = soup.select_one(
'#root > div > div > div.contents.product > div > div.product_view_main > form > div > div.cont.prd_select_wrap.false > div.result_btn_inner > div > ul > li.final > a')
if search_result is not None:
if search_result.text != "일시품절":
kakaotalk_message_send(name, url)
# driver 종료
driver.quit()
처음에는 BeautifulSoup 만 사용해서 크롤링을 시도했었다
아무리 해도 요소를 제대로 못 찾길래 이상하다 싶어서 디버깅해보니 html 페이지 정보를 제대로 못 가져오고 있었다!
확인해보니 페이지가 로딩되기 전에 페이지를 파싱 해버려서 문제가 되었다
selenium 라이브러리를 통해서 로딩이 완료된 페이지 정보를 가져올 수 있었다
해당 사이트는 버튼이 모두 로딩되고 난 뒤에 버튼 상태를 품절 상태로 변경하는 구조였기 때문에 로딩 여유 시간을 10초로 두고 개발했다
selenium 라이브러리를 사용하면 특정 ID값이 생성될 때까지 대기시키는 등 여러 조건이 있었지만 현재 크롤링하고자 하는 웹페이지는 해당사항이 없어서 넘어갔음
해당 사이트를 크롤링하고 버튼이 '일시품절' 상태가 아닐 때 카카오톡 메시지를 보내도록 코드를 짰다
아 selenium을 사용하려면 브라우저 드라이버가 필요했다 본인 환경에 맞는 드라이버를 설치하면 됨
[chrome 드라이버 다운로드 페이지] - 윈도우 64bit는 없어서 32bit로 사용했는데 동작 잘되었음
https://chromedriver.chromium.org/downloads
3. 카카오톡 알림 메시지 전송
# 카카오톡 메세지 보내기
def kakaotalk_message_send(name, url):
KAKAO_TOKEN = '토큰'
send_url = "https://kapi.kakao.com/v2/api/talk/memo/default/send" # 나에게 보내기 주소
header = {"Authorization": 'Bearer ' + KAKAO_TOKEN}
data = {
"template_object": json.dumps({
"object_type": "text",
"text": "무친 " + name + " 입고됐다고 어서 궈햇\n" + url,
"link": {
"web_url": url,
"mobile_web_url": url
},
"button_title": "바로 확인"
})
}
return requests.post(send_url, headers=header, data=data)
해당 상품의 이름과 구매 url을 보내주는 방식으로 설계했다
아주 간단!
4. 스케줄러 동작
# 배치 목록
def batch_list():
# ZV-E10
name = 'ZV-E10'
url = 'https://store.sony.co.kr/product-view/102263902'
stock_check(name, url)
# ZV-E10L
name = 'ZV-E10L'
url = 'https://store.sony.co.kr/product-view/102263904'
stock_check(name, url)
# ZV-E1
#name = 'ZV-E1'
#url = 'https://store.sony.co.kr/product-view/102263855'
#stock_check(name, url)
def main():
# 스케줄러 3분마다 실행
repetitionTimeMinutes = 3
sched = BlockingScheduler(timezone='Asia/Seoul')
sched.add_job(batch_list,'interval', minutes=repetitionTimeMinutes)
sched.start()
main()
3분마다 체크하도록 설정했다
2개의 상품만 확인하면 돼서 목록에서 찾을까 하다가 상품페이지에서 하는 게 더 확실할 것 같아서 상품페이지에서 크롤링하도록 개발했다
파이썬 개발은 처음이라 메인을 어떤 식으로 코드를 구성하는 게 좋은지 잘 몰라서..
우선 깔끔해 보이도록 짰는데 이 부분은 추 후에 기능 개선하면서 같이 고도화해도 좋을 것 같음
일단은 잘 동작한다!
'개발 지식 > Etc.' 카테고리의 다른 글
H2 DataBase 초기 접속 (0) | 2022.06.09 |
---|---|
ngrok - 외부에서 사내 IP 환경 접속 시 (0) | 2022.03.31 |
[jQuery] 마우스 우클릭 이벤트 (0) | 2021.01.28 |