Scrapy отслеживает и очищает неразрешенные ссылки

У меня есть CrawlSpider, настроенный на переход по определенным ссылкам и сбор новостного журнала, где ссылки на каждый выпуск следуют следующей схеме URL:

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', )), ),
    )

РЕДАКТИРОВАТЬ: я исправил это, используя гораздо более простое регулярное выражение для 2009, 2010, 2011, но мне все еще любопытно, почему вышеизложенное не работает, если у кого-то есть какие-либо предложения.


person Community    schedule 16.12.2011    source источник


Ответы (1)


Вам нужно передать deny аргументов в SgmlLinkExtractor, который собирает ссылки на follow. И вам не нужно создавать так много Rule, если они вызывают одну функцию parse_item. Я бы написал ваш код как:

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',
        ),
    )

Если это настоящие шаблоны URL-адресов в правилах, которые вы используете для parse_item, их можно упростить до этого:

 Rule(SgmlLinkExtractor(
                allow = ('(fr|eg|ec|op|sc|re|in)[0-9]*\.htm', ), 
                callback = 'parse_item',
        ),
 )
person reclosedev    schedule 17.12.2011
comment
Фантастический. Спасибо за помощь! - person ; 17.12.2011