简体   繁体   English

Selenium Python - 无论顺序如何,我如何处理弹出窗口上的异常并处理 null 或空搜索

[英]Selenium Python - How do I handle the exceptions on popups regardless of the order and handle a null or empty search

I have a search that is looping through a list.我有一个遍历列表的搜索。 I've added a try for the situations where the search requires additional clicks on the popups.对于搜索需要额外点击弹出窗口的情况,我添加了一个尝试。 However, the order of the nested try, except causes an issue depending on which order the popups come in. With the current code the application is getttng stuck on the optionModalContent popup.但是,嵌套尝试的顺序,除了会导致问题取决于弹出窗口的进入顺序。使用当前代码,应用程序被卡在 optionModalContent 弹出窗口上。 Additionally, if a search is completed that is null or empty, the application will timeout.此外,如果完成了 null 或空的搜索,则应用程序将超时。 What is the best way to handle the empty/null search?处理空/空搜索的最佳方法是什么? Example would be searching C06 or 0.例如搜索 C06 或 0。

Below is my code with a slimmed down version of the application.下面是我的代码,其中包含应用程序的精简版本。

from selenium import webdriver
import pandas as pd
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait, TimeoutException
import time
appended_data  = []
classlist = ['C',
            'C01',
            'BETA BLOCKING AGENTS',  #optionModalContent
            'ANTIADRENERGIC AGENTS', #spellingModal
            'C02', 
            'C06',        #no search results timesout need to know how to handle this
            'C07',
            'Vitamins' #handled by optionModalContentTable    
            ]
time.sleep(1)
with webdriver.Chrome('C:\Program Files\Chrome Driver\chromedriver.exe') as driver:   ## uses the content manager by using with webdriver.Chrome, improves performance

    for search in classlist:
            page = f"https://mor.nlm.nih.gov/RxClass/search?query={search}"
            driver = webdriver.Chrome('C:\Program Files\Chrome Driver\chromedriver.exe')
            driver.get(page)

            modal_wait = WebDriverWait(driver, 4)
            try:
                modal_el = modal_wait.until(EC.element_to_be_clickable((By.ID, 'synModalContent')))  ## handles last popup if the search isn't exact
                modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
                

                try:
                    modal_el = modal_wait.until(EC.element_to_be_clickable((By.ID, 'optionModalContent')))  ## handles popup that requires you to select a line item
                    modal_el.find_element(By.CSS_SELECTOR, 'ul.uloption').click()   
                    
                except:
  
                    try:
                        modal_el = modal_wait.until(EC.element_to_be_clickable((By.ID, 'spellingModal')))  ## handles popup to suggest spelling
                        modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
                         

                    except:
                        modal_el = modal_wait.until(EC.element_to_be_clickable((By.ID, 'optionModalContentTable')))   ##handles first popup window on search if there are multiple classes for vitamin
                        modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
                        pass 
   
            except TimeoutException:
                pass        
            table = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'tr.dbsearch')))
            classid = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.table-responsive div.propText strong:nth-child(2)"))).text
            classname = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.table-responsive div.propText strong:nth-child(1)"))).text
            classtype = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.table-responsive div.propText strong:nth-child(3)"))).text
            filename = classname[0:30]+'.csv'
            df = pd.read_html(driver.page_source)[1].iloc[:,:-1].assign(ClassID=classid, ClassName=classname, ClassType=classtype)
            appended_data.append(df)
            driver.quit()
    appended_data = pd.concat(appended_data)
    appended_data.to_csv('testcategorization.csv')  

       
          

I know my problem is going to be in my nested try except.我知道我的问题将出现在我的嵌套尝试中。 I've moved things around and added passes, but regardless of the order the application will eventually get stuck on one of the searches.我已经移动了一些东西并添加了通行证,但无论应用程序最终会卡在其中一个搜索上的顺序如何。 What is the best way to handle all of the popups regardless of the order?无论顺序如何,处理所有弹出窗口的最佳方法是什么?

Perhaps there is a better way to go about the try and except.也许有一个更好的方法来 go 关于尝试和除外。 Additionally if the search returns no results, I'm not sure how to handle that.此外,如果搜索没有返回任何结果,我不确定如何处理。

The end result I'm looking for is to get my application to run without getting stuck on a popup that is in the list regardless of the order it's ran in.我正在寻找的最终结果是让我的应用程序运行而不会卡在列表中的弹出窗口上,而不管它的运行顺序如何。

For now, this is what got me going:现在,这就是让我前进的原因:

Fetch the search key from current url, and subject the code to if elif else under try block.从当前 url 中获取搜索键,并将代码置于try块下的if elif else中。 You may still improve it by using try/except in each if elif else statements.您仍然可以通过在每个if elif else语句中使用try/except来改进它。

title = driver.current_url
        print(title)
    try:
        if "BETA%20BLOCKING%20AGENTS" in title:
            modal_el = modal_wait.until(EC.element_to_be_clickable(
                (By.ID, 'optionModalContent')))  ## handles popup that requires you to select a line item
            modal_el.find_element(By.CSS_SELECTOR, 'ul.uloption').click()
        elif "ANTIADRENERGIC%20AGENTS" in title:
            modal_el = modal_wait.until(
                EC.element_to_be_clickable((By.ID, 'spellingModal')))  ## handles popup to suggest spelling
            modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
            modal_wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id='optionModalContent']//li"))).click()
        elif "Vitamins" in title:
            modal_el = modal_wait.until(EC.element_to_be_clickable((By.ID,
                                                                    'optionModalContentTable')))  ##handles first popup window on search if there are multiple classes for vitamin
            modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
            modal_wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id='optionModalContent']//li"))).click()
        else:
            modal_el = modal_wait.until(
                EC.element_to_be_clickable((By.ID, 'synModalContent')))  ## handles last popup if the search isn't exact
            modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()

Still checking how to handle the no classes found condition.仍在检查如何处理no classes found的情况。 If I crack it, will post it here as update.如果我破解它,将在此处作为更新发布。 Will check in my free time.将检查我的空闲时间。 I would want to appreciate for the code that you wrote.我希望感谢您编写的代码。 It is very lean except that an additional browser instance opens, but I would say this is a very good one.除了打开一个额外的浏览器实例之外,它非常精简,但我会说这是一个非常好的实例。 I learned something today from you.我今天从你那里学到了一些东西。

UPDATE: I tried some alternatives and it worked.更新:我尝试了一些替代方案,它奏效了。 Please check this below code.请检查以下代码。 It manages to get the result by search each item from the search list, while handling the C06 .它设法通过从搜索列表中搜索每个项目来获得结果,同时处理C06

I used a lot of print statements which I used for debug purposes.我使用了很多用于调试目的的打印语句。 Feel free to remove them.随意删除它们。 Also, I used time.sleep in few occasions to have the alert handled.此外,我在几次使用time.sleep来处理警报。 Try to reduce it and see if it works.尝试减少它,看看它是否有效。

for search in classlist:
    page = f"https://mor.nlm.nih.gov/RxClass/search?query={search}"
    driver = webdriver.Chrome(ChromeDriverManager().install())
    driver.get(page)
    time.sleep(5)
    try:
        WebDriverWait(driver, 3).until(EC.alert_is_present())
        alert = driver.switch_to.alert
        alert.accept()
        print("alert accepted")
    except TimeoutException:
        print("no alert")
    title = driver.current_url
    print(title)
    modal_wait = WebDriverWait(driver, 4)
    try:
        if "BETA%20BLOCKING%20AGENTS" in title:
            print("betablocker")
            modal_el = modal_wait.until(EC.element_to_be_clickable(
                (By.ID, 'optionModalContent')))  ## handles popup that       requires you to select a line item
            modal_el.find_element(By.CSS_SELECTOR, 'ul.uloption').click()
        elif "ANTIADRENERGIC%20AGENTS" in title:
            print("diuretic")
            modal_el = modal_wait.until(
                EC.element_to_be_clickable((By.ID, 'spellingModal')))  ## handles popup to suggest spelling
            modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
            modal_wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id='optionModalContent']//li"))).click()
        elif "Vitamins" in title:
            print("vitamin")
            modal_el = modal_wait.until(EC.element_to_be_clickable((By.ID,
                                                                    'optionModalContentTable')))  ##handles first popup window on search if there are multiple classes for vitamin
            modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
            modal_wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id='optionModalContent']//li"))).click()
        else:
            print("others")
            modal_el = modal_wait.until(
                EC.element_to_be_clickable((By.ID, 'synModalContent')))  ## handles last popup if the search isn't exact
            modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
    except Exception as e:
        print(f"No tables found in {search}")
        continue

Console Output (End result):控制台 Output(最终结果):

Process finished with exit code 0

UPDATE 2: TO HANDLE TRY/EXCEPT per the comment of query creator.更新 2:根据查询创建者的评论处理尝试/除外。

for search in classlist:
    page = f"https://mor.nlm.nih.gov/RxClass/search?query={search}"
    driver = webdriver.Chrome(ChromeDriverManager().install())
    driver.get(page)
    time.sleep(2)
    try:
        WebDriverWait(driver, 3).until(EC.alert_is_present())
        alert = driver.switch_to.alert
        alert.accept()
        print("alert accepted")
        print(f"No tables found in {search}")
        continue
    except TimeoutException:
        print("no alert")
    modal_wait = WebDriverWait(driver, 4)
    try:
        modal_el = modal_wait.until(
            EC.element_to_be_clickable((By.ID, 'synModalContent')))  ## handles last popup if the search isn't exact
        modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
    except:
        try:
            modal_el = modal_wait.until(EC.element_to_be_clickable(
                (By.ID, 'optionModalContent')))  ## handles popup that requires you to select a line item
            modal_el.find_element(By.CSS_SELECTOR, 'ul.uloption').click()
        except:
            try:
                modal_el = modal_wait.until(
                    EC.element_to_be_clickable((By.ID, 'spellingModal')))  ## handles popup to suggest spelling
                modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
            except:
                modal_el = modal_wait.until(EC.element_to_be_clickable((By.ID,
                                                                        'optionModalContentTable')))  ##handles first popup window on search if there are multiple classes for vitamin
                # modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
                modal_el.find_element(By.CSS_SELECTOR, 'div.nameEntry').click()
                pass

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM