Cómo scrapear datos de Instagram usando Python

Comentarios: 0

Obtener acceso a los datos de Instagram puede ser complicado debido a diversos mecanismos anti-bot, requisitos de inicio de sesión y límites de velocidad. Sin embargo, puedes extraer información útil de perfiles públicos con las herramientas y técnicas adecuadas. Este artículo te guiará sobre cómo scrapear datos de usuarios de Instagram usando Python haciendo peticiones API al backend de Instagram, extrayendo información de los datos JSON devueltos y guardándola en un archivo JSON.

Configuración de las bibliotecas necesarias

Antes de adentrarnos en el código, asegúrate de tener instaladas las librerías de Python necesarias.


pip install requests python-box

  • solicitudes: Para realizar peticiones HTTP.
  • python-box: Simplifica el acceso a los datos convirtiendo los diccionarios en objetos que permiten el acceso con notación de puntos.

Vamos a dividir el código en diferentes secciones para una mejor comprensión, incluyendo el envío de la petición, la obtención y el análisis sintáctico de los datos, el uso de proxies para evitar ser detectados y la simplificación del análisis sintáctico de JSON con la librería Box.

Paso 1. Hacer la petición a la API

El frontend de Instagram está fuertemente protegido, pero el backend ofrece puntos finales de la API que se pueden utilizar sin autenticación. Usaremos uno de estos puntos en adelante.

Esta API proporciona información detallada sobre el perfil de un usuario, incluyendo su descripción, número de seguidores y publicaciones. Vamos a explorar cómo solicitar datos utilizando la biblioteca requests en Python.

Explicación:

  1. Cabeceras: Instagram bloquea la mayoría de las peticiones de bots analizando las cabeceras de las peticiones. El x-ig-app-id es esencial porque imita una petición procedente de la propia app de Instagram.
  2. La cadena User-Agent representa el navegador que realiza la solicitud, engañando a Instagram para que crea que se trata de un usuario real.
  3. Solicitud de API de backend: La URL https://i.instagram.com/api/v1/users/web_profile_info/?username={username} forma parte de la API backend de Instagram. Proporciona información detallada sobre un perfil público.
  4. Manejo de la respuesta JSON: Utilizamos response.json() para convertir la respuesta de la API en un objeto JSON que podemos analizar fácilmente y extraer información de él.

import requests

# Define las cabeceras para imitar una petición real del navegador
headers = {
    "x-ig-app-id": "936619743392459",  # ID de la aplicación de Instagram para autenticar la solicitud
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept": "*/*",
}

# Sustitúyalo por el nombre de usuario que desea raspar
username = 'testtest'

# Enviar una solicitud API para obtener los datos del perfil
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers)
response_json = response.json()  # Parsear la respuesta en un objeto JSON

Paso 2. Manejar proxies para saltarse la limitación de velocidad

Dado que Instagram restringe las solicitudes repetidas desde la misma dirección IP, si necesitas comprar proxy para el scraping a gran escala, es importante elegir direcciones estables y de buena calidad. Un proxy enruta tus peticiones a través de diferentes direcciones IP, y si necesitas comprar proxy España para una ubicación concreta, también puede ayudarte a trabajar con un contexto regional específico.

Para configurar un servidor proxy, necesitarás la dirección IP, el número de puerto y, si es necesario, un nombre de usuario y una contraseña para la autenticación.


proxies = {
    'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
    'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}

response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers, proxies=proxies)

Paso 3. Simplificando el análisis sintáctico de JSON con Box

La API de Instagram devuelve una compleja estructura JSON anidada, que puede ser difícil de navegar utilizando el acceso tradicional basado en diccionarios. Para facilitar el parseo, podemos usar la librería Box, que permite acceder a datos JSON usando notación de puntos en lugar de claves de diccionario.

Explicación:

  1. Box: Esta librería convierte un diccionario JSON en un objeto, permitiéndonos acceder a campos profundamente anidados usando la notación de puntos. Por ejemplo, en lugar de escribir response_json['data']['user']['full_name'], podemos escribir simplemente response_json.data.user.full_name.
  2. Extracción de datos: Extraemos información útil del perfil como el nombre completo del usuario, su ID, biografía, si es una cuenta de empresa o profesional, estado de verificación y número de seguidores.

from box import Box

response_json = Box(response.json())

# Extraer los datos del perfil del usuario
user_data = {
    'full name': response_json.data.user.full_name,
    'id': response_json.data.user.id,
    'biography': response_json.data.user.biography,
    'business account': response_json.data.user.is_business_account,
    'professional account': response_json.data.user.is_professional_account,
    'category name': response_json.data.user.category_name,
    'is verified': response_json.data.user.is_verified,
    'profile pic url': response_json.data.user.profile_pic_url_hd,
    'followers': response_json.data.user.edge_followed_by.count,
    'following': response_json.data.user.edge_follow.count,
}

Paso 4. Extracción de datos de vídeo y línea de tiempo

Una vez extraídos los datos del perfil, también podemos scrapear los datos de la línea de tiempo de vídeo del usuario y las publicaciones habituales.

Explicación:

  1. Datos de vídeo: Esta sección extrae datos sobre los vídeos de Instagram del usuario, incluida la URL del vídeo, el recuento de visualizaciones, el recuento de comentarios y la duración del vídeo.
  2. Timeline Media: Del mismo modo, esta sección extrae datos de la línea de tiempo del usuario, capturando la URL multimedia de la publicación, los me gusta y los comentarios.

# Extraer datos de vídeo
profile_video_data = []
for element in response_json.data.user.edge_felix_video_timeline.edges:
    video_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'video url': element.node.video_url,
        'view count': element.node.video_view_count,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
        'duration': element.node.video_duration,
    }
    profile_video_data.append(video_data)

# Extraer datos multimedia de la línea de tiempo (fotos y vídeos)
profile_timeline_media_data = []
for element in response_json.data.user.edge_owner_to_timeline_media.edges:
    media_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'media url': element.node.display_url,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
    }
    profile_timeline_media_data.append(media_data)

Paso 5. Guardar los datos en archivos JSON

Una vez extraídos todos los datos, el siguiente paso es guardarlos en un archivo JSON para su posterior análisis o almacenamiento. Utilizamos el módulo json de Python para escribir los datos extraídos en archivos JSON. Cada archivo tendrá un formato ordenado, gracias al parámetro indent=4, que facilita la lectura y el procesamiento de los datos.


import json

# Guardar los datos del usuario en un archivo JSON
with open(f'{username}_profile_data.json', 'w') as file:
    json.dump(user_data, file, indent=4)

# Guardar datos de vídeo en un archivo JSON
with open(f'{username}_video_data.json', 'w') as file:
    json.dump(profile_video_data, file, indent=4)

# Guardar los datos multimedia de la línea de tiempo en un archivo JSON
with open(f'{username}_timeline_media_data.json', 'w') as file:
    json.dump(profile_timeline_media_data, file, indent=4)

Código completo

Aquí está el script Python completo que combina todas las secciones discutidas anteriormente. Este código scrapea los datos de perfil de usuario, los datos de vídeo y los datos multimedia de la línea de tiempo de Instagram, gestiona las cabeceras y proxies necesarios y guarda la información extraída en archivos JSON.


import requests
from box import Box
import json

# Encabezados para imitar una solicitud real del navegador a la API de Instagram
headers = {
    "x-ig-app-id": "936619743392459", 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept": "*/*",
}

# Establecer un proxy para evitar la limitación de velocidad y la detección (opcional)
proxies = {
    'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
    'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}

# El nombre de usuario de Instagram a raspar
username = 'testtest'

# Enviar una solicitud a la API de Instagram para obtener los datos del perfil
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', 
                        headers=headers, proxies=proxies)
response_json = Box(response.json())  # Convertir la respuesta en un objeto Box para facilitar la navegación

# Extraer datos del perfil del usuario
user_data = {
    'full name': response_json.data.user.full_name,
    'id': response_json.data.user.id,
    'biography': response_json.data.user.biography,
    'business account': response_json.data.user.is_business_account,
    'professional account': response_json.data.user.is_professional_account,
    'category name': response_json.data.user.category_name,
    'is verified': response_json.data.user.is_verified,
    'profile pic url': response_json.data.user.profile_pic_url_hd,
    'followers': response_json.data.user.edge_followed_by.count,
    'following': response_json.data.user.edge_follow.count,
}

# Extraer datos de vídeo de la línea de tiempo de vídeo del usuario
profile_video_data = []
for element in response_json.data.user.edge_felix_video_timeline.edges:
    video_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'video url': element.node.video_url,
        'view count': element.node.video_view_count,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
        'duration': element.node.video_duration,
    }
    profile_video_data.append(video_data)

# Extraer datos multimedia de la línea de tiempo (fotos y vídeos)
profile_timeline_media_data = []
for element in response_json.data.user.edge_owner_to_timeline_media.edges:
    media_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'media url': element.node.display_url,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
    }
    profile_timeline_media_data.append(media_data)

# Guardar los datos del perfil del usuario en un archivo JSON
with open(f'{username}_profile_data.json', 'w') as file:
    json.dump(user_data, file, indent=4)
print(f'saved json: {username}_profile_data.json')

# Guardar datos de vídeo en un archivo JSON
with open(f'{username}_video_data.json', 'w') as file:
    json.dump(profile_video_data, file, indent=4)
print(f'saved json: {username}_video_data.json')

# Guardar los datos multimedia de la línea de tiempo en un archivo JSON
with open(f'{username}_timeline_media_data.json', 'w') as file:
    json.dump(profile_timeline_media_data, file, indent=4)
print(f'saved json: {username}_timeline_media_data.json')

El scraping de datos de Instagram con Python se puede hacer aprovechando la API backend proporcionada por Instagram, que ayuda a eludir algunas de las restricciones front-end. Utilizar las cabeceras adecuadas para imitar el comportamiento del navegador y emplear proxies residenciales para evitar la limitación de velocidad son pasos críticos. La biblioteca Box simplifica aún más el proceso haciendo que el análisis sintáctico de JSON sea más intuitivo gracias a la notación de puntos. Antes de empezar a scrapear Instagram a escala, recuerda cumplir con los términos de servicio de Instagram, y asegúrate de que tus esfuerzos de scraping no violan sus políticas.

Comentarios:

0 Comentarios