2016-03-19 9 views
0

自分のニーズに合ったクロールスパイダーを作成しました。しかし、私がクロールしているサイト上のいくつかのカテゴリ(すべてではない)には特定のXMLサイトマップがあります。そこで、これらのカテゴリで.xmlサイトマップを解析し、リンクを取得してクロールスパイダーに残して、それらのリンクにもっと深く関わってほしいと思っています。途中でXMLページからのリンクを解析して追加するCrawlspider

SitemapSpiderとXMLFeedSpiderがありますが、XMLFeedSpiderでcrawlspiderの機能が必要であること、またはその逆が必要であることはわかっています。

ご協力いただければ幸いです。

答えて

3

は、サイトマップにURLをCrawlSpiderの作業を行うには、それが見えます:あなただけのコールバックでsitemap_xml_xpathrulesの先頭にルールを追加して編集する必要があります CrawlSpider does not process XML responsesのようになります。したがって、それを受け入れるには、_requests_to_followを上書きする必要があります。ここで

は、私はあなたが/urlset/url/locからページを解析する方法に応じて(sitemapindexを含む)で開始することsitemap.gz URLを

from scrapy.spiders.crawl import CrawlSpider, Rule 
from scrapy.link import Link 
from scrapy.http import Request 


class XmlLinkExtractor(): 

    def __init__(self, xpath, namespaces): 
     self.xpath = xpath 
     self.namespaces = namespaces 

    def extract_links(self, response): 
     selector = response.selector 
     if self.namespaces: 
      for i, ns in self.namespaces.items(): 
       selector.register_namespace(i, ns) 
     for link in selector.xpath(self.xpath).extract(): 
      yield Link(link) 


class ExampleSitemapCrawlSpider(CrawlSpider): 
    name = "myspider" 
    start_urls = (
     # link to a sitemap index file 
     'http://www.example.com/sitemap.gz', 

     # link to a sitemap file 
     #'http://www.example.com/sitemaps/sitemap-general.xml', 
     ) 
    rules = (

     # this handles sitemap indexes, following links to other sitemaps 
     Rule(XmlLinkExtractor('/sm:sitemapindex/sm:sitemap/sm:loc/text()', 
       {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}),), 

     # this is for "leaf" pages in sitemaps 
     Rule(XmlLinkExtractor('/sm:urlset/sm:url/sm:loc/text()', 
       {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}), 
      # here, defining the callback without follow=True 
      # makes the crawler stop at these pages level, 
      # not following deeper links 
      # unset the callback if you want those pages 
      # to go through other rules once downloaded 
      callback='parse_loc'), 
     # ... other rules 
    ) 

    def _requests_to_follow(self, response): 
     # we need to override `_requests_to_follow` 
     # and comment these 2 lines, because they filter XML responses 
     #if not isinstance(response, HtmlResponse): 
     # return 
     seen = set() 
     for n, rule in enumerate(self._rules): 
      links = [lnk for lnk in rule.link_extractor.extract_links(response) 
        if lnk not in seen] 
      if links and rule.process_links: 
       links = rule.process_links(links) 
      for link in links: 
       seen.add(link) 
       r = Request(url=link.url, callback=self._response_downloaded) 
       r.meta.update(rule=n, link_text=link.text) 
       yield rule.process_request(r) 

    def parse_loc(self, response): 
     self.logger.debug("parsing %r" % response) 

を試みた例のクモだ、あなたは別のコールバックに異なるURLをリダイレクトすることもできますparse_sitemap_xmlに来るthatsの応答がNULLであるように思わ前に。予想通り、そのHTMLとして扱われていない()異なるルールを追加すること、およびフィルタリング(またはフィルタリングするためにXPathを使用を許可するようXmlLinkExtractorをカスタマイズ

+0

ありがとうポール、また私が気づいたことは、スティーブンも正しい答えを持っているということです。問題は、私がcrawlspiderでxmlページ(xmlとしてstart_urlsを設定した場合)から始めるときに存在します。 HTMLページで始めるとxmlページに移動すると、crawlspiderはStevenの答えでそのトリックをしているようです。皆、ありがとうございました。返事が遅れて申し訳ありません。 – Saitx

0

現在のCrawlSpiderにルールを追加して、XMLを自分で解析することができます。あなたがXML応答用のカスタムリンク抽出を調理することができ、

import scrapy 
import scrapy.linkextractors 
import scrapy.spiders.crawl 


class SmartlipoSpider(scrapy.spiders.crawl.CrawlSpider): 
    name = "myspider" 
    start_urls = ('http://example.com/',) 
    rules = (
     scrapy.spiders.crawl.Rule(
      scrapy.linkextractors.LinkExtractor(
       allow=r'sitemap\.xml$', 
      ), 
      callback='parse_sitemap_xml', follow=True, 
     ), 
     # the other rules... 
    ) 

    def parse_sitemap_xml(self, response): 
     sitemap_xml_xpath = '/urlset/url' 

     for url in response.xpath(sitemap_xml_xpath): 
      yield scrapy.Request(url) 

    # your other callbacks... 
+0

私はこれを試してみました。 – Saitx

+0

Crawlspiderが戻るのdoesnt xmlの結果。何らかの理由で応答が空になったり、上記のコードでxse_url XML_pageを実行してもparse_sitemap_xmlが実行されません。 – Saitx

関連する問題