2013-11-25 16 views
7

Desidero essere in grado di ottenere in modo ricorsivo tutti i collegamenti da un sito Web, quindi seguire tali collegamenti e ottenere tutti i collegamenti da tali siti Web. La profondità dovrebbe essere 5-10 in modo che restituisca una matrice di tutti i collegamenti che trova. Preferibilmente usando una bella zuppa/pitone. Grazie!Come ottenere tutti i collegamenti dal sito Web utilizzando Beautiful Soup (python) in modo ricorsivo

Ho provato fino ad ora e non funziona ... qualsiasi aiuto sarà apprezzato.

from BeautifulSoup import BeautifulSoup 
import urllib2 

def getLinks(url): 
    if (len(url)==0): 
     return [url] 
    else: 
     files = [ ] 
     page=urllib2.urlopen(url) 
     soup=BeautifulSoup(page.read()) 
     universities=soup.findAll('a',{'class':'institution'}) 
     for eachuniversity in universities: 
      files+=getLinks(eachuniversity['href']) 
     return files 

print getLinks("http://www.utexas.edu/world/univ/alpha/") 
+1

Cosa hai provato? Le comunità di SE non sono servizi di scrittura di sceneggiature/programmi. Tendiamo ad aspettarci che qualcuno abbia provato a implementare la propria soluzione e poi chiede quando si imbattono in errori. Per favore pubblica alcuni dei codici che hai provato e quali problemi hai riscontrato. – nerdwaller

+0

ho aggiunto il mio tentativo sopra – coderlyfe

+0

@coderlyfe 2 domande: 1-Cosa intendi per profondità 5-10? Vuoi andare per ottenere link, andare su siti web; ottenere link da tutti quelli, vai al sito ... 5 volte? 2-Come fai a sapere che i siti web che stai per scrivere sono scritti nello stesso modo del primo? stai mettendo una condizione a tutte le a (classe: istituzione).Forse non ci sono collegamenti negli altri siti web con quella classe, il che rende il tuo algoritmo ricorsivo inutilizzabile. – JGallo

risposta

1

algoritmi ricorsivi sono utilizzati per ridurre grossi problemi a quelli più piccoli che hanno la stessa struttura e quindi combinare i risultati. Sono spesso composti da un caso base che non conduce alla ricorsione e un altro caso che porta alla ricorsione. Ad esempio, supponi di essere nato nel 1986 e di voler calcolare la tua età. Potresti scrivere:

def myAge(currentyear): 
    if currentyear == 1986: #Base case, does not lead to recursion. 
     return 0 
    else:     #Leads to recursion 
     return 1+myAge(currentyear-1) 

Io, io stesso, non vedo davvero il punto nell'usare la ricorsione nel tuo problema. Il mio suggerimento è innanzitutto quello di mettere un limite nel codice. Quello che ci hai dato verrà eseguito all'infinito, perché il programma si blocca in loop infinitamente annidati; non raggiunge mai una fine e inizia a tornare. Quindi puoi avere una variabile al di fuori della funzione che si aggiorna ogni volta che scendi di un livello e ad un certo punto interrompe la funzione dall'avvio di un nuovo ciclo for e inizia a restituire ciò che ha trovato.

Ma poi si sta entrando nel cambiamento delle variabili globali, si sta utilizzando la ricorsione in un modo strano e il codice diventa disordinato.

Ora leggendo i commenti e seeng quello che vuoi veramente, che, devo dire, non è chiaro, puoi usare l'aiuto di un algoritmo ricorsivo nel tuo codice, ma non scrivere tutto in modo ricorsivo.

def recursiveUrl(url,depth): 

    if depth == 5: 
     return url 
    else: 
     page=urllib2.urlopen(url) 
     soup = BeautifulSoup(page.read()) 
     newlink = soup.find('a') #find just the first one 
     if len(newlink) == 0: 
      return url 
     else: 
      return url, recursiveUrl(newlink,depth+1) 


def getLinks(url): 
    page=urllib2.urlopen(url) 
    soup = BeautifulSoup(page.read()) 
    links = soup.find_all('a', {'class':'institution'}) 
    for link in links: 
     links.append(recursiveUrl(link,0)) 
    return links 

Ora c'è ancora un problema con questo: i collegamenti non sono sempre legati a pagine web, ma anche per i file e le immagini. Ecco perché ho scritto l'istruzione if/else nella parte ricorsiva della funzione 'url-opening'. L'altro problema è che il tuo primo sito Web ha 2166 link istituzionali e la creazione di 2166 * 5 beautifulSoups non è veloce. Il codice precedente esegue una funzione ricorsiva 2166 volte. Questo non dovrebbe essere un problema, ma hai a che fare con file html (o php qualunque) di grandi dimensioni, quindi fare una zuppa di 2166 * 5 richiede un'enorme quantità di tempo.

4

il numero di strisciare pagina crescerà in modo esponenziale, ci sono molte questioni coinvolte che potrebbero non sembrare complicato a primo sguardo, controlla scrapy Panoramica dell'architettura per avere un'idea di come dovrebbe essere fatto nella vita reale

enter image description here

tra le altre caratteristiche grandi Scrapy non ripeterà strisciando stesse pagine (a meno che non si forzi a) e può essere configurato per la massima DEPTH_LIMIT

meglio ancora, Scrapy è dotato di un collegamento strumenti di estrazione link-extractors

+0

Mentre ti ho votato, trovo che la scrapy sia eccessivamente supponente e difficile nella pratica per progetti specifici. Se uno si prende il tempo di scrivere il proprio raschietto, allora può modificare ogni aspetto di esso e controllarlo dall'alto verso il basso. Inoltre, il tuo livello di conoscenza aumenta in modo esponenziale. – jamescampbell

Problemi correlati