首页 > 解决方案 > 一个简单的 IF 算法的问题:如何检测一个或多个元素不存在?

问题描述

新更新 这是主窗口。它包括根据抓取的结果在每个文本旁边显示一个绿色图标(正确执行抓取)或一个红色图标(抓取错误)。然后基本上,有一个带有问号的图标被红色或绿色图标替换。除了图标更改之外,还会显示错误消息(带有异常的错误消息包含在另一个外部文件中,我用于抓取)。由于导入的两个 py 脚本(或者更确切地说是它们的函数),执行了抓取。它们是 msg1 = Scraping_Nome_Campionati.scraping_nome_campionati_e_tor 和 msg2 = Scraping_Nome_Squadre_MIO.scraping_nome_squadre_e_tor()

def do_scraping():
    
    msg1 = Scraping_Nome_Campionati.scraping_nome_campionati_e_tor()
    if msg1:
        message1.configure(text=msg1)
        message1.configure(foreground="red")
        vuoto_elenco_campionati.config(image=render7)
        
    else:
         vuoto_elenco_campionati.config(image=render8)
         message1.configure(foreground="green")



    msg2 = Scraping_Nome_Squadre_MIO.scraping_nome_squadre_e_tor()
    if msg2:
        message2.configure(text=msg2)
        message2.configure(foreground="red")
        vuoto_elenco_squadre.config(image=render7)

    else:
         vuoto_elenco_squadre.config(image=render8)
         message2.configure(foreground="green")
  
button = Button(test_scraping, text="Avvia", bg='#e95420', foreground='white', command=do_scraping)
button.place(x=116, y=512)

两个外部文件中的抓取是这样进行的(我只携带一个文件作为示例)

#example
driver.minimize_window()
driver.get("web site")
Element1=driver.find_element_by_class_name("name class")
Element1_text = Element1.text

#insert in database
con = sqlite3.connect('/dababase')
cursor = con.cursor()
records_added_Risultati = 0

    Values = ((Element1_text,), (Element2_text,))
    sqlite_insert_query = 'INSERT INTO xxxxx VALUES (?);'
    count = cursor.executemany(sqlite_insert_query, Values)
    con.commit()

#The error messages are contained in this external scraping file, 
# and NOT in the main window with icons

except NoSuchElementException:
    return "FAILED (NoSuchElementException)"

except NameError:
    return "FAILED (Name Error)"

except ValueError:
    return "FAILED (ValueError)"

if records_added_Risultati == 0:
   return "FAILED: 0 record scraping"

Campionati_per_controllo_errori = [Element1_text, Element2_text]
if any(Campionati_per_controllo_errori):
    return "FAILED (manca 1 campionato)"

问题:所以回顾一下,问题是当抓取正确完成时(抓取和数据库插入),我仍然得到红色错误图标+错误消息。我设置了一种错误类型,以确保“如果没有正确执行抓取,即使只有 1 个,则必须打印错误”,也就是说,如果 20 个文本中的 19 个正确下载,则必须出现错误及其消息. 问题是:即使您抓取了 20 条文本并且一切都正确完成,我也会收到一条消息,指出存在错误并且文本尚未被抓取。

旧更新

如何编码以下内容:

  1. “如果一个或多个”这些元素没有被检测到,那么我会收到一条警告消息。通过警告消息,我的意思是万一有一个抓取问题导致,不是错误,而只是一个空的结果。这样一个元素不会被刮掉,但其他元素会被刮掉。

  2. 如果未检测到所有内容,是否会显示警告消息?

所以我需要两种类型的代码。

#example
driver.minimize_window()
driver.get("web site")
Element1=driver.find_element_by_class_name("name class")
Element1 = Element1text


if Element1 or Element2 or Element3 or Element4 or Element5 = no scraping:
    return "error"

if Element1, Element2, Element3, Element4, Element5 = no scraping:
    return "error"

UPDATE 元素是使用 Selenium 抓取并保存在数据库中的数据。例如它们是这样的:

    #Element1
    driver.get("site")

    for Element1 in driver.find_elements(By.CSS_SELECTOR, xxxxxx'][class^='rxxxxxx']"):
        Element1_text = Element1.text
        count = cursor.execute(sqlite_insert_query, (Element1_text,))
        print(Element1_text)
    driver.close

#insert in database
con = sqlite3.connect('/dababase')
cursor = con.cursor()
records_added_Risultati = 0

    Values = ((Element1_text,), (Element2_text,))
    sqlite_insert_query = 'INSERT INTO xxxxx VALUES (?);'
    count = cursor.executemany(sqlite_insert_query, Values)
    con.commit()

标签: pythonpython-3.xalgorithmselenium

解决方案


对于 python3,考虑使用any()all()函数。

从文档中:

全部(可迭代)

如果可迭代对象的所有元素都为真(或可迭代对象为空),则返回 True。

任何(可迭代)

如果可迭代的任何元素为真,则返回真。如果可迭代对象为空,则返回 False。

现在您只需要从您的元素中创建一个可迭代对象,这非常简单:

some_iterable = [Element1, Element2, Element3, Element4, Element5]
if any(some_iterable):  # Like using or on all of them!
    return "error"

if all(some_iterable):  # Like using and on all of them!
    return "error"

现在我们有最后一个问题!元素需要具有固有的真值,它们需要被评估为真或假。正如@Prophet在他的回答中指出的那样,使用driver.find_elements_by_class_name而不是driver.find_element_by_class_name(区别在于 ELEMENTS 而不是单个 ELEMENT)可以实现这一点,因为如果找不到具有该类名的元素,它会提供一个空数组(评估为 False)。

如果找到该类元素的一个实例,您将得到一个仅包含该元素的数组,您可以按如下方式使用它Element1[0]:如果发现多个元素,如预期的那样,您将拥有它们的数组,因此您需要相应地处理它们。

编辑:更多解释。

any(some_iterable)相当于: Element1 or Element2 or Element3 or Element4 or Element5 这里。 all(some_iterable)相当于: Element1 and Element2 and Element3 and Element4 and Element5

现在您可能会问自己为什么Element1 and Element2 and Element3 and Element4 and Element5甚至可以工作!答案是,如果元素是[]None,它们在运算符 ( and) 和 ( or) 下的计算结果为 False,导致整个表达式计算结果为 False。您可以在此处的 if 语句中阅读有关 False 的更多信息。

您可以if any(some_iterable)在某种程度上认为“如果 some_iterable 中的任何元素存在并且非零”,并且if any(some_iterable)说“如果 some_iterable 中的所有元素都存在并且它们都非零”。

实际上,它比这更复杂(很多事情都返回 false,而不仅仅是None[]0,但你明白了。


更新了对更新问题的答案。

当任何/全部都不存在时,您想抛出错误。您not的代码中缺少 a 。

只是改变:

if any(Campionati_per_controllo_errori):  # If any of them is present, throw an error. Not what we want.
    return "FAILED (manca 1 campionato)"

至:

if not all(Campionati_per_controllo_errori):  # If not all of them are present, throw an error.
    return "FAILED (manca 1 campionato)"

推荐阅读