2013-05-18 45 views
1

我正在尝试制作网页的对象图(边之间的'相关'链接页面)。一旦我得到这个工作,我将创建一个关键字作为URL的对象字典,这样我就不会创建同一页面的多个对象。在相同类型的对象中迭代对象列表

我有一个类Page(),里面的页面是一个用Page()类型的对象填充的列表。我在根页面对象上调用函数root.crawlRelated()。这填充列表。然后我尝试遍历列表并调用obj.crawlRelated()。我的目标是,然后用它们相关的页面的列表填充每个对象的Page()在root.related []中。

在网站上,我爬每一页有5个相关链接,所以两代之后应该有根在相关的5个对象,并且每个这些对象应在其相关的5个对象。我遇到的问题是,crawlRelated()方法将所有对象追加到root,而不是root.related中的相应对象。

from urllib import urlopen 
#from bs4 import BeautifulSoup 
import re 

####################CLASS PAGE###################### 
class Page(): 

    __title = "" 
    __link = "" 
    related = [] 
    __relatedURLs = [] 

    def __init__(self, title, link, relatedURLs): 
     self.__title = title 
     self.__link = link 
     self.__relatedURLs = relatedURLs 

    def get_attributes(self,key): 
     return self.__attributes.get(key,None) 

    def get_relatedURLs(self): 
     return self.__relatedURLs 

    def get_title(self): 
     return self.__title 

    def crawl(self,url): 
     webpage = urlopen(url).read() 
     patFinderTitle = re.compile('<title>(.*)</title>') 
     patFinderLink = re.compile('<link rel="canonical" href="([^"]*)" />') 
     patFinderRelated = re.compile('<li><a href="([^"]*)"') 

     findPatTitle = re.findall(patFinderTitle, webpage) 
     findPatLink = re.findall(patFinderLink, webpage) 
     findPatRelated = re.findall(patFinderRelated, webpage) 

     self.related.append(Page(findPatTitle,findPatLink,findPatRelated)) 

    def crawlRelated(self): 
     for link in self.__relatedURLs: 
      self.crawl(link) 
      print 'crawled related in', self.__title 
####################END CLASS######################   


print 'doing some work...' 
webpage = urlopen('http://medtwice.com/am-i-pregnant/').read() 

patFinderTitle = re.compile('<title>(.*)</title>') 
patFinderLink = re.compile('<link rel="canonical" href="([^"]*)" />') 
patFinderRelated = re.compile('<li><a href="([^"]*)"') 

findPatTitle = re.findall(patFinderTitle, webpage) 
findPatLink = re.findall(patFinderLink, webpage) 
findPatRelated = re.findall(patFinderRelated, webpage) 

print 'found the webpage', findPatTitle 

root = Page(findPatTitle,findPatLink,findPatRelated) 
print 'Now crawling', root.get_relatedURLs() 
root.crawlRelated() 
print 'done crawling related' 
print 'crawling related gen 2...' 

i = 0 
for rel in root.related: 
    print 'crawling', rel#.get_title() 
    #print rel.get_relatedURLs() 
    rel.crawlRelated() 
    i += 1 
    if i > 3: 
     break 

print 'done crawling related gen 2' 
print root.related 
print len(root.related) 
print len(root.related[0].related) 

if if> 3:break line是为了防止由于这个bug而发生的无限循环。

后这行代码运行

print len(root.related) 
print len(root.related[0].related) 
>> 25 
>> 25 

我想它返回

>>5 
>>5 

我在做什么错?谢谢。

回答

0

的关键是在你的代码的这一部分:

class Page(): 

    __title = "" 
    __link = "" 
    related = [] 
    __relatedURLs = [] 

    def __init__(self, title, link, relatedURLs): 
     self.__title = title 
     self.__link = link 
     self.__relatedURLs = relatedURLs 

您已经声明related为类变量。这意味着类Page的所有实例共享一个数组。无论您访问root.related还是rel.related左右,它都是相同的阵列。因此,当您访问root.related时,您添加的任何内容(例如,rel.related(在crawl方法中))也会出现。

的解决方案是使related一个实例变量,通过仅在构造分配给它。当你在这,你或许应该删除类变量的其他声明,因为他们得到相应的实例变量掩盖。基本上,像这样开始你的课程:

class Page(): 
    def __init__(self, title, link, relatedURLs): 
     self.__title = title 
     self.__link = link 
     self.__relatedURLs = relatedURLs 
     self.related = [] 
+0

感谢这正是我所需要的。 :) –