Dividiremos nuestro código en dos secciones: una para la extracción de datos y otra para la manipulación de datos. La primera parte la cubre el paquete Requests, mientras que la segunda parte la cubre BeautifulSoup. Sin más preámbulos, pasemos a la programación, comenzando por la parte de extracción:
import requests
def scrape( url = None ):
# if there is no URL, there is no need to use Python HTTP clients
# We will print a message and stop execution
if url == None:
print('[!] Please add a target!')
return
response = requests.get( url )
return response
En esta sección, definimos una función con un único parámetro: la URL de destino. Si no se proporciona la URL, mostraremos un mensaje y detendremos la ejecución. De lo contrario, utilizaremos el método get de Requests para obtener la respuesta. Ahora bien, sabemos que los clientes HTTP de Python admiten más métodos, así que añadamos un parámetro condicional:
import requests
def scrape( method = 'get', url = None, data = None ):
# if there is no URL, there is no need to use Python HTTP clients
# We will print a message and stop execution
if url == None:
print('[!] Please add a target!')
return
if method.lower() == 'get':
response = requests.get( url )
elif method.lower() == 'post':
if data == None:
print('[!] Please add a payload to your POST request!')
return
response = requests.post( url, data )
return response
Como puedes ver, hemos añadido un par de parámetros más a nuestra función. El parámetro `method` especifica qué método debe utilizarse para nuestra solicitud. El parámetro `data` representa la carga útil que enviamos con la solicitud POST. Por defecto, el método es GET, por lo que el parámetro `method` no es obligatorio.
Reto: Añade más métodos a esta función y amplía las capacidades de nuestro scraper. No solo es divertido, sino que también es una buena forma de aprender. Además, podrás personalizar el código para añadirlo a tu portfolio.
Hasta ahora hemos visto la extracción de datos. Analicemos el HTML y hagamos algo con él:
from bs4 import BeautifulSoup
def extract_elements(data = None, el = None):
if data == None:
print('[!] Please add some data!')
return
if el == None:
print('[!] Please specify which elements you are targeting!')
return
soup = BeautifulSoup(data.text, 'html.parser')
elements = soup.find_all(el)
return elements
Pero un rastreador web debería ser capaz de extraer datos más específicos. Por ejemplo, debería poder localizar y devolver elementos basándose en su selector CSS. Así que añadamos la lógica que se encarga de esta parte:
from bs4 import BeautifulSoup
def extract_elements(data = None, el = None, attr = None, attr_value = None):
if data == None:
print('[!] Please add some data!')
return
if el == None:
print('[!] Please specify which elements you are targeting!')
return
soup = BeautifulSoup(data.text, 'html.parser')
elements = soup.find_all(el, { attr : attr_value })
return elements
BeautifulSoup nos permite extraer datos específicos basándonos en sus atributos. Así que aquí hemos añadido dos nuevos parámetros que nos ayudarán a localizar y extraer elementos basándonos en sus atributos.
Ahora tenemos todo lo que necesitamos. Solo queda combinar las dos secciones y ya tendremos nuestro rastreador web. Una vez que hayas montado tu código, simplemente:
- Crea una nueva variable que contenga los datos extraídos con Requests
- Imprime los elementos devueltos por BeautifulSoup
Aquí están las dos piezas que le faltaban a su código:
data = scrape('GET', 'https://webscrapingapi.com')
print( extract_elements(data, 'ul') )
Estoy seguro de que ya has averiguado para qué sirve todo y que, a estas alturas, no hace falta ninguna explicación. Al igual que con nuestro scraper, te reto a que experimentes con la función `extract_elements` y consigas que haga algo más que simplemente devolver elementos.