2013-04-06 10 views
7

Sono nuovo di Scrapy e sto cercando di eseguire la scansione di più siti da un file di testo con CrawlSpider. Tuttavia, mi piacerebbe limitare la profondità di scraping per il sito e anche il numero totale di pagine scansionate di nuovo per il sito Web. Sfortunatamente, quando gli attributi start_urls e allowed_domains sono impostati, response.meta ['depth'] sembra sempre essere zero (questo non accade quando sto provando a raschiare singoli siti). L'impostazione di DEPTH_LIMIT nel file delle impostazioni non sembra fare nulla. Quando rimuovo la definizione init e semplicemente imposta start_urls e allowed_domains, le cose sembrano funzionare correttamente. Ecco il codice (Ci scusiamo per il rientro - non è questo il problema):Scansione di più siti con Python Scrapy con profondità limitata per sito

class DownloadSpider(CrawlSpider): 
    name = 'downloader' 
    rules = (
    Rule(SgmlLinkExtractor(), callback='parse_item', follow=True), 
    ) 
    def __init__(self, urls_file, N=10): 
     data = open(urls_file, 'r').readlines()[:N] 
     self.allowed_domains = [urlparse(i).hostname.strip() for i in data] 
     self.start_urls = ['http://' + domain for domain in self.allowed_domains] 

    def parse_start_url(self, response): 
     return self.parse_item(response) 

    def parse_item(self, response): 
     print response.url 
     print response.meta['depth'] 

Ciò si traduce in response.meta [ 'profondità'] sempre uguale a zero e la striscia cralwer solo il primo sito di ogni elemento di start_urls (cioè non segue alcun link). Così ho due domande 1) Come limitare la scansione ad una certa profondità per ogni sito in start_urls 2) Come limitare il numero totale delle scansioni per sito, indipendentemente dalla profondità

Grazie!

+0

Sembra che il problema è nella parte in cui si passa gli argomenti al ragno. Se questo viene rimosso, il crawler funziona perfettamente con l'impostazione DEPTH_LIMIT. Tuttavia, ciò rende molto inefficiente alimentarlo con un set di siti in continua evoluzione per la scansione di – gpanterov

risposta

2

Non dimenticare di chiamare i costruttori della classe base (ad esempio con super):

def __init__(self, urls_file, N=10, *a, **kw): 
    data = open(urls_file, 'r').readlines()[:N] 
    self.allowed_domains = [urlparse(i).hostname.strip() for i in data] 
    self.start_urls = ['http://' + domain for domain in self.allowed_domains] 
    super(DownloadSpider, self).__init__(*a, **kw) 

UPDATE:

Quando si sovrascrivono un metodo in Python il metodo della classe base è non viene più chiamato e invece viene chiamato il nuovo metodo, questo significa che se si desidera eseguire la nuova logica in aggiunta alla logica precedente (cioè non invece di), è necessario chiamare la vecchia logica ma nualmente.

Ecco la logica che ti mancava non chiamando il CrawlSpider.__init__() (via super(DownloadSpider, self).__init__()):

self._compile_rules() 
+0

THanks. Questo l'ha risolto (anche se non ho ancora idea del perché - continuerò a sfogliare la documentazione in scrapy) – gpanterov