@Dane4kaa

Задание по парсингу страниц, как оформить в цикле/рекурсии с try/except?

Помогите, пожалуйста, новичку разобраться
Дали задание:
Дана страница (в нашем случае википедия), нужно ее распарсить и извлечь все ссылки, затем перейти по собранным ссылкам и извлечь все ссылки уже из них. Посоветовали использовать рекурсию, глубина рекурсии 3. В итоге нужно из всех собранных ссылок выбрать '.png' и записать в файл.
Я смогла только с 1 страницы все собрать и отсортировать, ни с рекурсией, ни с циклом не выходит. Постоянно получаю либо ConnectionError, либо MemoryError. Понимаю, что нужно вводить try/except, но уже полностью запуталась.
Заранее благодарю!

from bs4 import BeautifulSoup, SoupStrainer
import requests

class Links:
    def get_urls(self, level: int) -> []:
        urls = []
        try:
            links_1 = []
            start_link = "https://ru.wikipedia.org/"
            links_1.append(start_link)
            for i in links_1:
                response = requests.get(i)
                soup = BeautifulSoup(response.content, "html.parser", parse_only=SoupStrainer(['a', 'img']))
                full_list = [link['href'] for link in soup if link.get('href')] + [img['src'] for img in soup if img.get('src')]
                full_list = list(set(full_list))
                for url in full_list:
                    if not url.startswith('https:/'):
                        if url.startswith('/'):
                            if url.find('.org') == -1:
                                url = start_link + url[1:]
                                full_list.append(url)
                            elif url.find('.org'):
                                url = 'https:' + url
                                full_list.append(url)
                        elif url.startswith('//'):
                            url = start_link + url[2:]
                            full_list.append(url)
                        else:
                            pass
                    elif url.startswith('https:/'):
                        full_list.append(url)
                        urls.append(full_list)
                self.get_urls(level - 1)
                links_1 = full_list
                links_1 = list(set(links_1))
                return links_1
        except MemoryError as e:
            print(e)

        return urls


links = Links()
list_links = links.get_urls(level=3)
#with open('text.txt', 'w') as f:
#    for x in list_links:
#        if x.endswith('.png'):
#            f.write('%s\n' % x)
  • Вопрос задан
  • 95 просмотров
Пригласить эксперта
Ответы на вопрос 2
Zarom
@Zarom
Мастер на все руки из жопы
  1. Нигде в коде нет проверки что level стал равен 0. Рекурсия получается бесконечной (у вас в MemoryError упирается)
  2. self.get_urls(level - 1) не возвращает список найденных urlов
Ответ написан
@deliro
Агрессивное программирование
Посоветовали использовать рекурсию, глубина рекурсии 3

По-человечьи это означает, что с изначальной страницы нужно перейти максимум на три уровня.

Нужно сделать:
1. Избавиться от дублей. В обычный set() запихивать урлы, где уже собрала ссылки, чтобы не тратить лишнее время
2. Класс Links переделать. Он должен принимать один урл — где искать ссылки и текущий уровень. Текущий уровень нужен для того, чтобы остановить процесс на уровне 2 (если начинать с нулевого).
3. Экземпляр Links(url="something", level=0) будет порождать другие Links(url="something-else", level=1) и уметь возвращать назад список ссылок. Соответсвенно, если self.level == 2, то найденые ссылки мы не парсим, а просто отдаём наверх
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы