Я пытаюсь собрать информацию о ценах для каждого варианта продукта на этой веб-странице: https://www.safetysign.com/products/7337/ez-pipe-marker.
Я использую Selenium и FireFox с Python 3 и Windows 10.
Вот мой текущий код:
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, я попытался изменить фреймы (хотя я не могу найти тег фрейма в html, который содержит этот элемент). Я попытался переключиться на разные фреймы, используя индекс, имя класса и идентификатор разных элементов div, которые, как я думал, могут быть фреймом, но ничего из этого не сработало. Я также пытался использовать ожидания, но они возвращают ту же ошибку.
Любая идея, что мне не хватает или я делаю неправильно?






Они вполне могут быть динамичными. Вместо этого выберите селектор типа label и индексируйте, чтобы щелкнуть нужный элемент, например. 0 для пункта, который вы упомянули (первый в списке). Кроме того, добавьте условие ожидания для присутствия labels.
Если вы хотите ограничиться только этими 5 вариантами size, используйте следующий селектор css вместо label:
.sku-contents ul:nth-child(3) label
то есть
sizes = WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".sku-contents ul:nth-child(3) label")))
sizes[0].click()
После выбора размера вы можете получить цену из ценового узла в зависимости от того, хотите ли вы цену для данного размера выборки, например. 0-99.
Для получения окончательной цены используйте:
.product-under-sku-total-label
Код:
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()
Спасибо за ответ! Это работает для получения разных размеров, но я не могу получить доступ к цене для каждого размера. Я думаю, что это та же проблема, что и у меня с доступом к размерам (они кажутся динамическими), поэтому я попытался использовать подход CSS_SELECTOR, но получил ошибку исключения тайм-аута. Для цены я использовал «price = WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, «div[id=skuer5c866ddb91611-total-price]»)))». никогда раньше не использовал селектор CSS, поэтому я уверен, что просто делаю это неправильно.
используйте .product-pricingnodecontent Я обновил ответ для вас, чтобы показать цену для 0-99 и т. д.... используйте .product-under-sku-total-label для общей суммы.
Любые проблемы, дайте мне знать.
Хотя ответы на ответы, похоже, работают (или будут работать, если я изменю несколько вещей, я выбрал этот ответ, потому что он показался мне самым чистым. Спасибо @QHarr!
Чтобы найти элементы, вы должны вызвать WebDriverWait для visibility_of_all_elements_located(), и вы можете создать Список и перебирать его для click() каждого элемента, и вы можете использовать следующее решение:
Блок кода:
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()
Спасибо за ответ, но у меня две проблемы. Во-первых, я использую Firefox и не могу понять, как установить те же параметры, что и вы для Chrome. Во-вторых, когда я запускаю код без этих параметров, я получаю ошибку TimeoutException, которая просто гласит: «Сообщение:».
@JarodJacobs Ознакомьтесь с обновленным ответом и дайте мне знать о статусе.
Какой элемент - назовите его, пожалуйста?