0

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)
Joe Ferndz
  • 8,417
  • 2
  • 13
  • 33
TVXD
  • 33
  • 9
  • Why is there an = addbutton in the middle of each line? – Arundeep Chohan Feb 20 '21 at 19:49
  • I followed a tutorial and assumed there had to be an addbutton every time. (The tutorial only showed the first part, I did the rest) Should I remove those? – TVXD Feb 20 '21 at 20:08
  • 1
    Yeah they don't do anything. – Arundeep Chohan Feb 20 '21 at 20:14
  • Couple of aside notes about the code - you can shorthand the clicking actions in one line by doing `browser.find_element_by_class_name('btn-primary').click()`. and I would put the `print` statements *after* the click functions, rather than before – Mangohero1 Feb 20 '21 at 20:30

2 Answers2

1

You don't need a "go to cart" button, only a URL "bestbuy.com/cart", I use that for my bot.

Community
  • 1
  • 1
0

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.

Mangohero1
  • 1,832
  • 2
  • 12
  • 20
  • Another problem you might run into is that the selectors are right, but they are going to fast for the browser. Ideally, it's a good idea to add an **implicit wait** so that it can wait for an element to be found or a command to complete. To do this, just put `browser.implicitly_wait(10)` (10 being the number of seconds to wait) right under the line where `browser` was defined. – Mangohero1 Feb 20 '21 at 20:37
  • I'd suggest swapping over to webdriver waits. Massive improvement in time than using implicit. – Arundeep Chohan Feb 20 '21 at 20:47
  • explicit waits are fine too -- I just prefer to use implicit wait in this case since given the size and scope of the code, it's not all too complicated – Mangohero1 Feb 20 '21 at 20:49
  • New Code failed. goToCartBtn = browser.find_element_by_class_name(".go-to-cart-button .btn-secondary") time.sleep(5) print("Go To Cart button was clicked.") goToCartBtn.click() – TVXD Feb 20 '21 at 23:29
  • 1
    @TVXD the code should be `find_element_by_css_selector` not `find_element_by_class_name` – Mangohero1 Feb 20 '21 at 23:52
  • still doesn't work, now the terminal logs are too long for me to post (somehow the fix made the logs longer?) EDIT: WAIT NEVERMIND IT WORKED BY ADDING A DELAY! TYSM, MY BRAIN CAN FINALLY REST – TVXD Feb 20 '21 at 23:56