2012-11-12 172 views
0
class Crawler1(object): 
    def __init__(self): 
     'constructor' 
     self.visited = [] 
     self.will_visit = [] 

    def reset(self): 
     'reset the visited links' 
     self.visited = [] 
     self.will_visit = [] 

    def crawl(self, url, n): 
     'crawl to depth n starting at url' 
     self.analyze(url) 
     if n < 0: 
      self.reset() 
     elif url in self.visted: 
      self.crawl(self.will_visit[-1],n-1) 
     else: 
      self.visited.append(url) 
      self.analyze(url) 
      self.visited.append(url) 
      self.will_visit.pop(-1) 
      self.crawl(self.will_visit[-1],n-1) 


    def analyze(self, url): 
     'returns the list of URLs found in the page url' 
     print("Visiting", url) 
     content = urlopen(url).read().decode() 
     collector = Collector(url) 
     collector.feed(content) 
     urls = collector.getLinks() 
     for i in urls: 
      if i in self.will_visit: 
       pass 
      else: 
       self.will_visit.append(i) 

我希望這個節目通過一系列的鏈接運行,但只到「N」讓它網絡爬蟲類

我不知道什麼是錯的代碼,但我敢肯定它很多。一些提示會很好。

預期輸出如果n = 1和Site 1中有對站點2和Site3鏈接:

Visiting [Site1] 
Visiting [Site2] 
Visiting [Site3] 
+0

你如何運行程序,以及目前爲止你看到了什麼行爲?我猜'c = Crawler1(); c.crawl('Site1',3)'。 – Edmund

+0

完全一樣。我得到'visting Site1',然後錯誤代碼'AttributeError:'Crawler1'對象沒有屬性'visted'' –

+0

嗯,這可能是因爲你在「visted」中缺少'i';)之後的任何其他錯誤? – Edmund

回答

2

你需要仔細想想應該如何表現,尤其是在如何決定抓取到另一頁。此代碼是集中在crawl方法:

  1. 如果n < 0,那麼你已經爬夠深,不想做任何事情。所以在這種情況下簡單地返回。

  2. 否則,分析頁面。然後,您要抓取每個新的網址,深度爲n-1

我認爲,困惑的一部分是你要保持一個urls隊列來訪問,但也遞歸爬行。首先,這意味着隊列不僅包含您想要按順序訪問的最後一個已爬網url的子項,還包含來自其他爬網但尚未完全處理的其他節點的子項。以這種方式管理深度優先搜索的形狀很困難。

取而代之,我將刪除will_visit變量,並讓analyze返回找到的鏈接的列表。然後,處理根據該列表到上面的步驟2,是這樣的:

# Crawl this page and process its links 
child_urls = self.analyze(url)  
for u in child_urls: 
    if u in self.visited: 
     continue # Do nothing, because it's already been visited 
    self.crawl(u, n-1) 

對於這個工作,你還需要改變analyze只返回URL列表中,而不是將它們放入堆棧:

def analyze(self, url): 
    ... 
    urls = collector.getLinks() 
    returns urls 
+1

好吧,我把這一切都設置好了,但是說NoneType不可迭代。我明白它的含義,你如何迭代一個函數? –

+0

我忘了指出'analyze'方法也需要改變。 – Edmund

+0

我已經改變了它,但同樣的錯誤 –