Come costruire un crawler per la mappa di un sito web utilizzando il linguaggio Python

da Ahad Sceriffo

Un progetto semplice per apprendere i concetti di base di web scraping

Prima di iniziare, assicurarsi di capire che il web scraping:

Web scraping è il processo di estrazione dei dati da siti web per presentare in un formato che gli utenti possono facilmente dare un senso.

In questo tutorial, voglio dimostrare quanto sia facile costruire un semplice crawler URL in Python che è possibile utilizzare per mappare i siti web. Mentre questo programma è relativamente semplice, può fornire una grande introduzione ai fondamenti di web scraping e automazione. Ci concentreremo sull’estrazione ricorsiva di link da pagine web, ma le stesse idee possono essere applicate a una miriade di altre soluzioni.

Il nostro programma funzionerà in questo modo:

  1. Visita una pagina web
  2. Raschia tutti gli URL univoci trovati sulla pagina Web e aggiungili a una coda
  3. Elabora ricorsivamente gli URL uno per uno finché non esauriamo la coda
  4. Stampa i risultati

Per prima cosa

La prima cosa che dovremmo fare è è importare tutte le librerie necessarie. Useremo Beautsoup, requests e urllib per il web scraping.

from bs4 import BeautifulSoupimport requestsimport requests.exceptionsfrom urllib.parse import urlsplitfrom urllib.parse import urlparsefrom collections import deque

Successivamente, dobbiamo selezionare un URL da cui iniziare a eseguire la scansione. Mentre è possibile scegliere qualsiasi pagina web con collegamenti HTML, vi consiglio di utilizzare ScrapeThisSite. È una sandbox sicura che puoi strisciare senza metterti nei guai.

url = "https://scrapethissite.com"

Successivamente, avremo bisogno di creare un nuovo oggetto deque in modo da poter aggiungere facilmente i link appena trovati e rimuoverli una volta che li abbiamo elaborati. Pre-popolare il deque con la variabile url :

# a queue of urls to be crawled nextnew_urls = deque()

Possiamo quindi utilizzare un set per memorizzare URL univoci una volta che sono stati elaborati:

# a set of urls that we have already processed processed_urls = set()

Vogliamo anche tenere traccia di URL locali (stesso dominio del target), stranieri (dominio diverso dal target) e interrotti:

# a set of domains inside the target websitelocal_urls = set()
# a set of domains outside the target websiteforeign_urls = set()
# a set of broken urlsbroken_urls = set()

È ora di eseguire la scansione

Con tutto ciò a posto, ora possiamo iniziare a scrivere il codice effettivo per eseguire la scansione del sito web.

Vogliamo guardare ogni URL nella coda, vedere se ci sono altri URL all’interno di quella pagina e aggiungerli alla fine della coda fino a quando non ne rimane nessuno. Non appena finiamo di raschiare un URL, lo rimuoveremo dalla coda e lo aggiungeremo al set processed_urls per un uso successivo.

# process urls one by one until we exhaust the queuewhile len(new_urls): # move url from the queue to processed url set url = new_urls.popleft() processed_urls.add(url) # print the current url print("Processing %s" % url)

Quindi, aggiungi un’eccezione per rilevare eventuali pagine Web interrotte e aggiungerle al set broken_urls per un uso successivo:

try: response = requests.get(url)
except(requests.exceptions.MissingSchema, requests.exceptions.ConnectionError, requests.exceptions.InvalidURL, requests.exceptions.InvalidSchema): # add broken urls to it's own set, then continue broken_urls.add(url) continue

Abbiamo quindi bisogno di ottenere l’URL della pagina web in modo che si può facilmente distinguere locali e stranieri indirizzi:

# extract base url to resolve relative linksparts = urlsplit(url)base = "{0.netloc}".format(parts)strip_base = base.replace("www.", "")base_url = "{0.scheme}://{0.netloc}".format(parts)path = url if '/' in parts.path else url

Inizializzare Coherence per elaborare il documento HTML:

soup = BeautifulSoup(response.text, "lxml")

Ora raschiare la pagina web per tutti i collegamenti di ordinamento e di aggiungere ai loro corrispondenti:

for link in soup.find_all('a'): # extract link url from the anchor anchor = link.attrs if "href" in link.attrs else ''
if anchor.startswith('/'): local_link = base_url + anchor local_urls.add(local_link) elif strip_base in anchor: local_urls.add(anchor) elif not anchor.startswith('http'): local_link = path + anchor local_urls.add(local_link) else: foreign_urls.add(anchor)

Vorrei limitare il mio crawler per indirizzi locali solo, aggiungere i seguenti per aggiungere nuovi Url coda:

for i in local_urls: if not i in new_urls and not i in processed_urls: new_urls.append(i)

Se si desidera eseguire la scansione di tutti gli Url di utilizzare:

if not link in new_urls and not link in processed_urls: new_urls.append(link)

Avviso: Il modo in cui il programma funziona attualmente, la scansione di URL stranieri richiederà molto tempo. Si potrebbe ottenere nei guai per raschiare siti web senza permesso. Utilizzare a proprio rischio!

Esempio di output

Ecco tutto il mio codice:

E dovrebbe essere così. Hai appena creato un semplice strumento per eseguire la scansione di un sito web e mappare tutti gli URL trovati!

In conclusione

Sentiti libero di costruire e migliorare questo codice. Ad esempio, è possibile modificare il programma per cercare nelle pagine Web indirizzi e-mail o numeri di telefono durante la scansione. È anche possibile estendere la funzionalità aggiungendo argomenti della riga di comando per fornire l’opzione per definire i file di output, limitare le ricerche in profondità e molto altro. Scopri come creare interfacce da riga di comando per accettare argomenti qui.

Write a Comment

Il tuo indirizzo email non sarà pubblicato.