Scrapy отслеживает недопустимые ссылки - PullRequest
6 голосов
/ 16 декабря 2011

У меня есть 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, но мне все еще любопытно, почему выше не работает, если у кого-то естьлюбые предложения.

1 Ответ

7 голосов
/ 17 декабря 2011

Вам нужно передать 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',
        ),
 )
...