2013-08-02 60 views
0

我使用this CrawlerSpider example作爲我的履帶的「主幹」。如何使兩個CrawlerSpider規則合作

我想實現這個想法:

第一條規則遵循鏈接。然後將匹配的鏈接進一步傳遞給第二個規則,其中第二個規則根據模式匹配新鏈接並調用它們的回調。

例如,我有規則:

... 

start_urls = ['http://play.google.com/store'] 

rules = (
    Rule(SgmlLinkExtractor(allow=('/store/apps',))), 
    Rule(SgmlLinkExtractor(allow=('/details\?id=',)), callback='parse_app'), 
) 

... 

我怎麼想到的是解析器將工作:

  1. 打開http://play.google.com/store '和第一URL匹配' https://play.google.com/store/apps/category/SHOPPING/collection/topselling_free'發現

  2. 通行證URL('https://play.google.com/store/apps/category/SHOPPING/collection/topselling_free')到第二條規則

  3. 第二條規則試圖匹配它的模式(allow =('。*/details \?id =',))),如果匹配,則爲該URL調用回調'parse_app'。

Atm,Crawler只是遍歷所有鏈接,並沒有解析任何東西。

+0

你的意思是你想解析符合模式「/store/apps/.*/details\?id=」的鏈接? –

+0

@徐家灣,是的,但首先我需要去查找符合第一條規則的所有鏈接,然後才從這些匹配的URL中提取符合第二條規則的其他網址。 – dimazubrik

回答

1

徐家灣意味着,匹配的URL /details\?id=也匹配/store/apps(從我所看到的簡單)

因此,嘗試改變規則的順序有parse_app規則符合:

rules = (
    Rule(SgmlLinkExtractor(allow=('/details\?id=',)), callback='parse_app'), 
    Rule(SgmlLinkExtractor(allow=('/store/apps',))), 
) 

或者使用deny

rules = (
    Rule(SgmlLinkExtractor(allow=('/store/apps',), deny=('/details\?id=',))), 
    Rule(SgmlLinkExtractor(allow=('/details\?id=',)), callback='parse_app'), 
) 

如果你想第一條規則()被應用上「http://play.google.com/store」,然後使用第二個規則()調用parse_app,您可能需要實現parse_start_url方法 用來生成請求SgmlLinkExtractor(allow=('/store/apps',))

喜歡的東西

from scrapy.http import Request 
from scrapy.contrib.spiders import CrawlSpider, Rule 
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor 
from scrapy.selector import HtmlXPathSelector 
from scrapy.item import Item 

class PlaystoreSpider(CrawlSpider): 
    name = 'playstore' 
    #allowed_domains = ['example.com'] 
    start_urls = ['https://play.google.com/store'] 

    rules = (
     #Rule(SgmlLinkExtractor(allow=('/store/apps',), deny=('/details\?id=',))), 
     Rule(SgmlLinkExtractor(allow=('/details\?id=',)), callback='parse_app'), 
    ) 

    def parse_app(self, response): 
     self.log('Hi, this is an app page! %s' % response.url) 
     # do something 


    def parse_start_url(self, response): 
     return [Request(url=link.url) 
       for link in SgmlLinkExtractor(
        allow=('/store/apps',), deny=('/details\?id=',) 
       ).extract_links(response)]