for循环中的break语句不起作用

break statement inside a for loop not working

使用以下代码,我无法跳出循环:

import requests
from bs4 import BeautifulSoup


link = "http://www.wuxiaworld.com/"

html = requests.get(link)
soup = BeautifulSoup(html.content, "html.parser")

all_aside = soup.find_all("aside", id="recent-posts-2")
for aside in all_aside:
    for li in aside.find_all("li"):
        for a in li.find_all("a"):
            if "ATG" in a.text:
                print(a.text)
                break

我想制作一个脚本,在故事的新章节发布时通知我。我刚刚开始制作它,但我被困在这里(它在最近的帖子中打印所有包含字符串 "ATG" 的新版本)。

我做了一些研究,发现我应该打破所有的循环,但是当我尝试这段代码时,没有任何内容被打印到控制台:

import requests
from bs4 import BeautifulSoup


link = "http://www.wuxiaworld.com/"

html = requests.get(link)
soup = BeautifulSoup(html.content, "html.parser")

all_aside = soup.find_all("aside", id="recent-posts-2")
for aside in all_aside:
    for li in aside.find_all("li"):
        for a in li.find_all("a"):
            if "ATG" in a.text:
                print(a.text)
                break
        break
    break

谢谢。

实际上,它们 正在 工作,完全按照设计。这不一定与某些人认为他们应该工作的方式相同:-)

外循环和中循环的break语句将被执行不管break是否发生。换句话说,它们是无条件的,所以那些循环只会执行一次。

您可以通过以下方式解决此问题:

foundIt = False
for aside in all_aside:
    for li in aside.find_all("li"):
        for a in li.find_all("a"):
            if "ATG" in a.text:
                print(a.text)
                foundIt = True
                break
        if foundIt: break
    if foundIt: break

另一种可能性(可能"cleaner")是将其重构为一个函数:

def printOne(asides):
    for aside in asides:
        for li in aside.find_all("li"):
            for a in li.find_all("a"):
                if "ATG" in a.text:
                    print(a.text)
                    return

并调用它:

printOne(all_asides)

有点丑陋的 hack(......好吧,好吧,完全和彻底的可憎),除了最外层的循环:

for ...:
   ...
else:
  continue
break

在第一种情况下,您在 for 循环的末尾中断,但下一个 for 循环仍将 运行。在第二种情况下,您在第一个 for 循环的第一次迭代后立即中断,并立即离开所有循环。

另一个答案提到使用一系列 if 语句来中断 您还可以使用异常处理来执行多级中断。

class BreakException(Exception):
    pass
try:
    for aside in all_aside:
        for li in aside.find_all("li"):
            for a in li.find_all("a"):
                if "ATG" in a.text:
                    print(a.text)
                    raise BreakException
except BreakException:
    pass

see here 了解更多通关方法。

也许上面的答案也是对的,但也可能有另一种罕见的情况。

如果您使用PyCharm进行调试,也有可能您已经编辑了代码并且代码行在视觉上移动了upward/downward但是调试会话重新启动后才会interpreted/executed

显然,重新启动调试会话效果很好...