Зацикливание при парсинге википедии
Задача спарсить названия животных и вывести общее количество животных на каждую букву.
import requests
from bs4 import BeautifulSoup
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.143 YaBrowser/22.5.0.1884 Yowser/2.5 Safari/537.36"
}
url = 'https://ru.wikipedia.org/wiki/Категория:Животные_по_алфавиту'
req = requests.get(url, headers=headers).text
while True:
soup = BeautifulSoup(req, 'lxml')
block = soup.find('div', class_='mw-category mw-category-columns')
category_letter = block.find('div', class_='mw-category-group')
category = category_letter.find_next('h3').text
animal_names = block.find_all('li')
animals_names = []
for animal in animal_names:
animal_name = animal.text
animals_names.append(animal_name)
names = 0
for name in animals_names:
if name.startswith(category):
names += 1
names_dict = {}
names_dict.update({category: names})
order = {}
for key in names_dict:
try:
order[key] += int(names_dict[key])
except:
order[key] = int(names_dict[key])
for key, value in order.items():
print(key, value)
links = soup.find('div', id='mw-pages').find_all('a')
for a in links:
if a.text == 'Следующая страница':
url = 'https://ru.wikipedia.org/' + a.get('href')
req = requests.get(url).text
Ошибка в том, что на букве Z код зацикливается, как исправить?
Ответы (2 шт):
Автор решения: CrazyElf
→ Ссылка
Чтобы не зацикливалось нужно прерывать цикл:
for a in links:
if a.text == 'Следующая страница':
url = 'https://ru.wikipedia.org/' + a.get('href')
req = requests.get(url).text
break # нужен для правильной работы else
else:
break # прерывает цикл while
К вашему коду добавлены в конце мои три строчки:
- чтобы правильно сработало
elseу циклаforнуженbreakвнутриfor, ну он в любом случае там нужен для оптимизации - если вы уже нашли ссылку на следующую страницу, то перебирать страницы дальше нет смысла - Ну и второй
break, который вelse, прерывает циклwhileв случае, если не найдена ссылка на следующую страницу
Автор решения: Сергей Ш
→ Ссылка
import requests
from bs4 import BeautifulSoup
url = 'https://ru.wikipedia.org/wiki/Категория:Животные_по_алфавиту'
names_dict = {}
while True:
req = requests.get(url)
soup = BeautifulSoup(req.text, 'lxml')
fragment = soup.find('div', id='mw-pages')
for nam in fragment.find_all('div', class_='mw-category-group'):
category = nam.h3.text
animal_names = [[x.text, f"https://ru.wikipedia.org{x.a['href']}"] for x in nam.find_all('li')]
if not names_dict.get(category):
names_dict[category] = []
names_dict[category] = names_dict[category] + animal_names
hrf = fragment.find_all('a')[-1]
# *_, tmp = soup.find('div', id='mw-pages').find_all('a')
url = f"https://ru.wikipedia.org{hrf['href']}"
if hrf.text != 'Следующая страница':
break
# выводим количество запмсей на букву
for x, y in names_dict.items():
print(x, len(y))
# выводим название и ссылку по букве 'Й'
for name, link in names_dict['Й']:
print(name)
print(link)