Como extrair dados do Instagram utilizando Python

Comentários: 0

Obter acesso aos dados do Instagram pode ser complicado devido a vários mecanismos anti-bot, requisitos de início de sessão e limites de taxa. No entanto, é possível extrair informações úteis de perfis públicos com as ferramentas e técnicas certas. Este artigo irá guiá-lo sobre como extrair dados de usuários do Instagram usando Python, fazendo solicitações de API para o back-end do Instagram, extraindo informações dos dados JSON retornados e salvando-os em um arquivo JSON.

Configuração das bibliotecas necessárias

Antes de entrarmos no código, certifique-se de que instalou as bibliotecas Python necessárias.


pip install requests python-box

  • pedidos: Para efetuar pedidos HTTP.
  • python-box: Simplifica o acesso aos dados, transformando dicionários em objectos que permitem o acesso por notação de pontos.

Vamos dividir o código em diferentes secções para uma melhor compreensão, incluindo o envio do pedido, a obtenção e análise dos dados, a utilização de proxies para evitar a deteção e a simplificação da análise JSON com a biblioteca Box.

Passo 1. Efetuar o pedido de API

O frontend do Instagram é altamente seguro, mas o backend oferece pontos de extremidade da API que podem ser usados sem autenticação. Iremos utilizar um destes pontos daqui para a frente.

Esta API fornece informações detalhadas sobre o perfil de um utilizador, incluindo a sua descrição, contagem de seguidores e publicações. Vamos explorar como solicitar dados usando a biblioteca de solicitações em Python.

Explicação:

  1. Cabeçalhos: O Instagram bloqueia a maioria dos pedidos de bots analisando os cabeçalhos dos pedidos. O x-ig-app-id é essencial porque imita um pedido proveniente da própria aplicação do Instagram.
  2. A cadeia User-Agent representa o browser que faz o pedido, levando o Instagram a acreditar que se trata de um utilizador real.
  3. Pedido de API backend: O URL https://i.instagram.com/api/v1/users/web_profile_info/?username={username} faz parte da API backend do Instagram. Fornece informações detalhadas sobre um perfil público.
  4. Manipulando a resposta JSON: Usamos response.json() para converter a resposta da API em um objeto JSON do qual podemos analisar e extrair informações facilmente.

import requests

# Definir cabeçalhos para imitar um pedido real do navegador
headers = {
    "x-ig-app-id": "936619743392459",  # Instagram app ID to authenticate the request
    "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": "*/*",
}

# Substitua isto pelo nome de utilizador que pretende extrair
username = 'testtest'

# Enviar um pedido de API para obter dados de perfil
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers)
response_json = response.json()  # Analisar a resposta num objeto JSON

Passo 2. Manipulação de proxies para contornar a limitação de débito

Uma vez que o Instagram restringe os pedidos repetidos a partir do mesmo endereço IP, a utilização de proxies é essencial para a recolha de dados em grande escala. Um proxy encaminha os seus pedidos através de diferentes endereços IP, ajudando-o a evitar a deteção.

Para configurar um servidor proxy, é necessário o endereço IP, o número da porta e, se necessário, um nome de utilizador e uma palavra-passe para autenticação.


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)

Passo 3. Simplificar a análise JSON com o Box

A API do Instagram retorna uma estrutura JSON aninhada complexa, que pode ser difícil de navegar usando o acesso tradicional baseado em dicionário. Para facilitar a análise, podemos usar a biblioteca Box, que permite acessar dados JSON usando notação de ponto em vez de chaves de dicionário.

Explicação:

  1. Caixa: Esta biblioteca converte um dicionário JSON num objeto, permitindo-nos aceder a campos profundamente aninhados utilizando a notação de pontos. Por exemplo, em vez de escrever response_json['data']['user']['full_name'], podemos simplesmente escrever response_json.data.user.full_name.
  2. Extração de dados: Extraímos informações de perfil úteis, como o nome completo do utilizador, ID, biografia, se é uma conta profissional ou empresarial, estado de verificação e número de seguidores.

from box import Box

response_json = Box(response.json())

# Extrair dados do perfil do utilizador
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,
}

Passo 4. Extrair os dados do vídeo e da linha de tempo

Uma vez extraídos os dados do perfil, podemos também extrair dados da cronologia dos vídeos e das publicações regulares do utilizador.

Explicação:

  1. Dados do vídeo: Esta secção extrai dados sobre os vídeos do Instagram do utilizador, incluindo o URL do vídeo, a contagem de visualizações, a contagem de comentários e a duração do vídeo.
  2. Media da linha de tempo: Da mesma forma, esta secção extrai dados da linha de tempo do utilizador, capturando o URL de multimédia, os gostos e os comentários da publicação.

# Extrair dados 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)

# Extrair dados multimédia da linha cronológica (fotografias e 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)

Passo 5. Guardar os dados em ficheiros JSON

Depois de extrair todos os dados, o passo seguinte é guardá-los num ficheiro JSON para análise ou armazenamento posterior. Utilizamos o módulo json do Python para escrever os dados extraídos em ficheiros JSON. Cada ficheiro será formatado de forma clara, graças ao parâmetro indent=4, o que facilita a leitura e o processamento dos dados.


import json

# Guardar os dados do utilizador num ficheiro JSON
with open(f'{username}_profile_data.json', 'w') as file:
    json.dump(user_data, file, indent=4)

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

# Guardar os dados multimédia da linha de tempo num ficheiro JSON
with open(f'{username}_timeline_media_data.json', 'w') as file:
    json.dump(profile_timeline_media_data, file, indent=4)

Código completo

Aqui está o script Python completo que combina todas as seções discutidas anteriormente. Este código extrai dados de perfil de utilizador, dados de vídeo e dados de multimédia da linha cronológica do Instagram, trata dos cabeçalhos e proxies necessários e guarda a informação extraída em ficheiros JSON.


import requests
from box import Box
import json

# Cabeçalhos para imitar um pedido real do navegador para a API de back-end do 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": "*/*",
}

# Definir um proxy para evitar a limitação da taxa e a deteção (opcional)
proxies = {
    'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
    'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}

# O nome de utilizador do Instagram a extrair
username = 'testtest'

# Enviar um pedido à API de backend do Instagram para obter dados de 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())  # Converter a resposta em objeto Box para facilitar a navegação

# Extrair dados do perfil do utilizador
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,
}

# Extrair dados de vídeo da linha de tempo de vídeo do utilizador
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)

# Extrair dados multimédia da linha cronológica (fotografias e 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 os dados do perfil do utilizador num ficheiro 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 dados de vídeo num ficheiro 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 os dados multimédia da linha de tempo num ficheiro 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')

A extração de dados do Instagram com Python pode ser feita aproveitando a API de back-end fornecida pelo Instagram, que ajuda a contornar algumas das restrições de front-end. Usar os cabeçalhos corretos para imitar o comportamento do navegador e empregar proxies para evitar a limitação de taxa são etapas críticas. A biblioteca Box simplifica ainda mais o processo, tornando a análise de JSON mais intuitiva com a notação de pontos. Antes de começar a fazer scraping do Instagram em escala, lembre-se de cumprir os termos de serviço do Instagram e certifique-se de que seus esforços de scraping não violam suas políticas.

Comentários:

0 Comentários