1

Webページのオブジェクトグラフを作成しようとしています(エッジはページ間の「関連」リンクです)。これが機能するようになったら、キーを URL としてオブジェクトの辞書を作成し、同じページの複数のオブジェクトを作成しないようにします。

私はクラス Page() を持っており、内部のページはタイプ Page() のオブジェクトで満たされたリストです。ルート ページ オブジェクトで関数 root.crawlRelated() を呼び出します。これにより、リストが作成されます。次に、リストを反復処理して obj.crawlRelated() を呼び出します。私の目標は、root.related[] の各オブジェクト Page() に関連ページのリストを設定することです。

私がクロールしている Web サイトでは、各ページに 5 つの関連リンクがあるため、2 世代後には関連する 5 つのオブジェクトを持つルートが存在し、それらのオブジェクトのそれぞれに関連する 5 つのオブジェクトがあるはずです。私が抱えている問題は、crawlRelated() メソッドが、root.related のそれぞれのオブジェクトではなく、すべてのオブジェクトを root に追加していることです。

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 i > 3: break 行は、このバグが原因で発生する無限ループを防ぐためのものです。

このコード行が実行された後

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

返してほしい

>>5
>>5

私は何を間違っていますか?ありがとう。

4

1 に答える 1

0

キーは、コードのこのセクションにあります。

class Page():

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

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

relatedクラス変数として宣言しました。つまり、クラスのすべてのインスタンスがPage1 つの配列を共有します。アクセスするかどうかにかかわらずroot.relatedrel.relatedそれはすべて同じ配列です。rel.relatedしたがって、たとえば(メソッド内で)に追加したものは、crawlにアクセスしたときにも表示されますroot.related

解決策はrelated、コンストラクターで代入するだけで、インスタンス変数を作成することです。その間、対応するインスタンス変数によってマスクされるため、クラス変数の他の宣言をおそらく削除する必要があります。基本的に、次のようにクラスを開始します。

class Page():
    def __init__(self, title, link, relatedURLs):
        self.__title = title
        self.__link = link
        self.__relatedURLs = relatedURLs
        self.related = []
于 2013-05-18T03:32:16.693 に答える