Cómo extraer datos de IMDB con Python

Comentarios: 0

En el mundo de hoy, la extracción de datos de plataformas sociales en línea como IMDB puede ser un camino eficaz hacia la recopilación de información muy necesaria relacionada con películas para fines de investigación o disfrute. En este tutorial, caminaremos a través de raspado de las 250 mejores películas en IMDB usando Python y extraer detalles como títulos de películas, resúmenes de películas, calificaciones, géneros y más.

Al raspar sitios web como IMDB, es crucial simular el comportamiento de un usuario real para minimizar el riesgo de detección y garantizar la recuperación exitosa de datos. He aquí algunas estrategias que se pueden emplear:

  1. Evitar el bloqueo de IP: Los sitios web suelen limitar el número de peticiones que se pueden realizar desde una misma dirección IP para evitar el scraping. Mediante el uso de proxies, puede repartir sus peticiones entre varias direcciones IP, reduciendo el riesgo de ser bloqueado.
  2. Asegure el anonimato: Los proxies enmascaran su dirección IP real, lo que no sólo ayuda a proteger su privacidad, sino que también hace que sea más difícil para los sitios web rastrear las actividades de raspado de vuelta a usted.
  3. Cumpla con los límites de velocidad: Distribuir las solicitudes a través de múltiples proxies puede ayudar a gestionar la frecuencia de tus consultas, manteniéndote dentro de los límites de velocidad del sitio web y reduciendo la probabilidad de activar medidas anti-scraping.
  4. Evite las sospechas del servidor: Incorporar cabeceras que imiten las de un navegador típico, como User-Agent, puede hacer que tus peticiones de scraping parezcan peticiones de usuario normales. Esto puede evitar que el servidor marque tus actividades como sospechosas.

Paso 1: Preparación del scraper

Para este tutorial, utilizaremos la biblioteca requests de Python para descargar el contenido web, lxml para analizar HTML y, opcionalmente, la biblioteca json para manejar datos formateados cuando sea necesario. Primero, instala las librerías necesarias.

Instalando las librerías

Antes de empezar, necesitas instalar las librerías Python necesarias. Ejecuta el siguiente comando en tu terminal para instalarlas:


pip install requests lxml

Estas librerías se utilizarán para realizar peticiones HTTP, analizar el contenido HTML y procesar los datos extraídos.

Configuración de las cabeceras de las peticiones HTTP

Para que nuestras peticiones se parezcan a las de un navegador web real, es crucial configurar las cabeceras HTTP adecuadamente. Aquí tienes un ejemplo de cómo podrías configurar estas cabeceras en tu script:


import requests

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 Do Not Track
    'pragma': 'no-cache',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    '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/129.0.0.0 Safari/537.36',
}

response = requests.get('https://www.imdb.com/chart/top/', headers=headers)

Cómo configurar proxies

Los proxies son útiles para el scraping a gran escala. Te ayudan a evitar ser bloqueado distribuyendo tus peticiones a través de múltiples IPs. A continuación te explicamos cómo puedes incluir un proxy:


proxies = {
    "http": "http://your_proxy_server",
    "https": "https://your_proxy_server"
}

response = requests.get('https://www.imdb.com/chart/top/', headers=headers, proxies=proxies)

Sustituye "tu_servidor_proxy" por los detalles reales del proxy a los que tienes acceso. Esto asegura que tu dirección IP no está expuesta, y ayuda a evitar ser bloqueado.

Paso 2: Analizar el contenido HTML

Después de obtener el contenido de la página web, necesitamos analizarlo para extraer los detalles de la película. Usaremos lxml para analizar el HTML y json para manejar los datos estructurados:


from lxml.html import fromstring
import json

# Analizar la respuesta HTML
parser = fromstring(response.text)

# Extraer los datos JSON-LD (datos estructurados) de la etiqueta script
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Ahora tenemos los datos de la película estructurados en formato JSON

Paso 3: Extraer los detalles de la película

La página Top 250 de IMDB incluye datos estructurados incrustados en el HTML, a los que se puede acceder fácilmente usando XPath y analizarlos como JSON. Extraeremos detalles de la película como nombre, descripción, calificaciones, géneros y más:


movies_details = json_data.get('itemListElement')

# Recorrer los datos de la película
movies_data = []
for movie in movies_details:
    movie_type = movie['item']['@type']
    url = movie['item']['url']
    name = movie['item']['name']
    description = movie['item']['description']
    image = movie['item']['image']
    bestRating = movie['item']['aggregateRating']['bestRating']
    worstRating = movie['item']['aggregateRating']['worstRating']
    ratingValue = movie['item']['aggregateRating']['ratingValue']
    ratingCount = movie['item']['aggregateRating']['ratingCount']
    contentRating = movie['item'].get('contentRating')
    genre = movie['item']['genre']
    duration = movie['item']['duration']
    
    # Añade los datos de cada película a la lista
    movies_data.append({
        'movie_type': movie_type,
        'url': url,
        'name': name,
        'description': description,
        'image': image,
        'bestRating': bestRating,
        'worstRating': worstRating,
        'ratingValue': ratingValue,
        'ratingCount': ratingCount,
        'contentRating': contentRating,
        'genre': genre,
        'duration': duration
    })

Paso 4: almacenar los datos

Una vez extraídos los datos, es importante almacenarlos en un formato fácil de analizar. En este caso, lo guardaremos en un archivo CSV utilizando la librería pandas:


import pandas as pd

# Convertir la lista de películas en un pandas DataFrame
df = pd.DataFrame(movies_data)

# Guardar los datos en un archivo CSV
df.to_csv('imdb_top_250_movies.csv', index=False)

print("IMDB Top 250 movies data saved to imdb_top_250_movies.csv")

Código completo

Aquí tienes el código completo para scrapear las 250 mejores películas de IMDB:


import requests
from lxml.html import fromstring
import json
import pandas as pd

# Definir las cabeceras de la solicitud
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',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    '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/129.0.0.0 Safari/537.36',
}

# Opcionalmente, configure proxies
proxies = {
    "http": "http://your_proxy_server",
    "https": "https://your_proxy_server"
}

# Enviar la solicitud a la página IMDB Top 250
response = requests.get('https://www.imdb.com/chart/top/', headers=headers, proxies=proxies)

# Analizar la respuesta HTML
parser = fromstring(response.text)

# Extraer los datos JSON-LD
raw_data = parser.xpath('//script[@type="application/ld+json"]/text()')[0]
json_data = json.loads(raw_data)

# Extraer detalles de la película
movies_details = json_data.get('itemListElement')

movies_data = []
for movie in movies_details:
    movie_type = movie['item']['@type']
    url = movie['item']['url']
    name = movie['item']['name']
    description = movie['item']['description']
    image = movie['item']['image']
    bestRating = movie['item']['aggregateRating']['bestRating']
    worstRating = movie['item']['aggregateRating']['worstRating']
    ratingValue = movie['item']['aggregateRating']['ratingValue']
    ratingCount = movie['item']['aggregateRating']['ratingCount']
    contentRating = movie['item'].get('contentRating')
    genre = movie['item']['genre']
    duration = movie['item']['duration']
    
    movies_data.append({
        'movie_type': movie_type,
        'url': url,
        'name': name,
        'description': description,
        'image': image,
        'bestRating': bestRating,
        'worstRating': worstRating,
        'ratingValue': ratingValue,
        'ratingCount': ratingCount,
        'contentRating': contentRating,
        'genre': genre,
        'duration': duration
    })

# Guardar los datos en un archivo CSV
df = pd.DataFrame(movies_data)
df.to_csv('imdb_top_250_movies.csv', index=False)
print("IMDB Top 250 movies data saved to imdb_top_250_movies.csv")

Consideraciones éticas

Antes de scrapear cualquier sitio web, es importante tener en cuenta cuestiones éticas y legales:

  • Respeta el Robots.txt: Comprueba el archivo robots.txt de IMDB para ver qué partes del sitio web están permitidas para el scraping. Respeta siempre las políticas del sitio web.
  • Evita sobrecargar el servidor: Raspe datos de manera responsable limitando la frecuencia de sus solicitudes para evitar poner una carga innecesaria en el servidor.
  • Respete las condiciones del servicio: Asegúrese de que el scraping no viola los términos de servicio de IMDB.

Ten siempre en cuenta las normas y utiliza el web scraping para fines legítimos.

Comentarios:

0 Comentarios