2015-01-15 15 views
9

Voglio ottenere tutti i link esterni da un determinato sito web usando Scrapy. Utilizzando il seguente codice il ragno striscia link esterni così:Scrapy, segui solo URL interni ma estrai tutti i link trovati

from scrapy.contrib.spiders import CrawlSpider, Rule 
from scrapy.contrib.linkextractors import LinkExtractor 
from myproject.items import someItem 

class someSpider(CrawlSpider): 
    name = 'crawltest' 
    allowed_domains = ['someurl.com'] 
    start_urls = ['http://www.someurl.com/'] 

    rules = (Rule (LinkExtractor(), callback="parse_obj", follow=True), 
) 

    def parse_obj(self,response): 
    item = someItem() 
    item['url'] = response.url 
    return item 

Che cosa mi manca? "Permessi_domini" non impedisce la scansione dei link esterni? Se imposto "allow_domains" per LinkExtractor, non estrae i collegamenti esterni. Giusto per chiarire: non voglio eseguire la scansione dei collegamenti interni ma estrarre i link esterni. Qualsiasi aiuto appriciato!

+0

Se abilito l'OffsiteMiddleware i collegamenti non vengono scansionati ma anche non estratti. Almeno allora riesco a vedere "Richiesta offsite filtrata a" www.externaldomain "Sicuramente mi manca qualcosa di banale qui? – sboss

+0

solo per capire: vuoi avere l'elenco di tutti i link esterni per un determinato sito web? – aberna

+0

Sì che è corretto! – sboss

risposta

9

È inoltre possibile utilizzare l'estrattore link per tirare tutti i collegamenti una volta che si sta analizzando ogni pagina.

L'estrattore di collegamenti filtrerà i collegamenti per voi. In questo esempio, l'estrattore di collegamenti rifiuterà i collegamenti nel dominio consentito in modo che riceva solo collegamenti esterni.

from scrapy.contrib.spiders import CrawlSpider, Rule 
from scrapy.contrib.linkextractors import LxmlLinkExtractor 
from myproject.items import someItem 

class someSpider(CrawlSpider): 
    name = 'crawltest' 
    allowed_domains = ['someurl.com'] 
    start_urls = ['http://www.someurl.com/'] 

    rules = (Rule(LxmlLinkExtractor(allow=()), callback='parse_obj', follow=True),) 


    def parse_obj(self,response): 
    for link in LxmlLinkExtractor(allow=(),deny = self.allowed_domains).extract_links(response): 
     item = someItem() 
     item['url'] = link.url 
3

Una soluzione potrebbe essere l'utilizzo rendono una funzione process_link nel SgmlLinkExtractor documentazione qui http://doc.scrapy.org/en/latest/topics/link-extractors.html

class testSpider(CrawlSpider): 
    name = "test" 
    bot_name = 'test' 
    allowed_domains = ["news.google.com"] 
    start_urls = ["https://news.google.com/"] 
    rules = (
    Rule(SgmlLinkExtractor(allow_domains=()), callback='parse_items',process_links="filter_links",follow= True) , 
    ) 

def filter_links(self, links): 
    for link in links: 
     if self.allowed_domains[0] not in link.url: 
      print link.url 

    return links 

def parse_items(self, response): 
    ### ... 
+0

@sboss Ho notato che hai accettato e dopo aver declassato la mia soluzione proposta.Il codice funziona correttamente, hai notato altri problemi? – aberna

+0

Ciao aberna, scusa per il downgrade. Ho trovato 12Ryan12: risposta s più elegante in quanto consente io per usare i filtri duplicati incorporati, ecc. – sboss

3

Un codice aggiornato in base alla risposta del 12Ryan12,

from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor 
from scrapy.item import Item, Field 

class MyItem(Item): 
    url= Field() 


class someSpider(CrawlSpider): 
    name = 'crawltest' 
    allowed_domains = ['someurl.com'] 
    start_urls = ['http://www.someurl.com/'] 
    rules = (Rule(LxmlLinkExtractor(allow=()), callback='parse_obj', follow=True),) 

    def parse_obj(self,response): 
     item = MyItem() 
     item['url'] = [] 
     for link in LxmlLinkExtractor(allow=(),deny = self.allowed_domains).extract_links(response): 
      item['url'].append(link.url) 
     return item 
-2

pip install -U Scrapy Ha risolto il problema)