Comment créer un robot d'exploration d'URL pour mapper un site Web à l'aide de Python

Un projet simple pour apprendre les bases du web scraping

Avant de commencer, assurons-nous de bien comprendre ce qu'est le web scraping:

Le scraping Web est le processus d'extraction de données de sites Web pour les présenter dans un format que les utilisateurs peuvent facilement comprendre.

Dans ce didacticiel, je souhaite montrer à quel point il est facile de créer un robot d'exploration d'URL simple en Python que vous pouvez utiliser pour mapper des sites Web. Bien que ce programme soit relativement simple, il peut fournir une excellente introduction aux principes de base du scraping Web et de l'automatisation. Nous nous concentrerons sur l'extraction récursive de liens à partir de pages Web, mais les mêmes idées peuvent être appliquées à une myriade d'autres solutions.

Notre programme fonctionnera comme ceci:

  1. Visitez une page Web
  2. Grattez toutes les URL uniques trouvées sur la page Web et ajoutez-les à une file d'attente
  3. Traitez récursivement les URL une par une jusqu'à épuisement de la file d'attente
  4. Imprimer les résultats

Tout d'abord

La première chose à faire est d'importer toutes les bibliothèques nécessaires. Nous utiliserons BeautifulSoup, les requêtes et urllib pour le scraping Web.

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

Ensuite, nous devons sélectionner une URL à partir de laquelle commencer l'exploration. Bien que vous puissiez choisir n'importe quelle page Web avec des liens HTML, je vous recommande d'utiliser ScrapeThisSite. C'est un bac à sable sûr que vous pouvez explorer sans avoir de problèmes.

url = “//scrapethissite.com”

Ensuite, nous allons devoir créer un nouvel objet deque afin que nous puissions facilement ajouter des liens nouvellement trouvés et les supprimer une fois que nous avons terminé de les traiter. Préremplissez le deque avec votre urlvariable:

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

Nous pouvons ensuite utiliser un ensemble pour stocker des URL uniques une fois qu'elles ont été traitées:

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

Nous voulons également garder une trace des URL locales (même domaine que la cible), étrangères (domaine différent de la cible) et des URL rompues:

# 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()

Temps d'exploration

Avec tout cela en place, nous pouvons maintenant commencer à écrire le code réel pour explorer le site Web.

Nous voulons regarder chaque URL dans la file d'attente, voir s'il y a des URL supplémentaires dans cette page et ajouter chacune à la fin de la file d'attente jusqu'à ce qu'il n'en reste plus. Dès que nous aurons fini de gratter une URL, nous la supprimerons de la file d'attente et l'ajouterons à l' processed_urlsensemble pour une utilisation ultérieure.

# 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)

Ensuite, ajoutez une exception pour attraper toutes les pages Web endommagées et les ajouter à l' broken_urlsensemble pour une utilisation ultérieure:

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

Nous devons ensuite obtenir l'URL de base de la page Web afin de pouvoir facilement différencier les adresses locales et étrangères:

# 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[:url.rfind(‘/’)+1] if ‘/’ in parts.path else url

Initialisez BeautifulSoup pour traiter le document HTML:

soup = BeautifulSoup(response.text, “lxml”)

Maintenant, récupérez la page Web pour tous les liens et triez-les en les ajoutant à leur ensemble correspondant:

for link in soup.find_all(‘a’): # extract link url from the anchor anchor = link.attrs[“href”] 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)

Puisque je souhaite limiter mon robot d'exploration aux adresses locales uniquement, j'ajoute ce qui suit pour ajouter de nouvelles URL à notre file d'attente:

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

Si vous souhaitez explorer toutes les URL, utilisez:

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

Avertissement: La façon dont le programme fonctionne actuellement, l'exploration d'URL étrangères prendra TRÈS longtemps. Vous pourriez avoir des ennuis pour le raclage de sites Web sans autorisation. À utiliser à vos risques et périls!

Voici tout mon code:

Et ça devrait être ça. Vous venez de créer un outil simple pour explorer un site Web et mapper toutes les URL trouvées!

En conclusion

N'hésitez pas à développer et à améliorer ce code. Par exemple, vous pouvez modifier le programme pour rechercher dans les pages Web des adresses e-mail ou des numéros de téléphone lorsque vous les explorez. Vous pouvez même étendre les fonctionnalités en ajoutant des arguments de ligne de commande pour fournir la possibilité de définir les fichiers de sortie, de limiter les recherches à la profondeur, et bien plus encore. Découvrez comment créer des interfaces de ligne de commande pour accepter des arguments ici.

Si vous avez des recommandations, des conseils ou des ressources supplémentaires, partagez-les dans les commentaires!

Merci d'avoir lu! Si vous avez aimé ce didacticiel et que vous voulez plus de contenu comme celui-ci, assurez-vous de casser le bouton suivant. ❤️

Assurez-vous également de consulter mon site Web, Twitter, LinkedIn et Github.