2011-12-16 73 views
6

我有一个CrawlSpider设立以下的某些环节和刮新闻杂志,其中的链接,每一个问题遵循下列URL方案:Scrapy是继刮不允许的链接

http://example.com/YYYY/DDDD/index.htm其中YYYY是年份, DDDD是三位或四位数问题编号。

我只想问题928以上,并有我的规则下面。我没有任何问题连接到网站,抓取链接或提取项目(所以我没有包括我的代码的其余部分)。蜘蛛似乎决定遵循不允许的链接。它试图刮掉377,398等问题,并遵循“culture.htm”和“feature.htm”链接。这会引发很多错误,并且不是非常重要,但它需要大量的数据清理。任何关于发生了什么问题的建议?

class crawlerNameSpider(CrawlSpider): 
name = 'crawler' 
allowed_domains = ["example.com"] 
start_urls = ["http://example.com/issues.htm"] 

rules = (
     Rule(SgmlLinkExtractor(allow = ('\d\d\d\d/(92[8-9]|9[3-9][0-9]|\d\d\d\d)/index\.htm',)), follow = True), 
     Rule(SgmlLinkExtractor(allow = ('fr[0-9].htm',)), callback = 'parse_item'), 
     Rule(SgmlLinkExtractor(allow = ('eg[0-9]*.htm',)), callback = 'parse_item'), 
     Rule(SgmlLinkExtractor(allow = ('ec[0-9]*.htm',)), callback = 'parse_item'), 
     Rule(SgmlLinkExtractor(allow = ('op[0-9]*.htm',)), callback = 'parse_item'), 
     Rule(SgmlLinkExtractor(allow = ('sc[0-9]*.htm',)), callback = 'parse_item'), 
     Rule(SgmlLinkExtractor(allow = ('re[0-9]*.htm',)), callback = 'parse_item'), 
     Rule(SgmlLinkExtractor(allow = ('in[0-9]*.htm',)), callback = 'parse_item'), 
     Rule(SgmlLinkExtractor(deny = ('culture.htm',)),), 
     Rule(SgmlLinkExtractor(deny = ('feature.htm',)),), 
    ) 

编辑:我解决了这个问题用一个更简单的正则表达式FOT 2009年,2010年,2011年,但我仍然好奇,为什么上面的,如果任何人有任何建议不起作用。

回答

8

您需要将deny参数传递给SgmlLinkExtractor,该参数收集指向follow的链接。如果他们调用一个函数parse_item,则不需要创建如此多的Rule。我会写你的代码为:

rules = (
     Rule(SgmlLinkExtractor(
        allow = ('\d\d\d\d/(92[8-9]|9[3-9][0-9]|\d\d\d\d)/index\.htm',), 
        deny = ('culture\.htm', 'feature\.htm'), 
        ), 
      follow = True 
     ), 
     Rule(SgmlLinkExtractor(
       allow = (
        'fr[0-9].htm', 
        'eg[0-9]*.htm', 
        'ec[0-9]*.htm', 
        'op[0-9]*.htm', 
        'sc[0-9]*.htm', 
        're[0-9]*.htm', 
        'in[0-9]*.htm', 
        ) 
       ), 
       callback = 'parse_item', 
     ), 
    ) 

如果它在您使用的是parse_item规则真正的URL模式,它可以简化为这样:

Rule(SgmlLinkExtractor(
       allow = ('(fr|eg|ec|op|sc|re|in)[0-9]*\.htm',), 
       callback = 'parse_item', 
     ), 
) 
+0

神奇。谢谢您的帮助! – Trey 2011-12-17 19:56:55