Search code examples
python-3.xseleniumselenium-chromedriverbest-buy-api

My auto-buying code for BestBuy isn't working... why?


I've been trying to get this code to work, but it just won't. (The link is a placeholder, I'm planning on changing it to a 3060 Ti to get one for a home rig.) It also says the goToCartBtn was clicked, but it wasn't.

import time
from selenium import webdriver
#For using chrome
browser = webdriver.Chrome('/Users/admin/Downloads/chromedriver')

#BestBuy RTX 3060 Ti webpage
browser.get('https://www.bestbuy.com/site/nvidia-geforce-rtx-nvlink-bridge-for-3090-cards-space-gray/6441554.p?skuId=6441554')


buyButton = False 

while not buyButton:
try:
    #If this works, then the button is not pytopen
    addToCartBtn = addButton = browser.find_element_by_class_name("btn-disabled")

    #Button isn't open, restart the script
    print("Button isn't ready yet.")

    #Refresh page after a delay
    time.sleep(1)
    browser.refresh()

except:

    addToCartBtn = addButton = browser.find_element_by_class_name("btn-primary")

    #Click the button 
    print("Button was clicked.")
    addToCartBtn.click()
    
    goToCartBtn = addButton = browser.find_element_by_class_name("btn-secondary")

    print("Go To Cart button was clicked.")
    goToCartBtn.click()

    checkoutBtn = addButton = browser.find_element_by_class_name("btn-lg")

    print("Checkout button clicked.")
    checkoutBtn.click()
    buyButton = True

Error Message shown below:

Terminal Logs (if needed):
Button was clicked.
Go To Cart button was clicked.
Traceback (most recent call last):
  File "SniperBot.py", line 15, in <module>
    addToCartBtn = addButton = browser.find_element_by_class_name("btn-disabled")
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 564, in find_element_by_class_name
    return self.find_element(by=By.CLASS_NAME, value=name)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".btn-disabled"}
  (Session info: chrome=88.0.4324.182)


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "SniperBot.py", line 35, in <module>
    goToCartBtn.click()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 80, in click
    self._execute(Command.CLICK_ELEMENT)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
  (Session info: chrome=88.0.4324.182)

Solution

  • Your goToCartButton selector is not specific enough.

     goToCartButton = browser.find_element_by_class_name('btn-secondary')
    

    Using this selector returns five elements, and Selenium will only interact with the first one it finds, which according to the DOM, isn't the "Go to Cart" button.

    Instead, you could use a CSS selector to return the specific element. Using CSS:

    goToCartButton = browser.find_element_by_css_selector('.go-to-cart-button .btn-secondary')
    

    And you should be able to click the button now.