(python) list index out of range - with using selenium click event

Viewed 584

There are 41 category checkbox, 12 are visible and remain are hidden, need to click on show more to show hidden checkboxes.

this code do that:: 1-loop >> 2-click on show more if i <=12 >> 3-click on checkbox

# -*- coding: utf-8 -*-
import time
from selenium import webdriver

driver = webdriver.Chrome(executable_path='C:\\Users\\Compu City\\Desktop\\chromedriver.exe')
driver.get('https://www.amazon.com/international-sales-offers/b/?ie=UTF8&node=15529609011&ref_=nav_navm_intl_deal_btn')
time.sleep(10)
res = driver.execute_script("return document.documentElement.outerHTML")

i=0
while i <= 41 :
    if(i <=12):
        driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > div.a-row.a-expander-container.a-expander-inline-container > a > span').click()
    driver.find_elements_by_css_selector('.a-expander-container .a-checkbox label .a-label')[i].click()
    driver.implicitly_wait(2)
    time.sleep(2)
    i+=1

the problem: code works well with 12 checkboxes and then click on show more then click just on the first checkbox NO.13 then get this error

D:\python neww>aaa.py

DevTools listening on ws://127.0.0.1:59799/devtools/browser/ac2188e0-10e3-493b-9d91-614731f8d135
Traceback (most recent call last):
  File "D:\python neww\aaa.py", line 14, in <module>
    driver.find_elements_by_css_selector('.a-expander-container .a-checkbox label .a-label')[i].click()
IndexError: list index out of range

i searched a lot about selution what i found that echeckbox not load , but when change .click() with .text

I get all checkbox label names, so how they don't load

i mage for checkboxes

3 Answers

the problem with css selectors try this code


i = 5
while i <= 29:
    driver.implicitly_wait(3)
    time.sleep(3)
    if(i==5):
        cat =driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > div.a-row.a-expander-container.a-expander-inline-container > div > span:nth-child({}) > div > label'.format(i)).click()
        driver.implicitly_wait(3)
        time.sleep(3)
    else:
        y=11
        while y<=29:
            cat = driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > span:nth-child({}) > div > label'.format(y)).click()
            y+=1
            driver.implicitly_wait(3)
            time.sleep(3)
    driver.implicitly_wait(3)
    time.sleep(3)

    i += 1
    print('i: ', i)

main problem with css selectors because there are three structures for html

1-first structure for first 12 check box

2-second one for first checkbox after click show more

3-third one when click on first checkbox after show more all structure will change and will include all check box

(i didn't use third part because it will make code so long and i want to short the code)

so try this code , after click on checkbox you will need to click clear so i think this code will be useful

first_part = 12
while first_part <=12:
    #click on category checkbox
    driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > div.a-row.a-expander-container.a-expander-inline-container > span:nth-child({}) > div > label'.format(first_part)).click()
    driver.implicitly_wait(3)
    time.sleep(3)
    #clear filter
    driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > span > div > a').click()
    driver.implicitly_wait(3)
    time.sleep(3)
    #print text of checkbox category
    print(driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > div.a-row.a-expander-container.a-expander-inline-container > span:nth-child({}) > div > label'.format(first_part)).text)
    first_part+=1
second_part = 1
while second_part <= 26:
    #show more
    driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > div.a-row.a-expander-container.a-expander-inline-container > a > span').click()
    driver.implicitly_wait(2)
    time.sleep(2)
    #print text of checkbox category
    print(driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > div.a-row.a-expander-container.a-expander-inline-container > div > span:nth-child({}) > div > label'.format(second_part)).text)
    #click on category checkbox
    driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > div.a-row.a-expander-container.a-expander-inline-container > div > span:nth-child({}) > div > label'.format(second_part)).click()
    driver.implicitly_wait(3)
    time.sleep(3)
    #clear filter
    driver.find_element_by_css_selector('#widgetFilters > div:nth-child(1) > span > div > a').click()
    driver.implicitly_wait(3)
    time.sleep(3)
    second_part+=1

Here is the simple and sweet script that will work.

driver.get('https://www.amazon.com/international-sales-offers/b/?ie=UTF8&node=15529609011&ref_=nav_navm_intl_deal_btn')
checkCSS = "[class='a-row a-spacing-small filterItem']:nth-of-type(1) .a-checkbox.checkbox.a-spacing-micro"
WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.CSS_SELECTOR, checkCSS)))
departments = len(driver.find_elements_by_css_selector(checkCSS))

for depNum in range(departments):
    print(depNum)
    if depNum == 12:
        WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.CSS_SELECTOR, "span.a-expander-prompt"))).click()
        time.sleep(1)
    WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.CSS_SELECTOR, checkCSS)))
    driver.find_elements_by_css_selector(checkCSS)[depNum].click()

Related