Условное выпадающее меню для l oop не работает ожидаемым образом - PullRequest
0 голосов
/ 17 апреля 2020

Я уже писал в Stack Exchange; однако, пока не получил большого ответа от этого; следовательно, разместив это здесь.

Я пытаюсь очистить некоторые данные, используя следующий код. Когда я запускаю код построчно, он работает нормально. Однако, когда я хочу запустить весь код на одном go, раскрывающиеся опции go останутся пустыми, и в результате последняя строка вернет ошибку. Ваша помощь будет высоко ценится. Код ниже.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
import os 

path = os.path.join(r"D:\ScrapedData\TN\SocialAudit")
path_to_chromedriver = 'D:\ScrapedData/chromedriver'
options = webdriver.ChromeOptions()
prefs = {'download.default_directory' : path}
options.add_experimental_option('prefs', prefs)
browser = webdriver.Chrome(chrome_options=options ,executable_path=path_to_chromedriver)    

url = "http://mnregaweb4.nic.in/netnrega/SocialAudit/StateList.aspx"
browser.get(url)
browser.set_page_load_timeout(45)
browser.maximize_window()

browser.find_element_by_link_text("BIHAR").click()
browser.implicitly_wait(5)

year=['2016-2017', '2017-2018', '2018-2019', '2019-2020']
elem2 = browser.find_element_by_name("ctl00$ContentPlaceHolder1$ddlFin")
elem2.send_keys(year[0])
browser.implicitly_wait(5)

select_dist = browser.find_element_by_name("ctl00$ContentPlaceHolder1$ddldist")
options = [x for x in select_dist.find_elements_by_tag_name("option")]
dist=[]
for e in range(len(options)):
    select_dist = Select(browser.find_element_by_name("ctl00$ContentPlaceHolder1$ddldist"))
    select_dist.select_by_index(e)

    select_block = Select(browser.find_element_by_name("ctl00$ContentPlaceHolder1$ddlblock"))
    options1 = select_block.options
    for f in range(len(options1)):
        select_block = Select(browser.find_element_by_name("ctl00$ContentPlaceHolder1$ddlblock"))
        select_block.select_by_index(f)

        select_gp = Select(browser.find_element_by_name("ctl00$ContentPlaceHolder1$ddlpanchayat"))
        options2 = select_gp.options
        for g in range(len(options2)):
            select_gp =  Select(browser.find_element_by_name("ctl00$ContentPlaceHolder1$ddlpanchayat"))
            select_gp.select_by_index(g)

            browser.find_element_by_css_selector("#ctl00_ContentPlaceHolder1_rbLoginLevel_1").click()
            browser.implicitly_wait(10)

            elem6 = browser.find_element_by_name("ctl00$ContentPlaceHolder1$txtperiodFrom")
            elem6.send_keys('01/04/2016')
            browser.implicitly_wait(10)

            elem7 = browser.find_element_by_name("ctl00$ContentPlaceHolder1$txtperiodTo")
            elem7.send_keys('31/03/2017')
            browser.implicitly_wait(10)

            browser.find_element_by_css_selector("#ctl00_ContentPlaceHolder1_login").click()
            browser.implicitly_wait(10)

            browser.find_element_by_link_text("Download All Reports").click()

1 Ответ

0 голосов
/ 17 апреля 2020

Кроме того, что целевая страница медленнее, чем старая улитка, и этих 10 секунд ожидания едва хватит на что-либо, есть две вещи, которые вы пропустили, которые вызвали ваши проблемы:

  • вы не сделали Учтите, что первым элементом опций выбора являются типы «выбрать опцию». Поэтому, если вы попытаетесь выполнить цикл по всем из них, вы должны проигнорировать опцию в первом индексе, иначе это будет выглядеть как «ничего не выбрано»
  • ждать этого счетчика. После того, как спиннер исчезнет, ​​страница будет обновлена. Не берите элементы до завершения обновления страницы sh, подождите, пока вращатель не исчезнет.

С помощью этих двух вспомогательных функций можно без проблем нажать кнопку «Получить отчеты»:

def is_spinner_gone(arg):
    loaded_spinner = browser.find_element_by_xpath('//div[//div[@class="loader"]]')
    if loaded_spinner:
        return loaded_spinner.get_attribute('style') == 'display: none;'
    return True

def wait_for_element(xpath):
    # this is necessary because the spinner does not pop up instantly
    time.sleep(1)
    no_spinner =  WebDriverWait(browser, 500).until(is_spinner_gone)

    element = WebDriverWait(browser, 500).until(
        EC.element_to_be_clickable((By.XPATH, xpath)))
    return element

Если вы получите ваши элементы с помощью вызова wait_for_element, вы сможете взаимодействовать с ними без ошибок. Я думаю, вы знаете, что нажатие этой кнопки еще не конец пути, вам придется выбрать формат отчета, и кто знает, что будет дальше.

Скорректированный код:


from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
import os
import time

path = os.path.join(r"D:\ScrapedData\TN\SocialAudit")
path_to_chromedriver = 'D:\ScrapedData/chromedriver'
options = webdriver.ChromeOptions()
prefs = {'download.default_directory' : path}
options.add_experimental_option('prefs', prefs)
browser = webdriver.Chrome(chrome_options=options ,executable_path=path_to_chromedriver)

start = time.time()
url = "http://mnregaweb4.nic.in/netnrega/SocialAudit/StateList.aspx"
browser.get(url)
browser.set_page_load_timeout(45)
browser.maximize_window()

loaded = time.time()
print(f'PAGE LOADED IN {loaded-start} seconds')

browser.find_element_by_link_text("BIHAR").click()

def is_spinner_gone(arg):
    loaded_spinner = browser.find_element_by_xpath('//div[//div[@class="loader"]]')
    if loaded_spinner:
        return loaded_spinner.get_attribute('style') == 'display: none;'
    return True

def wait_for_element(xpath):
    # this is necessary because the spinner does not pop up instantly
    time.sleep(1)
    no_spinner =  WebDriverWait(browser, 500).until(is_spinner_gone)

    element = WebDriverWait(browser, 500).until(
        EC.element_to_be_clickable((By.XPATH, xpath)))
    return element

year=['2016-2017', '2017-2018', '2018-2019', '2019-2020']
elem2 = wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$ddlFin"]')
selector_page_loaded = time.time()
print(f'WORK AREA LOADED IN {selector_page_loaded-loaded} seconds')

elem2.send_keys(year[0])

select_dist = wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$ddldist"]')
options = [x for x in select_dist.find_elements_by_tag_name("option")]
dist=[]
# ISSUE: default fields are included in the options!
for e in range(1,len(options)):
    select_dist = Select(wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$ddldist"]'))
    select_dist.select_by_index(e)

    select_block = Select(wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$ddlblock"]'))
    options1 = select_block.options
    for f in range(1, len(options1)):
        select_block = Select(wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$ddlblock"]'))
        select_block.select_by_index(f)

        select_gp = Select(wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$ddlpanchayat"]'))
        options2 = select_gp.options
        for g in range(1, len(options2)):
            select_gp = Select(wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$ddlpanchayat"]'))
            select_gp.select_by_index(g)

            wait_for_element('//*[@id="ctl00_ContentPlaceHolder1_rbLoginLevel_1"]').click()

            elem6 = wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$txtperiodFrom"]')
            elem6.send_keys('01/04/2016')

            elem7 = wait_for_element('//*[@name="ctl00$ContentPlaceHolder1$txtperiodTo"]')
            elem7.send_keys('31/03/2017')

            wait_for_element('//*[@value="Get Reports"]').click()
            print(f'FIRST RUN IN {time.time()-selector_page_loaded}')

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