Cómo extraer datos financieros de Google con Python

Comentarios: 0

Los inversores y analistas de hoy en día utilizan la información de Google Finance ya que es actual y precisa. Google Finance parece ser el lugar preferido a la hora de tener datos financieros actuales de todo tipo, especialmente para acciones junto con índices y tendencias del mercado ya que da más detalles sobre las métricas financieras de las empresas. Python es el mejor lenguaje para el web scraping. Este post te ayudará a aprender cómo recopilar datos de Google Finance para que puedas tener todas las herramientas de análisis financiero necesarias.

Instalación de las librerías necesarias

Antes de empezar, asegúrate de que tienes Python instalado en tu sistema. También necesitarás las librerías: requests para realizar peticiones HTTP y lxml para analizar el contenido HTML de las páginas web. Para instalar las librerías necesarias, utiliza los siguientes comandos en la línea de comandos:

pip install requests
pip install lxml

A continuación, exploraremos el proceso paso a paso para extraer datos de Google Finance:

Paso 1: Comprender la estructura HTML

Para scrapear datos de Google Finance, necesitamos identificar los elementos HTML específicos que contienen la información que nos interesa:

  • Título: ubicado en //div[@class="zzDege"]/text()
  • Precio: en //div[@class="YMlKec fxKbKc"]/text()
  • Fecha: situado en //div[@class="ygUjEc"]/text()

Estas expresiones XPath nos servirán de guía para navegar y extraer los datos relevantes de la estructura HTML de las páginas de Google Finance.

Título:

1.png

Precio:

2.png

Fecha:

3.png

Paso 2: Configuración de la función de raspado

Al configurar un scraper, es crucial centrarse en varios aspectos importantes para garantizar una recopilación de datos eficiente y segura.

Hacer una petición HTTP

Para obtener contenido HTML del sitio web de Google Finance, emplearemos la biblioteca de peticiones. Este paso inicia el proceso cargando la página web de la que pretendemos extraer datos.

Importancia de utilizar cabeceras correctas en el scraping

Es realmente importante utilizar las cabeceras correctas a la hora de hacer web scraping, sobre todo la cabecera User-Agent. El uso de cabeceras es esencial para simular una petición genuina del navegador que evitará que el sitio identifique y detenga su script automático. Garantizan que el servidor responda correctamente proporcionando información relevante sobre la solicitud. Sin las cabeceras adecuadas, la solicitud podría ser denegada o el servidor podría devolver un contenido completamente diferente o entregar contenido en porciones que podrían restringir la actividad de web scraping. Por lo tanto, configurar las cabeceras adecuadamente ayuda a mantener el acceso al sitio web y garantiza que el scraper recupere los datos correctos.

import requests

# Defina las cabeceras para imitar la visita de un navegador y evitar que el servidor las bloquee
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',  # Cabecera de solicitud Do Not Track
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
    'sec-ch-ua-arch': '"x86"',
    'sec-ch-ua-bitness': '"64"',
    'sec-ch-ua-full-version-list': '"Not/A)Brand";v="8.0.0.0", "Chromium";v="126.0.6478.114", "Google Chrome";v="126.0.6478.114"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-model': '""',
    'sec-ch-ua-platform': '"Linux"',
    'sec-ch-ua-platform-version': '"6.5.0"',
    'sec-ch-ua-wow64': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
}

# Definir la URL de la página de Google Finance para BNP Paribas (ticker BNP) en la bolsa Euronext Paris (EPA)
url = "https://www.google.com/finance/quote/BNP:EPA?hl=en"

# Realiza la petición HTTP GET a la URL con las cabeceras especificadas
response = requests.get(url, headers=headers)

Importancia de utilizar proxies

Cuando se escanea Google Finance o cualquier otro sitio web a gran escala, es fundamental utilizar proxies. He aquí por qué:

  • Evitar bloqueos de IP: sitios web como Google Finance suelen bloquear o restringir el acceso desde direcciones IP que realizan demasiadas peticiones en un periodo corto. Los proxies ayudan a distribuir las solicitudes entre varias direcciones IP, lo que reduce las posibilidades de detección y bloqueo.
  • Mayor privacidad: el uso de proxies añade una capa de anonimato, protegiendo tu identidad y tus intenciones mientras rastreas datos.
# Definir la configuración del proxy
proxies = {
    'http': 'http://your_proxy_address:port',
    'https': 'https://your_proxy_address:port',
}

# Realiza la petición HTTP GET a la URL con las cabeceras y proxies especificados
response = requests.get(url, headers=headers, proxies=proxies)

Análisis de HTML con lxml

Una vez obtenido el contenido HTML, tenemos que analizarlo utilizando la biblioteca lxml. Esto nos permitirá navegar a través de la estructura HTML y extraer los datos que necesitamos.:

La función fromstring de lxml.html se importa para analizar el contenido HTML en un objeto Element. El método fromstring analiza response.text, el HTML sin procesar de la página web obtenida anteriormente, y devuelve un objeto Element almacenado en la variable parser, que representa la raíz del árbol HTML analizado.

from lxml.html import fromstring

# Analiza el contenido HTML de la respuesta utilizando el método fromstring de lxml
parser = fromstring(response.text)

Extracción de datos con XPath

Ahora, extraigamos datos específicos utilizando expresiones XPath del árbol HTML analizado:

El título recupera el título del instrumento financiero a partir del HTML analizado. El precio recupera el precio actual de la acción. La fecha recupera la fecha. El diccionario finance_data contiene el título, el precio y la fecha extraídos. Este diccionario se añade a una lista.

#Lista para almacenar los datos de salida
finance_data_list = []

# Extracción del título del instrumento financiero
title = parser.xpath('//div[@class="zzDege"]/text()')[0]

# Extracción del precio actual de la acción
price = parser.xpath('//div[@class="YMlKec fxKbKc"]/text()')[0]

# Extracción de la fecha
date = parser.xpath('//div[@class="ygUjEc"]/text()')[0]

# Creación de un diccionario para almacenar los datos extraídos
finance_data = {
    'title': title,
    'price': price,
    'date': date
}
# añadir datos a finance_data_list
finance_data_list.append(finance_data)

Tratamiento y almacenamiento de datos

Para manejar los datos obtenidos, puede que desee procesarlos o almacenarlos en un formato estructurado como JSON:

La variable output_file especifica el nombre del archivo JSON donde se guardarán los datos (finance_data.json). La variable open(fichero_salida, 'w') abre el fichero en modo de escritura, y json.dump(lista_datos_finanzas, f, sangría=4) escribe la lista_datos_finanzas en el fichero con una sangría de 4 espacios para facilitar la lectura.

# Guardar finance_data_list en un archivo JSON
output_file = 'finance_data.json'
with open(output_file, 'w') as f:
    json.dump(finance_data_list, f, indent=4)

Tratamiento de las excepciones a las solicitudes

Cuando se extraen datos de sitios web, es importante gestionar las excepciones en las solicitudes para garantizar la fiabilidad y solidez del script de extracción. Estas solicitudes pueden fallar por varias razones, como problemas de red, errores del servidor o tiempos de espera. La librería de peticiones en Python proporciona una forma efectiva de manejar este tipo de excepciones como se muestra a continuación:

try:
    # Envío de una solicitud GET a la URL
    response = requests.get(url)

    # Lanzar un HTTPError para respuestas erróneas (códigos de estado 4xx o 5xx)
    response.raise_for_status()

except requests.exceptions.HTTPError as e:
    # Gestión de errores HTTP (como 404, 500, etc.)
    print(f"HTTP error occurred: {e}")

except requests.exceptions.RequestException as e:
    # Gestionar cualquier otra excepción que pueda producirse durante la solicitud
    print(f"An error occurred: {e}")

El bloque try envuelve el código que puede lanzar excepciones. El bloque requests.get(url) envía una petición GET. El response.raise_for_status() comprueba el código de estado de la respuesta y lanza un HTTPError para los códigos fallidos. El except requests.exceptions.HTTPError as e: captura las excepciones HTTPError e imprime el mensaje de error. El except requests.exceptions.RequestException as e: atrapa otras excepciones (por ejemplo, errores de red, timeouts) e imprime el mensaje de error.

Código completo

Ahora, vamos a integrarlo todo para crear nuestra función scraper que obtiene, analiza y extrae datos de múltiples URLs de Google Finance:

import requests
from lxml.html import fromstring
import json
import urllib3
import ssl

ssl._create_default_https_context = ssl._create_stdlib_context
urllib3.disable_warnings()


# Lista de URL que se van a raspar
urls = [
    "https://www.google.com/finance/quote/BNP:EPA?hl=en",
    "https://www.google.com/finance/quote/SPY:NYSEARCA?hl=en",
    "https://www.google.com/finance/quote/SENSEX:INDEXBOM?hl=en"
]

# Definir cabeceras para imitar la visita de un navegador
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
    'sec-ch-ua-arch': '"x86"',
    'sec-ch-ua-bitness': '"64"',
    'sec-ch-ua-full-version-list': '"Not/A)Brand";v="8.0.0.0", "Chromium";v="126.0.6478.114", "Google Chrome";v="126.0.6478.114"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-model': '""',
    'sec-ch-ua-platform': '"Linux"',
    'sec-ch-ua-platform-version': '"6.5.0"',
    'sec-ch-ua-wow64': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
}

# Definir punto final proxy
proxies = {
    'http': 'http://your_proxy_address:port',
    'https': 'https://your_proxy_address:port',
}

# Lista para almacenar los datos raspados
finance_data_list = []

# Recorre cada URL y extrae los datos
for url in urls:
    try:
        # Envío de una solicitud GET a la URL
        response = requests.get(url, headers=headers, proxies=proxies, verify=False)
        
        # Lanzar un HTTPError para respuestas erróneas (códigos de estado 4xx o 5xx)
        response.raise_for_status()
        
        # Analiza el contenido HTML de la respuesta utilizando el método fromstring de lxml
        parser = fromstring(response.text)
        
        # Extracción del título, el precio y la fecha
        title = parser.xpath('//div[@class="zzDege"]/text()')[0]
        price = parser.xpath('//div[@class="YMlKec fxKbKc"]/text()')[0]
        date = parser.xpath('//div[@class="ygUjEc"]/text()')[0]
        
        # Almacenar los datos extraídos en un diccionario
        finance_data = {
            'title': title,
            'price': price,
            'date': date
        }
        
        # Añadir la nota del diccionario a la lista
        finance_data_list.append(finance_data)
    
    except requests.exceptions.HTTPError as e:
        # Gestión de errores HTTP (como 404, 500, etc.)
        print(f"HTTP error occurred for URL {url}: {e}")
    except requests.exceptions.RequestException as e:
        # Gestionar cualquier otra excepción que pueda producirse durante la solicitud
        print(f"An error occurred for URL {url}: {e}")

# Guardar finance_data_list en un archivo JSON
output_file = 'finance_data.json'
with open(output_file, 'w') as f:
    json.dump(finance_data_list, f, indent=4)

print(f"Scraped data saved to {output_file}")

Salida:

4.png

Esta guía ofrece un tutorial completo sobre el scraping de datos de Google Finance utilizando Python, junto con potentes bibliotecas como `lxml` y `requests`. Sienta las bases para crear herramientas sofisticadas de extracción de datos financieros, que pueden utilizarse para realizar análisis de mercado en profundidad, supervisar las actividades de la competencia o respaldar decisiones de inversión informadas.

Comentarios:

0 Comentarios