Introduction to my first MMORTS - learn more

Web scraping con Python, tutorial e introduccion usando Beautiful Soup

En este post aprenderemos como poder scrapear una página web para extraer y formatear de ella la información que necesitemos utilizando  Beautiful Soup. Antes de todo necesitaremos crear nuestro entorno de trabajo, puedes usar un procesador de textos tradicional o un IDE. En mi caso emplearé PyCharm con la que depuraré (debug) el programa para encontrar fallos y como se comporta en cada paso.

 

Instalación de paquetes

Vamos a instalar request y bs4 de BeautifulSoup para procesarlo para hacer peticiones y obtener los datos que necesitamos respectivamente. Necesitaremos un interpretador (parser), yo haré empleo de lxml, pero podéis emplear html.parser y ahorraros instalar un paquete extra.

$ pip install requests 
$ pip install bs4 
$ pip install lxml

 

Programación de la aplicación

Una vez instalados comenzaremos a programar nuestra aplicación en la que importaremos los paquetes anteriormente instalados.

import requests from bs4 
import BeautifulSoup 
import lxml

 

En mi caso quiero obtener todos los títulos de las entradas que tengo en mi página web, con lo que tendré que ir por todas las páginas de entradas hasta que no haya más, esto lo haremos con un bucle examinando si es ya la última página y no existen más.

Inicializaremos una lista vacía y una variable en la que almacenaremos el número de entradas del anterior ciclo del bucle, comparando este con el número de entradas con la nueva página, si este es el mismo asimilaremos que ya no existen más entradas. Tendremos otra variable con valor de 1, que es la página actual.

postList = [] 
oldSize = 0 
page = 1

 

Ahora toca empezar a diseñar nuestro bucle, en mi caso utilizo un while, pero igualmente puedes hacer un for o de la forma que necesites en tu entorno. Haremos una consulta GET apuntando a la URL que queremos emplear. Inicializaremos BeautifulSoup y el interpretador que hayamos escogido.

while 1: 
    request = requests.get("https://danielbeltejar.es/page/" + str(page)) 
    # print(request.text) #HTML soup = BeautifulSoup(request.text, 'lxml')

 

Ahora haremos la búsqueda de los títulos en el código HTML, en nuestro navegador abrimos las DevTools o vemos el código fuente de la página. Y buscamos el texto que deseemos.

En este caso quiero extraer el texto de la clase h2 que tiene definido «entry-title default-max-width». Sabiendo esto voy a hacer la búsqueda filtrando lo que no sea lo anterior dicho.

posts = soup.find_all(“h2”, {“class”: “entry-title default-max-width”})

A continuación interactuáremos con todas las líneas halladas y sacaremos el texto en mi caso, aunque igualmente dejo el ejemplo para extraer la URL del href.

# print(post) #Obtener linea HTML
# print(post.a.get('href')) #Obtener URL post
print(post.a.get_text()) #Obtener nombre post

 

Añadiremos el texto a nuestra lista anteriormente inicializada.

postList.insert(len(postList), post.a.get_text())

 

Ya fuera del segundo bucle compararemos el tamaño de la lista en el anterior ciclo del primer bucle con el ciclo de segundo bucle en el que formateamos el texto. Si este es idéntico, significa que ya no hay más páginas para analizar con lo que salimos del programa con un break. Si de lo contrario es distinto, aumentamos la variable de página en 1 y el bucle ejecutará otra consulta GET a la nueva URL con el nuevo número de página, ejecutándose hasta la anterior condición definida.

if oldSize == (oldSize + len(posts)):
    break oldSize = oldSize+len(posts) 
    page = page+1

 

import requests
from bs4 import BeautifulSoup
import lxml

postList = []
oldSize = 0
page = 1

while 1:
    request = requests.get("https://danielbeltejar.es/page/" + str(page))
    # print(request.text) #HTML
    soup = BeautifulSoup(request.text, 'lxml')
    
    posts = soup.find_all("h2", {"class": "entry-title default-max-width"})
    for post in posts:
        # print(post) #Obtener linea HTML
        # print(post.a.get('href')) #Obtener URL post
        print(post.a.get_text()) #Obtener nombre post
        postList.insert(len(postList), post.a.get_text())
    if oldSize == (oldSize + len(posts)):
        break
    oldSize = oldSize+len(posts)
    page = page+1

El código quedaría tal que así, puedes quitar los comentarios que he agregado por si no estás en una IDE o no cuentas con una opción para depurar tu código just in time por pasos.