Cómo construir un rastreador de URL para mapear un sitio web usando Python

Un proyecto simple para aprender los fundamentos del web scraping

Antes de comenzar, asegurémonos de comprender qué es el web scraping:

El web scraping es el proceso de extraer datos de sitios web para presentarlos en un formato que los usuarios puedan entender fácilmente.

En este tutorial, quiero demostrar lo fácil que es crear un rastreador de URL simple en Python que puede usar para mapear sitios web. Si bien este programa es relativamente simple, puede proporcionar una excelente introducción a los fundamentos del web scraping y la automatización. Nos centraremos en la extracción recursiva de enlaces de páginas web, pero las mismas ideas se pueden aplicar a una gran cantidad de otras soluciones.

Nuestro programa funcionará así:

  1. Visite una página web
  2. Raspe todas las URL únicas que se encuentran en la página web y agréguelas a una cola
  3. Procese de forma recursiva las URL una por una hasta que agotemos la cola
  4. Imprimir resultados

Lo primero es lo primero

Lo primero que debemos hacer es importar todas las bibliotecas necesarias. Usaremos BeautifulSoup, solicitudes y urllib para web scraping.

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

A continuación, debemos seleccionar una URL desde la que comenzar a rastrear. Si bien puede elegir cualquier página web con enlaces HTML, le recomiendo usar ScrapeThisSite. Es una caja de arena segura que puedes rastrear sin meterte en problemas.

url = “//scrapethissite.com”

A continuación, necesitaremos crear un nuevo objeto deque para que podamos agregar fácilmente los enlaces recién encontrados y eliminarlos una vez que hayamos terminado de procesarlos. Complete previamente el deque con su urlvariable:

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

Luego, podemos usar un conjunto para almacenar URL únicas una vez que se hayan procesado:

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

También queremos realizar un seguimiento de las URL locales (el mismo dominio que el objetivo), extranjeras (un dominio diferente al objetivo) y las URL rotas:

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

Hora de gatear

Con todo eso en su lugar, ahora podemos comenzar a escribir el código real para rastrear el sitio web.

Queremos mirar cada URL en la cola, ver si hay alguna URL adicional dentro de esa página y agregar cada una al final de la cola hasta que no quede ninguna. Tan pronto como terminemos de raspar una URL, la eliminaremos de la cola y la agregaremos al processed_urlsconjunto para su uso posterior.

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

A continuación, agregue una excepción para detectar cualquier página web rota y agréguela al broken_urlsconjunto para su uso posterior:

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

Luego, necesitamos obtener la URL base de la página web para que podamos diferenciar fácilmente las direcciones locales y extranjeras:

# 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

Inicialice BeautifulSoup para procesar el documento HTML:

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

Ahora raspe la página web para todos los enlaces y ordene agregarlos a su conjunto correspondiente:

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)

Como quiero limitar mi rastreador solo a direcciones locales, agrego lo siguiente para agregar nuevas URL a nuestra cola:

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

Si desea rastrear todas las URL, utilice:

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

Advertencia: la forma en que funciona el programa actualmente, rastrear URL extranjeras llevará MUCHO tiempo. Es posible que se meta en problemas por raspar sitios web sin permiso. ¡Úselo bajo su propio riesgo!

Aquí está todo mi código:

Y eso debería ser todo. ¡Acaba de crear una herramienta sencilla para rastrear un sitio web y asignar todas las URL encontradas!

En conclusión

Siéntase libre de desarrollar y mejorar este código. Por ejemplo, puede modificar el programa para buscar direcciones de correo electrónico o números de teléfono en páginas web mientras las rastrea. Incluso podría ampliar la funcionalidad agregando argumentos de línea de comando para brindar la opción de definir archivos de salida, limitar las búsquedas a profundidad y mucho más. Obtenga información sobre cómo crear interfaces de línea de comandos para aceptar argumentos aquí.

Si tiene recomendaciones, consejos o recursos adicionales, ¡comparta los comentarios!

¡Gracias por leer! Si te gustó este tutorial y quieres más contenido como este, asegúrate de aplastar ese botón de seguimiento. ❤️

También asegúrese de visitar mi sitio web, Twitter, LinkedIn y Github.