2017-09-21 17 views
2

私はfoo.comを這っていると想像してください。 foo.com自体にはいくつかの内部リンクを持っており、それはのようないくつかの外部リンクがあります:私は、そのような私がscrapyに行きたいなどの外部リンクのために、すべての内部リンクだけでなく、唯一の深さをクロールするscrapyを希望治療は1つの深さだけ外部リンクに従います

foo.com/hello 
foo.com/contact 
bar.com 
holla.com 

bar.comまたはholla.comに、それ以外のリンクはbar.com内にありますので、深さは1にしてください。

これは可能ですか?この場合の設定は何でしょうか?

ありがとうございました。

答えて

1

CrawlSpiderクラスにスパイダーを配置し、Ruleに実装されているメソッドを実装してRuleに渡すことができます。この方法は、望ましくないリンクを追跡する前にそれをフィルタリングします。 documentationから:

process_linksを用いて、各応答から抽出された各リンクリストに対して呼び出さされる呼び出し可能な、または(その名前のクモオブジェクトからメソッドが使用される場合)の文字列でありますlink_extractorを指定します。これは主にフィルタリングの目的で使用されます。

0

組み込みのソリューションではありませんが、自分で再帰を混乱させる必要があります。あなたはスパイダーにドメインの配列(セット)を保ち、干渉したり無視したりすることで簡単にそれを行うことができます。ソートの

気にいら:

from urllib.parse import urlparse 

self.track = set() 

... 
domain = tracktraurlparse(response.url).netloc 
x.add(domain) 
if len(x) > MAX_RECURSION: 
    x.remove(domain) 
    # raise StopIteration (# if you're within a generator) 
    return None 
0

私は、コールバック関数の引数を渡すことで解決策を見つけました。 urlが内部リンクの場合は、flagをtrue(そうでない場合はfalse)に設定します。フラグがfalse(外部リンク)を返した場合、クローラは新しいリンクを抽出しません。ここで私のサンプルコード:

class BrokenLinksSpider(CrawlSpider): 
name = test 
start_urls = "your_url" 

def parse(self, response): 
    flag = response.meta.get('flag') 
    if flag or flag==None: 
     extractor = LinkExtractor(deny_domains="") 
     links = extractor.extract_links(response) 
     for link in links: 
      if link.url[:8]=="your_url": 
       new_request = Request(link.url, callback=self.parse,meta={'flag': True}) 
      else: 
       new_request = Request(link.url, callback=self.parse,meta={'flag': False}) 
      yield new_request