перебирая выпадающее меню с помощью Selenium и Python - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь перебрать выпадающее меню по этому адресу: https://www.accuform.com/safety-sign/danger-danger-authorized-personnel-only-MADM006

Так, например, первое выпадающее меню - в разделе параметров - перечисляет различные материалы, и я хочу выбрать каждыйодин по очереди, а затем собрать некоторую другую информацию с веб-страницы, прежде чем перейти к следующему материалу.Вот мой текущий код:

driver = webdriver.Firefox()
driver.get('https://www.accuform.com/safety-sign/danger-danger-authorized-personnel-only-MADM006')

time.sleep(3)

driver.find_element_by_id('x-mark-icon').click()

select = Select(driver.find_element_by_name('Wiqj7mb4rsAq9LB'))
options = select.options
optionsList = []

driver.find_elements_by_class_name('select-wrapper')[0].click()

element = driver.find_element_by_xpath("//select[@name='Wiqj7mb4rsAq9LB']")
actions = ActionChains(driver)
actions.move_to_element(element).perform()

# driver.execute_script("arguments[0].scrollIntoView();", element)


for option in options: #iterate over the options, place attribute value in list
    optionsList.append(option.get_attribute("value"))

for optionValue in optionsList:
    print("starting loop on option %s" % optionValue)
    # select = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[@name='Wiqj7mb4rsAq9LB']")))
    # select = Select(select)
    select.select_by_value(optionValue)

Я начал только с цикла, но получил эту ошибку:

ElementNotInteractableException: Message: Element <option> could not be scrolled into view

Затем я добавил webdriverwait и получил ошибку TimeoutException.

Затем я понял, что, вероятно, мне следует нажать на оболочку, в которой удерживается раскрывающийся список, поэтому я добавил щелчок, который вызывает меню, но я все еще получил исключение TimeoutException.

Итак, я подумал, может быть, мне следует перейти к элементу, который я пробовал со строками цепочки действий, и получил эту ошибку

WebDriverException: Message: TypeError: rect is undefined

Я пытался избежать этой ошибки, используя этот кодвместо этого:

    # driver.execute_script("arguments[0].scrollIntoView();", element)

Что снова привело к исключению timeoutexception.

Я довольно новичок в Python и Selenium и в основном только что модифицировал код из SO-ответов на подобные вопросы, но ничего не помогло,

Я использую Python 3.6 и текущие версии Selenium и Firefox WebDriver.

Если что-то неясно или вам нужна дополнительная информация, просто дайте мне знать.

Спасиботак много!

РЕДАКТИРОВАТЬ: Основываясь на ответе и комментариях Каджал Кунды, я обновил свой код следующим образом:

`material_dropdown = driver.find_element_by_xpath("//input[@class='select- 
dropdown']")

driver.execute_script("arguments[0].click();", material_dropdown)

materials=driver.find_elements_by_css_selector("div.select-wrapper 
ul.dropdown-content li")



for material in materials:

    # material_dropdown = 
    driver.find_element_by_xpath("//input[@class='select-dropdown']")

    # driver.execute_script("arguments[0].click();", material_dropdown)

    # materials=driver.find_elements_by_css_selector("div.select-wrapper ul.dropdown-content li")

    material_ele=material.find_element_by_tag_name('span')

if material_ele.text!='':

    material_ele.click()

    time.sleep(5)

    price = driver.find_element_by_class_name("dataPriceDisplay")

    print(price.text)`

В результате он успешно печатает цену дляпервый тип материала, но затем он возвращает: StaleElementReferenceException: Message: The element reference of <li class=""> is stale;...

Я пробовал варианты наличия хэшированных строк внутри и снаружи цикла, но всегда получаю версию ошибки StaleElementReferenceException.

Есть предложения?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Вы можете сделать все это с помощью requests.Возьмите выпадающий список из опций, перечисленных в выпадающем меню, затем объедините атрибуты value в URL-адрес запроса, который извлекает json, содержащий всю информацию на странице.Тот же принцип применяется для добавления в другие выпадающие значения.Идентификаторы для каждого раскрывающегося списка - это атрибуты value опций в раскрывающемся списке, которые отображаются в отображаемом URL-адресе, разделенные // для каждого раскрывающегося списка.

import requests
from bs4 import BeautifulSoup as bs

url = 'https://www.accuform.com/product/getSku/danger-danger-authorized-personnel-only-MADM006/1/false/null//{}//WHFIw3xXmQx8zlz//6wr93DdrFo5JV//WdnO0RpwKpc4fGF'
startURL = 'https://www.accuform.com/safety-sign/danger-danger-authorized-personnel-only-MADM006'

res = requests.get(startURL)
soup = bs(res.content, 'lxml')
materials = [item['value'] for item in soup.select('#Wiqj7mb4rsAq9LB option')]
sizes = [item['value'] for item in soup.select('#WvXESrTyQjM3Ciw option')]
languages = [item['value'] for item in soup.select('#WUYWGMePtpmpmhy option')]
units = [item['value'] for item in soup.select('#W91eqaJ0WPXwe9b option')]

for material in materials:
    data = requests.get(url.format(material)).json()
    soup = bs(data['dataMaterialBullets'], 'lxml')
    lines = [item.text for item in soup.select('li')]
    print(lines)
    print(data['dataPriceDisplay'])     
    # etc......

Образец JSON:

image

0 голосов
/ 27 февраля 2019

Попробуйте приведенный ниже код. Он должен работать.

    driver = webdriver.Firefox()
    driver.get('https://www.accuform.com/safety-sign/danger-danger-authorized-personnel-only-MADM006')

    time.sleep(3)
    driver.find_element_by_id('x-mark-icon').click()

    material_dropdown = driver.find_element_by_xpath("//input[@class='select-dropdown']")
    driver.execute_script("arguments[0].click();", material_dropdown)

    #Code for material dropdown
    materials=driver.find_elements_by_css_selector("div.select-wrapper ul.dropdown-content li")


    material_optionsList = []
    for material in materials:
        material_ele=material.find_element_by_tag_name('span')
        if material_ele.text!='':
          material_optionsList.append(material_ele.text)

    print(material_optionsList)

    driver.execute_script("arguments[0].click();", material_dropdown)


    size_dropdown = driver.find_element_by_xpath("(//input[@class='select-dropdown'])[2]")
    driver.execute_script("arguments[0].click();", size_dropdown)

    #Code for size dropdown
    Sizes=driver.find_elements_by_css_selector("div.select-wrapper ul.dropdown-content li")
    size_optionsList = []
    for size in Sizes:
        size_ele=size.find_element_by_tag_name('span')
        if size_ele.text!='':
            size_optionsList.append(size_ele.text)



driver.execute_script("arguments[0].click();", size_dropdown)

Вывод:

[u'Adhesive Vinyl', u'Plastic', u'Adhesive Dura-Vinyl', u'Aluminum', u'Dura-Plastic\u2122', u'Aluma-Lite\u2122', u'Dura-Fiberglass\u2122', u'Accu-Shield\u2122']

Надеюсь, вы сделаете все остальное. Дайте мне знать, работает ли он для вас.

РЕДАКТИРОВАТЬ Код для циклического прохождения и получения значения цены материалов.

for material in range(len(materials)):
    material_ele=materials[material]

    if material_ele.text!='':
       #material_optionsList.append(material_ele.text)
       #material_ele.click()
       driver.execute_script("arguments[0].click();", material_ele)
       time.sleep(2)
       price = driver.find_element_by_id("priceDisplay")
       print( price.text)
       time.sleep(2)
       material_dropdown = driver.find_element_by_xpath("//input[@class='select-dropdown']")
       driver.execute_script("arguments[0].click();", material_dropdown)
       materials = driver.find_elements_by_css_selector("div.select-wrapper ul.dropdown-content li")
       material+=2

Вывод:

$8.31
$9.06
$13.22
$15.91
$15.91
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...