[O] Finish
This commit is contained in:
+43
-11
@@ -1,5 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
|
import traceback
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from selenium.webdriver import Chrome
|
from selenium.webdriver import Chrome
|
||||||
@@ -29,12 +32,29 @@ MODELS = [
|
|||||||
]
|
]
|
||||||
USD_TO_CAD = 1.27
|
USD_TO_CAD = 1.27
|
||||||
AVAIL_TABLE: dict[str, bool] = {}
|
AVAIL_TABLE: dict[str, bool] = {}
|
||||||
|
TITLE_SHORTEN = re.compile('(rtx|nvidia|geforce|edition|gddr[56]x*|video|card)', flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
|
def shorten_title(title: str):
|
||||||
|
short_title = TITLE_SHORTEN.sub('', title)
|
||||||
|
while ' ' in short_title:
|
||||||
|
short_title = short_title.replace(' ', ' ')
|
||||||
|
return short_title.strip()
|
||||||
|
|
||||||
|
|
||||||
|
def send_message(msg: str):
|
||||||
|
r = requests.get(f'https://api.telegram.org/bot{TG_TOKEN}/sendMessage',
|
||||||
|
params={'chat_id': TG_RECEIVER, 'parse_mode': 'Markdown', 'text': msg})
|
||||||
|
|
||||||
|
if r.status_code != 200:
|
||||||
|
print('Request not OK:', r.status_code, r.text)
|
||||||
|
|
||||||
|
|
||||||
def parse_page(browser: Chrome):
|
def parse_page(browser: Chrome):
|
||||||
# Parse page
|
# Parse page
|
||||||
for item in browser.find_elements(By.CLASS_NAME, 'x-productListItem'):
|
for item in browser.find_elements(By.CLASS_NAME, 'x-productListItem'):
|
||||||
title = item.find_element(CSS, 'div[data-automation="productItemName"]').get_attribute('innerHTML')
|
title = item.find_element(CSS, 'div[data-automation="productItemName"]').get_attribute('innerHTML')
|
||||||
|
title = shorten_title(title)
|
||||||
|
|
||||||
# Check availability
|
# Check availability
|
||||||
avail = item.find_elements(CSS, 'div[data-automation="store-availability-messages"] span[data-automation="store-availability-checkmark"]')
|
avail = item.find_elements(CSS, 'div[data-automation="store-availability-messages"] span[data-automation="store-availability-checkmark"]')
|
||||||
@@ -42,10 +62,14 @@ def parse_page(browser: Chrome):
|
|||||||
# Not available, check if it was previously available
|
# Not available, check if it was previously available
|
||||||
if len(avail) == 0:
|
if len(avail) == 0:
|
||||||
if title in AVAIL_TABLE:
|
if title in AVAIL_TABLE:
|
||||||
# TODO: Feedback
|
send_message(f'Sold out: `{title}`')
|
||||||
del AVAIL_TABLE[title]
|
del AVAIL_TABLE[title]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Already sent availability message
|
||||||
|
if title in AVAIL_TABLE:
|
||||||
|
continue
|
||||||
|
|
||||||
# Get price
|
# Get price
|
||||||
price = item.find_element(CSS, 'div[data-automation="product-pricing"] > span > div').get_attribute('innerHTML')
|
price = item.find_element(CSS, 'div[data-automation="product-pricing"] > span > div').get_attribute('innerHTML')
|
||||||
price = round(float(price.replace(',', '')[1:]))
|
price = round(float(price.replace(',', '')[1:]))
|
||||||
@@ -66,13 +90,17 @@ def parse_page(browser: Chrome):
|
|||||||
if price_incr > INCR_MAX:
|
if price_incr > INCR_MAX:
|
||||||
print(' '.join(title.split()[:2]), f'is in stock but price increase {price_incr * 100:.0f}% '
|
print(' '.join(title.split()[:2]), f'is in stock but price increase {price_incr * 100:.0f}% '
|
||||||
f'is larger than defined threshold.')
|
f'is larger than defined threshold.')
|
||||||
continue
|
# continue
|
||||||
|
|
||||||
|
# Find link
|
||||||
|
link = item.find_element(CSS, 'a').get_attribute('href')
|
||||||
|
|
||||||
# Available and meets threshold criteria, notify user
|
# Available and meets threshold criteria, notify user
|
||||||
AVAIL_TABLE[title] = True
|
AVAIL_TABLE[title] = True
|
||||||
|
send_message(f'{model[0].upper()} Became Available!\n'
|
||||||
print(model)
|
f'\n'
|
||||||
print(title)
|
f'${price:.0f} | {price_incr * 100:.0f}% Incr | Value: {value:.0f}\n'
|
||||||
|
f'- [{title}]({link})')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@@ -82,11 +110,15 @@ if __name__ == '__main__':
|
|||||||
browser = Chrome(options=web_options)
|
browser = Chrome(options=web_options)
|
||||||
browser.get('https://www.bestbuy.ca/en-ca/collection/graphics-cards-with-nvidia-chipset/349221')
|
browser.get('https://www.bestbuy.ca/en-ca/collection/graphics-cards-with-nvidia-chipset/349221')
|
||||||
|
|
||||||
parse_page(browser)
|
# parse_page(browser)
|
||||||
browser.close()
|
# browser.close()
|
||||||
|
|
||||||
# Refresh indefinitely
|
# Refresh indefinitely
|
||||||
# while True:
|
while True:
|
||||||
# parse_page(browser)
|
try:
|
||||||
# time.sleep(5)
|
parse_page(browser)
|
||||||
# browser.refresh()
|
except Exception as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
time.sleep(5)
|
||||||
|
browser.refresh()
|
||||||
|
time.sleep(2)
|
||||||
|
|||||||
Reference in New Issue
Block a user