如果处理了错误,while 循环会跳过一个循环。我怎样才能让它在周期的其余部分运行?

Posted

技术标签:

【中文标题】如果处理了错误,while 循环会跳过一个循环。我怎样才能让它在周期的其余部分运行?【英文标题】:While loop skips a cycle if an error is handled. How can I make it run the rest of the cycle? 【发布时间】:2020-11-04 12:52:23 【问题描述】:

我还是 Python 新手,我写了一些代码来帮助我浏览一些在线列表。

我必须在其中进行一些错误处理,因为当找不到列表的属性时,它会导致程序崩溃。

如果我尝试使用 pass 或 continue ,我只会陷入无限循环,正如预期的那样。

我觉得我已经把自己写到了一个角落,我似乎无法找到解决方案。我发现我无法弄清楚的解决方案,大多数是针对其他语言的。

我怎样才能使这个工作,以便一旦发现错误循环不会跳过所有其他属性?

编辑: 我认为我的帖子在这一点上不清楚,我很抱歉。发生的情况是:如果未找到列表中感兴趣的元素,则跳过其他元素。因此,如果列表没有指定所有者名称(第一个元素或属性),则整个列表将被忽略。它继续到下一个列表。知道如何解决这个问题吗?

以下是部分代码:

#iterate through the results according to user input earlier
i = 0
while (i < number_of_results):

    Result_page = driver.current_url
#define elements of the listing of interest
    stran = requests.get(driver.current_url)
    soup = BeautifulSoup(stran.content, 'html.parser')
    ime = soup.find("dd", itemprop="name")
    ulica = soup.find("dd", itemprop="streetAddress")
    postna_stevilka = soup.find("span", itemprop="postalCode")
    kraj = soup.find("span", itemprop="addressLocality")
    tel = soup.find("dd", itemprop="telephone")
    spletna_stran = soup.find("dd", itemprop="url") 
    mobil = soup.find("a", itemprop="telephone")
    
    try:
        print(ime.text)
        c1 = sheet.cell(row=i+1, column=1)
        c1.value = ime.text
        print(ulica.text)
        c1 = sheet.cell(row=i+1, column=2)
        c1.value = ulica.text
        print(postna_stevilka.text)
        c1 = sheet.cell(row=i+1, column=3)
        c1.value = postna_stevilka.text
        print(kraj.text)
        c1 = sheet.cell(row=i+1, column=4)
        c1.value = kraj.text
        print(tel.text)
        c1 = sheet.cell(row=i+1, column=5)
        c1.value = tel.text
#print(mobil.text) does not work, cut out to prevent error
        print(spletna_stran.text)
        c1 = sheet.cell(row=i+1, column=6)
        c1.value = spletna_stran.text
        
        
#catch the error when an entry isn't there      
    except AttributeError:
        print("No such entry.")
    
       
        

    next_entry = driver.find_element_by_xpath("/html/body/main/chousingdetail/div/div[2]/div[1]/nav/div/div[2]/a[2]/i")
    next_entry.click()
    i +=1

【问题讨论】:

我认为 continue 应该在 except 之后,并且在 finally 之后应该有一个函数,无论例外***.com/questions/10544928/…。 finally 块无论如何都会运行,并且在你的 finally 块中你有 continue 它不会让它下面的代码运行。所以我建议你把continue下面的所有块都移到finally块。它应该工作 或从finally 块中删除continue @AmitKumar 我的原始代码没有“继续”或“最终”子句,这是我试图让循环返回属性并提取其他信息的尝试。我认为我的帖子在这一点上不清楚,我很抱歉。发生的情况是:如果未找到列表中感兴趣的元素,则跳过其他元素。因此,如果列表没有指定所有者名称(第一个元素或属性),则整个列表将被忽略。它继续到下一个列表。知道如何解决这个问题吗? @CYREX 感谢您提供该主题的链接!我想我不清楚我的问题,我已经相应地编辑了我的帖子。我的代码原本没有这些子句。 【参考方案1】:

如果我正确理解你的意图,你不应该那样使用try...except

一旦try 块遇到异常,它就会跳转到except 块。它不会“尝试”其余的行。因此,如果您希望检查所有元素而不考虑其中任何一个失败,则需要将每个元素放在单独的 try...except 块中。例如,

try:
    print(ime.text)
    c1 = sheet.cell(row=i+1, column=1)
    c1.value = ime.text
except:
    pass

try:
    print(ulica.text)
    c1 = sheet.cell(row=i+1, column=2)
    c1.value = ulica.text
except:
    pass

等等。这样,将处理缺失值,并且脚本将移动到下一个元素。

但是,我更喜欢这样做:因为bs4.BeautifulSoup.find() 返回None,如果它没有找到任何东西,你可以使用:

ime = soup.find("dd", itemprop="name")
if ime:
    print(ime.text)
    c1 = sheet.cell(row=i+1, column=1)
    c1.value = ime.text

等等。我什至会将这些行包装在一个函数中,因为它们对于每个元素几乎都是相同的。 (事实上​​,我可以对您的代码提出一些改进建议,但也许这是另一个讨论;我现在会坚持这个问题!)

【讨论】:

谢谢。呃,现在解决办法太明显了。我想我太专注于尽可能多地保留我的代码。您首选的执行方式看起来非常流畅。出于某种原因,我完全忘记了if。我现在就试试这个。 :) 我刚刚用了你的方法,效果很好!我已将此标记为答案,因为它解决了我的问题。很抱歉向您提出这个问题,但我也非常感谢您对我的代码提出任何建议,因为我对 Python 非常笨拙... @Coercer_,这不是最好的论坛,但简单地说:1)将重复的步骤包装在一个函数中以减少代码并使其更易于维护;例如,get_item_value(col)。 2)number_of_results 来自哪里?在找不到“next”时考虑结束循环;使代码更健壮。 3) 看起来你想要一张桌子。一个自然的结构是一个列表[row_1 ... row_n],其中row_i = ime_i.attrs["itemprop"]: ime_i.text, ... etc.。该列表可以使用 csv.DictWriter 轻松导出到 CSV/电子表格中。 再次感谢您。 number_of_results 来自这部分代码之前的代码。要求用户输入邮政编码和要浏览的列表数量。我没有发布所有内容,因为我认为专注于给我带来麻烦的部分是明智的。然后代码在相关站点上运行搜索。是的,我正在用列表中的相关信息构建一个表格。我正在使用 openpyxl 将信息写入单元格,然后保存工作簿。【参考方案2】:

复制粘贴finally 语句中的最后三行。

【讨论】:

感谢您的回答。我试过了,它确实有效。但是,它并没有解决我的问题,即一旦找不到属性就会跳过属性。我已经编辑了我的帖子以澄清。

以上是关于如果处理了错误,while 循环会跳过一个循环。我怎样才能让它在周期的其余部分运行?的主要内容,如果未能解决你的问题,请参考以下文章

为啥程序跳过while循环

空while循环的Python语法

如果函数内部的条件失败,则跳过 bash while 循环

7.6.1 continue 语句

为啥 Python for 循环在遍历列表副本并进行删除时会跳过元素? [复制]

在while循环中使用if语句使R跳过某些索引值