Come raschiare i dati di Instagram usando Python

Commenti: 0

Ottenere l'accesso ai dati di Instagram può essere complicato a causa di vari meccanismi anti-bot, requisiti di login e limiti di velocità. Tuttavia, è possibile estrarre informazioni utili dai profili pubblici con gli strumenti e le tecniche giuste. Questo articolo vi guiderà su come raschiare i dati degli utenti di Instagram utilizzando Python, effettuando richieste API al backend di Instagram, estraendo informazioni dai dati JSON restituiti e salvandoli in un file JSON.

Impostazione delle librerie necessarie

Prima di entrare nel codice, assicuratevi di aver installato le librerie Python necessarie.


pip install requests python-box

  • richieste: Per effettuare richieste HTTP.
  • python-box: Semplifica l'accesso ai dati trasformando i dizionari in oggetti che consentono l'accesso alla notazione a punti.

Per una migliore comprensione, suddivideremo il codice in diverse sezioni: l'invio della richiesta, l'ottenimento e l'analisi dei dati, l'uso di proxy per evitare il rilevamento e la semplificazione dell'analisi JSON con la libreria Box.

Passo 1. Effettuare la richiesta API

Il frontend di Instagram è fortemente protetto, ma il backend offre endpoint API che possono essere utilizzati senza autenticazione. Utilizzeremo uno di questi punti in futuro.

Questa API fornisce informazioni dettagliate sul profilo di un utente, tra cui la descrizione, il numero di follower e i post. Vediamo come richiedere i dati utilizzando la libreria requests di Python.

Spiegazione:

  1. Intestazioni: Instagram blocca la maggior parte delle richieste dei bot analizzando le intestazioni delle richieste. L'x-ig-app-id è essenziale perché imita una richiesta proveniente dall'app stessa di Instagram.
  2. La stringa User-Agent rappresenta il browser che effettua la richiesta, facendo credere a Instagram che si tratti di un utente reale.
  3. Richiesta API di backend: L'URL https://i.instagram.com/api/v1/users/web_profile_info/?username={username} fa parte dell'API di backend di Instagram. Fornisce informazioni dettagliate su un profilo pubblico.
  4. Gestione della risposta JSON: Utilizziamo response.json() per convertire la risposta dell'API in un oggetto JSON che possiamo analizzare ed estrarre facilmente le informazioni.

import requests

# Definire le intestazioni per imitare una vera richiesta del browser
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": "*/*",
}

# Sostituire questo dato con il nome utente che si vuole scrapare
username = 'testtest'

# Inviare una richiesta API per ottenere i dati del profilo
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers)
response_json = response.json()  # Analizzare la risposta in un oggetto JSON

Passo 2. Gestione dei proxy per bypassare la limitazione di velocità

Poiché Instagram limita le richieste ripetute dallo stesso indirizzo IP, l'uso di proxy è essenziale per lo scraping su larga scala. Un proxy instrada le richieste attraverso indirizzi IP diversi, aiutandovi a evitare il rilevamento.

Per configurare un server proxy, sono necessari l'indirizzo IP, il numero di porta e, se necessario, un nome utente e una password per l'autenticazione.


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. Semplificare l'analisi di JSON con Box

L'API di Instagram restituisce una complessa struttura JSON annidata, che può essere difficile da navigare utilizzando un accesso tradizionale basato sui dizionari. Per semplificare il parsing, possiamo utilizzare la libreria Box, che consente di accedere ai dati JSON utilizzando la notazione a punti invece delle chiavi del dizionario.

Spiegazione:

  1. Box: Questa libreria converte un dizionario JSON in un oggetto, consentendo di accedere a campi profondamente annidati usando la notazione a punti. Per esempio, invece di scrivere response_json['data']['user']['full_name'], possiamo semplicemente scrivere response_json.data.user.full_name.
  2. Estrazione dei dati: Estraiamo informazioni utili sul profilo, come il nome completo dell'utente, l'ID, la biografia, se si tratta di un account aziendale o professionale, lo stato di verifica e il numero di follower.

from box import Box

response_json = Box(response.json())

# Estrarre i dati del profilo utente
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. Estrazione dei dati video e della timeline

Una volta estratti i dati del profilo, possiamo anche effettuare lo scraping dei dati della timeline dei video e dei post regolari dell'utente.

Spiegazione:

  1. Dati video: Questa sezione estrae i dati relativi ai video Instagram dell'utente, tra cui l'URL del video, il numero di visualizzazioni, il numero di commenti e la durata del video.
  2. Timeline Media: Analogamente, questa sezione estrae i dati dalla timeline dell'utente, catturando l'URL dei media del post, i like e i commenti.

# Estrarre i dati video
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)

# Estrazione dei dati multimediali della timeline (foto e video)
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. Salvataggio dei dati in file JSON

Una volta estratti tutti i dati, il passo successivo è salvarli in un file JSON per ulteriori analisi o per l'archiviazione. Utilizziamo il modulo json di Python per scrivere i dati estratti in file JSON. Ogni file sarà formattato in modo ordinato, grazie al parametro indent=4, che rende facile la lettura e l'elaborazione dei dati.


import json

# Salvare i dati dell'utente in un file JSON
with open(f'{username}_profile_data.json', 'w') as file:
    json.dump(user_data, file, indent=4)

# Salvare i dati video in un file JSON
with open(f'{username}_video_data.json', 'w') as file:
    json.dump(profile_video_data, file, indent=4)

# Salvare i dati multimediali della timeline in un file JSON
with open(f'{username}_timeline_media_data.json', 'w') as file:
    json.dump(profile_timeline_media_data, file, indent=4)

Codice completo

Ecco lo script Python completo che combina tutte le sezioni discusse in precedenza. Questo codice esegue lo scrapping dei dati del profilo utente, dei dati video e dei dati multimediali della timeline di Instagram, gestisce le intestazioni e i proxy necessari e salva le informazioni estratte in file JSON.


import requests
from box import Box
import json

# Intestazioni per simulare una vera richiesta del browser all'API di backend di 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": "*/*",
}

# Impostare un proxy per evitare la limitazione della velocità e il rilevamento (facoltativo)
proxies = {
    'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
    'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}

# Il nome utente di Instagram da raschiare
username = 'testtest'

# Inviare una richiesta all'API di backend di Instagram per ottenere i dati del profilo
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())  # Convertire la risposta in un oggetto Box, per facilitare la navigazione.

# Estrarre i dati del profilo utente
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,
}

# Estrarre i dati video dalla timeline video dell'utente
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)

# Estrazione dei dati multimediali della timeline (foto e video)
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)

# Salvare i dati del profilo utente in un file 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')

# Salvare i dati video in un file 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')

# Salvare i dati multimediali della timeline in un file 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')

Lo scraping dei dati di Instagram con Python può essere effettuato sfruttando l'API di back-end fornita da Instagram, che aiuta a bypassare alcune delle restrizioni di front-end. L'uso delle intestazioni giuste per imitare il comportamento del browser e l'impiego di proxy per evitare la limitazione della velocità sono passi fondamentali. La libreria Box semplifica ulteriormente il processo rendendo l'analisi JSON più intuitiva grazie alla notazione a punti. Prima di iniziare lo scraping di Instagram su scala, ricordate di rispettare i termini di servizio di Instagram e di assicurarvi che i vostri sforzi di scraping non violino le sue politiche.

Commenti:

0 Commenti