1

I'm trying to gather price information for each product variation from this web page: https://www.safetysign.com/products/7337/ez-pipe-marker

I'm using Selenium and FireFox with Python 3 and Windows 10.

Here is my current code:

driver = webdriver.Firefox()
driver.get('https://www.safetysign.com/products/7337/ez-pipe-marker')
#frame = driver.find_element_by_class_name('product-dual-holder')
# driver.switch_to.frame('skuer5c866ddb91611')
# driver.implicitly_wait(5)
driver.find_element_by_id('skuer5c866ddb91611-size-label-324').click()   
price = driver.find_element_by_class_name("product-pricingnodecontent product-price-content").text.replace('$', '')
products.at[counter, 'safetysign.com Price'] = price
print(price)
print(products['safetysign.com URL'].count()-counter)

So, I'm trying to start by just selecting the first product variation by id (I've also tried class name). But, I get an Unable to locate element error. As suggested in numerous SO posts, I tried to change frames (even though I can't find a frame tag in the html that contains this element). I tried switching to different frames using index, class name, and id of different div elements that I thought might be a frame, but none of this worked. I also tried using waits, but that return the same error.

Any idea what I am missing or doing wrong?

1
  • Which element - name it please ? Commented Mar 11, 2019 at 15:01

2 Answers 2

1

To locate the elements you have to induce WebDriverWait for the visibility_of_all_elements_located() and you can create a List and iterate over it to click() each item and you can use the following solution:

  • Code Block:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    
    driver=webdriver.Firefox(executable_path=r'C:\Utility\BrowserDrivers\geckodriver.exe')
    driver.get("https://www.safetysign.com/products/7337/ez-pipe-marker")
    for product in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//form[@class='product-page-form']//div[@class='sku-contents']//following::ul[1]/li//label[starts-with(@for, 'skuer') and contains(., 'Pipe')]"))):
        WebDriverWait(driver, 20).until(EC.visibility_of(product)).click()
    driver.quit()
    
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer, but I have two problems. One, I'm using Firefox and can't figure out how to set the same options as you have done for Chrome. Second, when I run the code without those options, I get a TimeoutException error that just reads 'Message: '
@JarodJacobs Check out the updated answer and let me know the status.
0

They may well be dynamic. Select by label type selector instead and index to click on required item e.g. 0 for the item you mention (first in the list). Also, add a wait condition for labels to be present.

If you want to limit to just those 5 size choices then use the following css selector instead of label :

.sku-contents ul:nth-child(3) label

i.e.

sizes = WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".sku-contents ul:nth-child(3) label")))
sizes[0].click()

After selecting size you can grab the price from the price node depending on whether you want the price for a given sample size e.g. 0-99.

To get final price use:

.product-under-sku-total-label

Code:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
url = 'https://www.safetysign.com/products/7337/ez-pipe-marker'
driver = webdriver.Chrome()
driver.get(url)
labels = WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "label")))
labels[0].click()
price0to99 = driver.find_element_by_css_selector('.product-pricingnodecontent').text
priceTotal = driver.find_element_by_css_selector('.product-under-sku-total-label').text
print(priceTotal, price0To99)
# driver.quit()

4 Comments

thanks for the answer! This works for getting the different sizes, but I can't access the price for each size. I think it is the same issue I had with accessing the sizes (they seem to be dynamic), so I tried using the CSS_SELECTOR approach, but get a timeoutexception error. For the price, I used "price = WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "div[id=skuer5c866ddb91611-total-price]")))" I've never used CSS selector before, so I'm pretty sure I just doing it wrong.
use .product-pricingnodecontent I have updated answer for you to show price for 0-99 etc.... use .product-under-sku-total-label for total.
Any problems let me know.
While the answer answers seem to work (or will work if I were to adjust a few things, I, I went with this answer because it seemed the cleanest to me. Thanks @QHarr!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.