Python рекурсивное сканирование для URL - PullRequest
1 голос
/ 21 июля 2011

У меня есть этот метод, который, когда предоставляется список ссылок, получит дочерние ссылки и так далее и так далее:

def crawlSite(self, linksList):
    finalList = []
    for link in list(linksList):
        if link not in finalList:
            print link            
            finalList.append(link)
            childLinks = self.getAllUniqueLinks(link)
            length = len(childLinks)
            print 'Total links for this page: ' + str(length)

        self.crawlSite(childLinks)
    return finalList

Это в конечном итоге повторится с тем же набором ссылок, и я не могу понять это. Когда я перемещаю self.crawlSite(childLinks) внутри оператора if. Я получаю первый пункт в списке повторяется снова и снова.

Справочная информация о методе self.getAllUniqueLinks(link) позволяет получить список ссылок с данной страницы. Он фильтрует по всем кликабельным ссылкам внутри данного домена. По сути, я пытаюсь получить все ссылки с кликами на веб-сайте. Если это не желаемый подход. Не могли бы вы порекомендовать лучший метод, который может сделать то же самое. Также учтите, что я довольно плохо знаком с Python и, возможно, не понимаю более сложные подходы. Поэтому, пожалуйста, объясните ваши мыслительные процессы. Если не возражаете :)

Ответы [ 2 ]

3 голосов
/ 21 июля 2011

Вам нужно

finalList.extend(self.crawlSite(childLinks))

не просто

self.crawlSite(childLinks)

Вам необходимо объединить список, возвращенный внутренними crawlSite() s, со списком, уже существующим во внешнем crawlSite(). Хотя все они называются finalList, у вас есть разные списки в каждой области.

Альтернативное (и лучшее) решение состоит в том, чтобы finalList был переменной экземпляра (или нелокальной переменной какого-либо типа), а не просто локальной переменной, чтобы он был общим для всех областей действия crawlSite() s:

def __init__(self, *args, **kwargs):
    self.finalList = set()

def crawlSite(self, linksList):
    for link in linksList:
        if link not in self.finalList:
            print link            
            self.finalList.add(link)
            childLinks = self.getAllUniqueLinks(link)
            length = len(childLinks)
            print 'Total links for this page: ' + str(length)
            self.crawlSite(childLinks)

Вам просто нужно убедиться, что вы self.finalList = [] хотите начать все заново с того же экземпляра.

Редактировать: Исправил код, поместив рекурсивный вызов в блок if. Использовал набор. Кроме того, linksList не должен быть списком, просто повторяемым объектом, поэтому удалите вызов list() из цикла for. Набор был предложен @ Ray-Toal

2 голосов
/ 21 июля 2011

Вы очищаете массив finalLinks при каждом рекурсивном вызове.

Необходим более глобальный набор ссылок, которые вы уже посетили. Каждый рекурсивный вызов должен вносить свой вклад в этот глобальный список, в противном случае, если ваш график имеет циклы, вы обязательно в конечном итоге посетите сайт дважды.

ОБНОВЛЕНИЕ: посмотрите хороший шаблон, используемый в DFS на графике с использованием генератора питонов . Ваш finalList может быть параметром, по умолчанию []. Добавляйте в этот список при каждом рекурсивном вызове. Кроме того, FWIW, рассмотрим set, а не list --- это быстрее.

...