I'm making a bot that buys items from the supreme website using the Selenium library for Python 3.5. The bot can successfully add an item to the cart, but in the checkout process, selenium throws an error whenever it attempts to send keys to an input element found by the find_element_by_id()
method. Here's a simplified version of the code that throws the error:
from selenium import webdriver
d = webdriver.Chrome()
# First it adds an item to the cart
d.get('http://www.supremenewyork.com/shop/tops-sweaters/vxdau6b3t/km1pzdca3')
d.find_element_by_name('commit').click()
# Then it goes to the checkout
d.get('https://www.supremenewyork.com/checkout')
name_box = d.find_element_by_id('order_billing_name')
# This is the line that throws the error
name_box.send_keys('name goes here')
Here's the full error message:
File "error.py", line 7, in <module>
name_box.send_keys('name goes here')
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 479, in send_keys
'value': keys_to_typing(value)})
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 628, in _execute
return self._parent.execute(command, params)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
self.error_handler.check_response(response)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
(Session info: chrome=66.0.3359.181)
(Driver info: chromedriver=2.35.528157 (4429ca2590d6988c0745c24c8858745aaaec01ef),platform=Mac OS X 10.13.3 x86_64)
When I replace the line name_box = d.find_element_by_id('order_billing_name')
with the line d.find_element_by_xpath("//input[@id='order_billing_name']")
the code works as intended. However, this isn't a viable solution as when the element is found this way, the send_keys()
method is very slow.
Let's try to do it correctly (of course there are a lot of things to improve, but I tried to keep it short. Please check the comments inline
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
# First it adds an item to the cart
driver.get('http://www.supremenewyork.com/shop/tops-sweaters/vxdau6b3t/km1pzdca3')
# wait until cart link is available
add_to_cart = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[name=commit]"))
)
# add to cart
add_to_cart.click()
# wait until checkout link is available
go_to_cart = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "div#cart:not(.hidden) a.checkout"))
)
# Then it goes to the checkout
go_to_cart.click()
# wait until name input is available
name_input = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "div.order_billing_name"))
)
# we can't select pseudo elements with css selector, but we can click on an element
# above it, which is defined in "name_input", and emulate keypresses,
# which are intended for the selected ("click()") element only
actions = ActionChains(driver)
actions.move_to_element(name_input).click().send_keys("hey 123").perform()
driver.quit()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With