#python #recursion #beautifulsoup
#python #рекурсия #beautifulsoup
Вопрос:
Я уже некоторое время обдумываю эту проблему, для личного проекта мне нужно получить любую ссылку с указанных начальных веб-страниц, которая не является внешней ссылкой, т.Е. Не покидает исходный веб-сайт.
Я уже использую bs4 для очистки веб-страниц от ссылок, однако я не могу найти способ продолжать делать это для каждой очищенной ссылки, не достигнув в конечном итоге максимальной глубины рекурсии.
Моя предыдущая попытка состояла из чего-то вроде этого:
link_list = []
link_buffer = ["www.example.com"]
def get_links(current_link):
new_links = []
soup = BeautifulSoup(current_link, "html.parser")
for link in soup.find_all("a"):
if link.has_attr("href"):
... # check here if the link does not leave the website
new_links.append(link)
return new_links
def get_all_the_links(list_of_links):
target = list_of_links.pop()
link_list.append(target)
...
for link in get_links(target):
...
if link not in link_list:
list_of_links.append(link)
if list_of_links.len() != 0: # recursiveness
get_all_the_links(list_of_links)
get_all_the_links(link_buffer)
Я также просмотрел scrapy, однако нашел его слишком сложным для того, что я пытаюсь сделать, поскольку я просто планирую сохранить эти ссылки в текстовый файл, а затем обработать их позже.
Комментарии:
1. Проблема, скорее всего, в циклических ссылках. Представьте, что страница A указывает на страницу B, а страница B указывает на страницу A. Тогда ваш алгоритм будет вечно переключаться между страницами A и B. Быстрое исправление: поддерживайте набор
already_visited
и посещайте только те ссылки, которые вы еще не посетили.2. Извините, у меня уже есть нечто подобное, и я отредактировал свой код, чтобы отразить это. Я считаю, что моя главная проблема заключается в том, что сайт, который я хочу просмотреть, на самом деле очень большой, поэтому мне нужен более сложный подход, чем просто сканирование по нему.
3. Не используйте рекурсию. Используйте бесконечный
while
цикл, который принимает URL-адрес изlist
илиQueue
, пока он не станет пустым. Когда вы анализируете каждую страницу и находите новые URL-адреса, добавляйте их в список / очередь. Как упоминал Stef , вам нужно отслеживать URL-адреса, которые вы посетили, чтобы не застрять в цикле. Вам также потребуется нормализовать URL-адреса. Смотрите en.wikipedia.org/wiki/URI_normalization
Ответ №1:
Приведенный вами пример кода немного запутан. Но в целом вам просто нужна дополнительная переменная хранилища для посещенных ссылок и проверьте, известна ли ссылка уже раньше
visited_links = set()
...
def get_all_the_links(list_of_links):
target = list_of_links.pop()
if target in visited_links:
# Ignore the current link and move on to next one.
get_all_the_links(list_of_links)
else:
visited_links.add(target)
...
# process link here...
...