¿Cómo raspar varias páginas de un sitio web usando Python?

Web Scraping es un método para extraer datos útiles de un sitio web utilizando programas informáticos sin tener que hacerlo manualmente. Estos datos se pueden exportar y organizar categóricamente para varios propósitos. Algunos lugares comunes donde Web Scraping encuentra su uso son sitios web de investigación y análisis de mercado, herramientas de comparación de precios, motores de búsqueda, recopilación de datos para proyectos de IA/ML, etc.

Profundicemos y raspamos un sitio web. En este artículo, tomaremos el sitio web GeeksforGeeks y extraeremos los títulos de todos los artículos disponibles en la página de inicio utilizando un script de Python. 

Si nota, hay miles de artículos en el sitio web y para extraerlos todos, tendremos que raspar todas las páginas para no perdernos ninguno. 

Página de inicio de GeeksforGeeks

Raspar varias páginas de un sitio web usando Python

Ahora, pueden surgir varios casos en los que es posible que desee obtener datos de varias páginas del mismo sitio web o también de varias URL diferentes, y escribir código manualmente para cada página web es una tarea tediosa y que requiere mucho tiempo. Además, define todos los principios básicos de la automatización. ¡Eh!  

Para resolver este problema exacto, veremos dos técnicas principales que nos ayudarán a extraer datos de múltiples páginas web:

  • el mismo sitio web
  • Diferente URL del sitio web

Acercarse:

El enfoque del programa será bastante simple y será más fácil de entender en un formato de PUNTO:

  • Importaremos todas las bibliotecas necesarias .
  • Configure nuestras strings de URL para establecer una conexión mediante la biblioteca de requests .
  • Analizar los datos disponibles de la página de destino utilizando el analizador de la biblioteca BeautifulSoup .
  • Desde la página de destino, identifique y extraiga las clases y etiquetas que contienen la información que es valiosa para nosotros.
  • Prototípelo para una página usando un bucle y luego aplíquelo a todas las páginas.

Ejemplo 1: recorrer los números de página 

números de página en la parte inferior del sitio web GeeksforGeeks

La mayoría de los sitios web tienen páginas etiquetadas del 1 al N. Esto hace que sea realmente sencillo para nosotros recorrer estas páginas y extraer datos de ellas, ya que estas páginas tienen estructuras similares. Por ejemplo:

observe la última sección de la URL – página/4/

Aquí, podemos ver los detalles de la página al final de la URL. Con esta información, podemos crear fácilmente un ciclo for iterando en tantas páginas como queramos (colocando page/(i)/ en la string de URL e iterando “ ihasta N ) y extrayendo todos los datos útiles de ellas. El siguiente código le dará más claridad sobre cómo raspar datos usando un For Loop en Python.

Python

import requests
from bs4 import BeautifulSoup as bs
  
URL = 'https://www.geeksforgeeks.org/page/1/'
  
req = requests.get(URL)
soup = bs(req.text, 'html.parser')
  
titles = soup.find_all('div',attrs = {'class','head'})
  
print(titles[4].text)

Producción:

Salida para el código anterior

Ahora, usando el código anterior, podemos obtener los títulos de todos los artículos simplemente intercalando esas líneas con un bucle.

Python

import requests
from bs4 import BeautifulSoup as bs
  
URL = 'https://www.geeksforgeeks.org/page/'
  
for page in range(1,10):
      # pls note that the total number of
    # pages in the website is more than 5000 so i'm only taking the
    # first 10 as this is just an example
  
    req = requests.get(URL + str(page) + '/')
    soup = bs(req.text, 'html.parser')
  
    titles = soup.find_all('div',attrs={'class','head'})
  
    for i in range(4,19):
        if page>1:
            print(f"{(i-3)+page*15}" + titles[i].text)
        else:
            print(f"{i-3}" + titles[i].text)

Producción:

Salida para el código anterior

Nota: el código anterior obtendrá las primeras 10 páginas del sitio web y eliminará los 150 títulos de los artículos que se encuentran en esas páginas. 

Ejemplo 2: recorrer una lista de diferentes URL.

La técnica anterior es absolutamente maravillosa, pero ¿qué sucede si necesita raspar diferentes páginas y no sabe sus números de página? Tendrá que raspar esas diferentes URL una por una y codificar manualmente un script para cada una de esas páginas web.

En su lugar, podría simplemente hacer una lista de estas URL y recorrerlas. Simplemente iterando los elementos de la lista, es decir, las URL, podremos extraer los títulos de esas páginas sin tener que escribir código para cada página. Aquí hay un código de ejemplo de cómo puedes hacerlo.

Python

import requests
from bs4 import BeautifulSoup as bs
URL = ['https://www.geeksforgeeks.org','https://www.geeksforgeeks.org/page/10/']
  
for url in range(0,2):
    req = requests.get(URL[url])
    soup = bs(req.text, 'html.parser')
  
    titles = soup.find_all('div',attrs={'class','head'})
    for i in range(4, 19):
        if url+1  > 1:
            print(f"{(i - 3) + url * 15}" + titles[i].text)
        else:
            print(f"{i - 3}" + titles[i].text)

Producción:

Salida para el código anterior

¿Cómo evitar que se prohíba tu dirección IP?

Controlar la velocidad de rastreo es lo más importante a tener en cuenta cuando se realiza una extracción muy grande. Bombardear el servidor con múltiples requests en un período de tiempo muy corto probablemente resultará en que su dirección IP sea incluida en la lista negra. Para evitar esto, podemos simplemente llevar a cabo nuestro rastreo en breves ráfagas aleatorias de tiempo. En otras palabras, agregamos pausas o pequeños descansos entre los períodos de rastreo, lo que nos ayuda a parecer humanos reales, ya que los sitios web pueden identificar fácilmente a un rastreador debido a la velocidad que posee en comparación con un humano que intenta visitar el sitio web. Esto ayuda a evitar el tráfico innecesario y la sobrecarga de los servidores del sitio web. Ganar-ganar!

Ahora, ¿cómo controlamos la tasa de rastreo? Es simple. Mediante el uso de dos funciones, randint() y sleep() de los módulos de python ‘random’ y ‘time’ respectivamente. 

Python3

from random import randint
from time import sleep 
  
print(randint(1,10))
Producción

1

La función randint() elegirá un número entero aleatorio entre los límites superior e inferior dados, en este caso, 10 y 1 respectivamente, para cada iteración del bucle. El uso de la función randint() en combinación con la función sleep() ayudará a agregar pausas breves y aleatorias en la velocidad de rastreo del programa. La función sleep() básicamente detendrá la ejecución del programa durante la cantidad de segundos dada. Aquí, la cantidad de segundos se ingresará aleatoriamente en la función de suspensión mediante el uso de la función randint() . Utilice el código que se proporciona a continuación como referencia.

Python3

from time import *
from random import randint
  
for i in range(0,3):
  # selects random integer in given range
  x = randint(2,5)
  print(x)
  sleep(x)
  print(f'I waited {x} seconds')
Producción

5
I waited 5 seconds
4
I waited 4 seconds
5
I waited 5 seconds

Para tener una idea clara de esta función en acción, consulte el código que figura a continuación.

Python3

import requests
from bs4 import BeautifulSoup as bs
from random import randint
from time import sleep
  
URL = 'https://www.geeksforgeeks.org/page/'
  
for page in range(1,10): 
      # pls note that the total number of
    # pages in the website is more than 5000 so i'm only taking the
    # first 10 as this is just an example
  
    req = requests.get(URL + str(page) + '/')
    soup = bs(req.text, 'html.parser')
  
    titles = soup.find_all('div',attrs={'class','head'})
  
    for i in range(4,19):
        if page>1:
            print(f"{(i-3)+page*15}" + titles[i].text)
        else:
            print(f"{i-3}" + titles[i].text)
  
    sleep(randint(2,10))

Producción:

El programa ha pausado su ejecución y está esperando para reanudar

La salida del código anterior

Publicación traducida automáticamente

Artículo escrito por jaygala260 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *