2015-10-03 15 views
5

Ho lavorato a un raschiatore raschiato che striscia attraverso tutti i collegamenti interni da un URL di avvio e raccoglie solo collegamenti esterni con scrapy. Tuttavia, il mio problema principale è la classificazione dei collegamenti esterni e dei collegamenti interni. Ad esempio, quando provo a filtrare i collegamenti esterni con link.startswith("http") or link.startswith("ftp") or link.startswith("www"), se il sito Web collega il proprio sito Web con un percorso assoluto (www.my-domain.com/about anziché /about), lo classificherà come collegamento esterno anche se non lo è. Quello che segue è il mio codice:Scrapy: archivia tutti i collegamenti esterni e scansiona tutti i collegamenti interni

import scrapy 
from lab_relationship.items import Links 

class WebSpider(scrapy.Spider): 
    name = "web" 
    allowed_domains = ["my-domain.com"] 
    start_urls = (
     'www.my-domain.com', 
    ) 

    def parse(self, response): 
     """ finds all external links""" 
     items = [] 
     for link in set(response.xpath('//a/@href').extract()): 
      item = Links() 
      if len(link) > 1: 
       if link.startswith("/") or link.startswith("."): 
        # internal link 
        url = response.urljoin(link) 
        item['internal'] = url 
        #yield scrapy.Request(url, self.parse) 
       elif link.startswith("http") or link.startswith("ftp") or link.startswith("www"): 
        # external link 
        item['external'] = link 
       else: 
        # misc. links: mailto, id (#) 
        item['misc'] = link 
       items.append(item) 
     return items 

Qualche suggerimento?

risposta

7

Utilizzare link extractor.

Durante l'istanziazione è necessario passare il dominio consentito. Non devi preoccuparti di specificare i tag richiesti, in quanto (secondo i documenti) il parametro tags accetta ('a', 'area') per impostazione predefinita.

Sul esempio di sito web Rust Lang, il codice per stampare tutti i collegamenti interni dal loro dominio sarà simile:

import scrapy 
from scrapy.linkextractors import LinkExtractor 


class RustSpider(scrapy.Spider): 
    name = "rust" 
    allowed_domains = ["www.rust-lang.org"] 
    start_urls = (
     'http://www.rust-lang.org/', 
    ) 

    def parse(self, response): 
     extractor = LinkExtractor(allow_domains='rust-lang.org') 
     links = extractor.extract_links(response) 
     for link in links: 
      print link.url 

e l'uscita sarebbe un elenco di tali link: https://doc.rust-lang.org/nightly/reference.html (posso' t post più), escludendo tutti i link come quelli di StackOverflow.

Si prega di controllare la pagina di documentazione, come link extractor ha molti parametri che potrebbe essere necessario.

+0

Hm .. stai suggerendo di creare una serie di collegamenti interni con LinkExtractor e per tutti i link, controlla se corrispondono ai collegamenti interni e, in caso negativo, si tratta di collegamenti esterni? –

+0

Non esattamente, impostando 'deny_domains = 'dominio'' puoi estrarre link che non si trovano in un dato dominio (esterno). –

+0

Oh uomo. È perfetto. Grazie mille. –

-2

Il se può richiedere più o istruzioni, non solo due.

+0

Ma il mio array includerà anche collegamenti interni. Voglio solo collegamenti esterni –

+0

Sì, l'ho notato. Osservando il tuo codice, "if link.startswith ("/") o link.startswith (". "):" La riga può avere più "o" istruzioni, altrimenti può essere usata una [opzione] (https: // pypi. python.org/pypi/switch) statement – kcrk

+0

Sto già usando multiple 'or's nel mio codice, e non vedo come questo filtra i link assoluti dai link relativi –

Problemi correlati