Quiero romper uno de mis bucles "for" una vez que devuelva "link" vacío.

import requests
import numpy as np
from bs4 import BeautifulSoup    

cats = ['house', 'apartment']
try:
    for cat in cats:
        pages = np.arange(1,500)
        for p in page:
            url ='https://www.immoweb.be/en/search/'+str(cat)+'/for-sale?countries=BE&page='+str(page)+'&orderBy=relevance'
            soup = BeautifulSoup(requests.get(url).content, "html.parser")
            data = json.loads(soup.find('iw-search')[':results'])
            for d in data:
                link = 'https://www.immoweb.be/en/classified/{}'.format(d['id'])
                if link ==0:
                   break
                #etc
                
except:
    pass

Excepto que sigue iterando en la página sin nunca iterar en "cat".

¿Hay alguna manera de romper con ese bucle anidado? Gracias por adelantado !

0
Thoms 8 may. 2021 a las 02:13

2 respuestas

La mejor respuesta

Hay dos maneras. Puede agregar una bandera de "salida". Establezca exit en False antes del primer bucle y verifíquelo en los bucles externos. Eso es lo que hace este código.

import requests
import numpy as np
from bs4 import BeautifulSoup    

cats = ['house', 'apartment']
try:
    exit = False
    for cat in cats:
        pages = np.arange(1,500)
        for p in page:
            url ='https://www.immoweb.be/en/search/'+str(cat)+'/for-sale?countries=BE&page='+str(page)+'&orderBy=relevance'
            soup = BeautifulSoup(requests.get(url).content, "html.parser")
            data = json.loads(soup.find('iw-search')[':results'])
            for d in data:
                link = 'https://www.immoweb.be/en/classified/{}'.format(d['id'])
                if link ==0:
                   exit = True
                   break
                #etc
            if exit: break
        if exit: break
                
except:
    pass

Podría decirse que un mejor diseño es poner todo esto en una función para que pueda return:

import requests
import numpy as np
from bs4 import BeautifulSoup    

def process():
    cats = ['house', 'apartment']
    try:
        for cat in cats:
            pages = np.arange(1,500)
            for p in page:
                url ='https://www.immoweb.be/en/search/'+str(cat)+'/for-sale?countries=BE&page='+str(page)+'&orderBy=relevance'
                soup = BeautifulSoup(requests.get(url).content, "html.parser")
                data = json.loads(soup.find('iw-search')[':results'])
                for d in data:
                    link = 'https://www.immoweb.be/en/classified/{}'.format(d['id'])
                    if link ==0:
                       return
                    #etc                
    except:
        pass
2
Tim Roberts 7 may. 2021 a las 23:19

Seguro; simplemente verifique la condición nuevamente cuando salga del bucle interno:

    for p in page:
        ...
        for d in data:
            link = 'https://www.immoweb.be/en/classified/{}'.format(d['id'])
            if link == 0:
               break
        if link == 0:
            break

Es un poco feo, pero también lo son las otras opciones. Tiene bucles de iteración condicional anidados. Sería bueno tener for d in data while link != 0, pero pocos lenguajes nos dan ese control de bucle complejo. Los descansos de varios niveles también son agradables, en las pocas ocasiones en que los necesitamos.

2
Prune 7 may. 2021 a las 23:17