цикл while true в python
Вопрос по завершению цикла while
при парсинге
offset = 1
while True:
website = f'https://new.zonafilm.ru/api/series?page={offset}'
usag = fake_useragent.UserAgent().random
random_usag = {"User-Agent": usag}
respon = requests.get(website, headers=random_usag).json()
data = respon.get('data')
files = []
for item in data:
if 'description' in item :
files.append({
'title': item.get('title'),
'desc': item.get('description'),
'image': item.get('cover_url')
})
else:
break
print(files)
offset += 1
После того, как цикл прошелся по всем страницам, вместо завершения функции на экран выводит скобки []
, хотя в условиях обозначил, что должно быть завершение.
Прошу пнуть в нужном направлении, где допустил ошибку, к сожалению, сам не могу дойти до решения.
Заранее спасибо, и извиняюсь за, возможно, глупый вопрос.
Ответы (3 шт):
Walrus
Моржовый (walrus) оператор, появившийся в Python 3.8,
дает возможность решить сразу две задачи:
- присвоить значение переменной
- вернуть это значение
Первое, files = []
должен быть вне цикла while
.
Второе, напиши функцию get_data(offset)
, в ней это всё: website
, usag
, random_usag
и вызывай её в условии цикла:
def get_data(offset):
if offset < 11:
return f"offset == {offset}"
else:
return None
offset = 1
while data := get_data(offset):
# далее обработка...
print(data)
offset += 1
Для оператора ”walrus” есть PEP 572,
начните знакомство с раздела Примеры (Examples)
Раз уж некоторые хотят архитектурно красивое решение, то, по-моему, надо делать так (не смог проверить, надеюсь, работает):
def get_data():
offset = 1
while True:
website = f'https://new.zonafilm.ru/api/series?page={offset}'
usag = fake_useragent.UserAgent().random
random_usag = {"User-Agent": usag}
respon = requests.get(website, headers=random_usag).json()
data = respon.get('data')
if data:
yield from data
else:
break
offset += 1
files = [{
'title': item.get('title'),
'desc': item.get('description'),
'image': item.get('cover_url')
} for item in get_data()]
print(files)
Поведение здесь отличается от того, что в вопросе, поскольку там через print выводилась каждая страница в отдельности, а тут - только все данные вместе.
Если нужно изменить так, чтобы вывод появлялся по мере появления данных, надо сделать вывод по одной строке с помощью
for item in get_data():
print({
'title': item.get('title'),
'desc': item.get('description'),
'image': item.get('cover_url')
})
Если важны именно страницы, то надо выкинуть отсюда from
yield from data
После чего в цикле for
обрабатывать страницы:
for items in get_data():
files = [{
'title': item.get('title'),
'desc': item.get('description'),
'image': item.get('cover_url')
} for item in items]
print(files)
PS: В зависимости от задачи может быть удобнее перенести маппинг внутрь функции получения данных.