2017-05-01 6 views
0

広範囲のクロール中に最初の10-20個の内部リンクを削り取る必要があるため、Webサーバーには影響しませんが、 "allowed_domains"のドメインScrapyのドキュメントではこれをカバーしていないため、私はGoogleから回答を見つけることができないので、ここで質問しています。これらの両方があれば、パフォーマンスに影響を与え、許可されているドメインのリストのサイズを制限するであろう、正規表現を使用するように見えるよう広範囲なクロール - 広範なクロール時に内部リンクのみを許可する、allowed_domainsのドメインが多すぎる

from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor 
from scrapy.item import Item, Field 

class DomainLinks(Item): 
    links = Field() 

class ScapyProject(CrawlSpider): 
    name = 'scapyproject' 

    #allowed_domains = [] 
    start_urls = ['big domains list loaded from database'] 

    rules = (Rule(LxmlLinkExtractor(allow=()), callback='parse_links', follow=True),) 

    def parse_start_url(self, response): 
     self.parse_links(response) 

    def parse_links(self, response): 
     item = DomainLinks() 
     item['links'] = [] 

     domain = response.url.strip("http://","").strip("https://","").strip("www.").strip("ww2.").split("/")[0] 

     links = LxmlLinkExtractor(allow=(),deny =()).extract_links(response) 
     links = [link for link in links if domain in link.url] 

     # Filter duplicates and append to 
     for link in links: 
      if link.url not in item['links']: 
       item['links'].append(link.url) 

     return item 

は、allowed_domainsリストを使用せずにリンクをフィルタリングし、LxmlLinkExtractorは、フィルタを許可するための最良の方法以下のリスト内包です各スクラップされたリンクは、リスト内のすべてのドメインに対して正規表現マッチングされますか?

links = [link for link in links if domain in link.url] 

私が解決しようとしているもう一つの問題は、スパイダーがallowed_domainsリストを使わずに内部リンクをたどるようにする方法です。カスタムミドルウェア?

おかげ

答えて

1

はい、あなたのリストの内包は、これを処理するための良い、おそらく最良の方法です。

links = [link for link in links if domain in link.url] 

それは次のような利点があります

  • それだけで、あなたのスクレーパーは、おそらくネットワークがこれを拘束されるように(非常に高速である内部リンクを受け入れ、他のホワイトリストのドメイン
  • へのリンクを無視します)多くのそれは、ルックアップテーブルまたはいくつかの巨大な正規表現をせずに動作します
  • を問題ではないはず

この他にも、私はドメインを抽出するためにurllibはを使用することをお勧め:Get domain name from URL

そして、あなたが唯一の内部リンクをクロールする場合は、あなたがすることによって、これを達成することができます:

parseparse_linksの名前を変更するルール
  • を取り除く
    • 手動
    • のみ内部リンクに従うために、新しい要求を作成します。

      def parse(self, response): 
      
          # your code ... removed for brevity ... 
      
          links = [link for link in links if domain in link.url] 
      
          # Filter duplicates and append to 
          for link in links: 
           if link.url not in item['links']: 
            item['links'].append(link.url) 
           yield Request(link) 
      
          yield item 
      
  • 関連する問題