2013-08-02 2 views
0

Я использую this CrawlerSpider example как «позвоночник» для моего Crawler.Как сделать два правила 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. Pass найдено URL ('https://play.google.com/store/apps/category/SHOPPING/collection/topselling_free') на второе правило

  3. Второе правило пытается сопоставить его шаблон (allow = ('. */Details \? Id =',))) и, если он соответствует, вызывает обратный вызов 'parse_app' для этого URL-адреса.

Atm, Crawler просто просматривает все ссылки и не разбирает ничего.

+0

вы имеете в виду, что вы хотите делать для анализа ссылок, соответствующих шаблону «/store/apps/.*/details\?id=»? –

+0

@XuJiawan, да, но сначала мне нужно пройти все ссылки, соответствующие первому правилу, и только затем извлечь из этих сопоставленных URL других URL-адресов, соответствующих второму правилу. – dimazubrik

ответ

1

Как следует Сюй Jiawan, URL соответствия /details\?id= также соответствовать /store/apps (от того, что я видел кратко)

Так попробуйте изменить порядок правил, чтобы иметь матч parse_app Правило первое:

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

Or использовать 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)] 
Смежные вопросы