Twitter non è solo una fonte estesa di notizie, è di gran lunga uno dei migliori campioni dei pensieri del mondo’. Con oltre 330 milioni di utenti attivi, è una delle principali piattaforme in cui le persone amano condividere i propri pensieri. I dati di Twitter possono essere utilizzati per una varietà di scopi come ricerca, analisi dei consumatori, analisi demografiche, e molti altri.
Pertanto, lo scopo principale di questo tutorial è insegnarti come ottenere un campione di dati di Twitter rilevanti per il tuo progetto o la tua attività.
Prima di procedere, assicurati di avere a portata di mano tutte queste variabili:
- Consumer Key
- Consumer Secret
- Access Token
- Access Token Secret
Se vuoi sapere come acquisire i dettagli sopra menzionati, vai a leggere quel post sul blog scritto dal mio collega Dattatray Upase.
Ora facciamo un po’ di programmazione!
Definizione delle variabili di input
Per prima cosa, devi definire alcune delle variabili globali di cui avrai bisogno per il programma:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import sys start_date = sys.argv[1] #"2018-01-09" end_date = sys.argv[2] #"2018-01-10" consumerKey="Inserisci_Qui_La_Tua_Consumer_Key" consumerSecret="Inserisci_Qui_La_Tua_Consumer_Secret" accessToken="Inserisci_Qui_La_Tua_Access_Token" accessTokenSecret="Inserisci_Qui_La_Tua_Access_Token_Secret" keyword= sys.argv[3] #"tcs" lang="en" #vedi cosa offre twitter per il filtraggio della lingua data={} |
Sto importando ‘sys’ per ottenere gli argomenti della riga di comando, perché potrei voler modificare le parole chiave, la data di inizio o la data di fine. Per la lingua ho scelto l'inglese, ma potresti voler verificare quali altre lingue sono supportate. I risultati verranno memorizzati in ‘data’ alla fine.
Di conseguenza, un utilizzo tipico dello script sarebbe questo:
python script.py start_date end_date keyword
Accesso alle API di Twitter
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import oauth2 req_count = 0 def oauth_req(url, http_method="GET", post_body=b"", http_headers=None): global req_count,consumerKey,consumerSecret,accessToken,accessTokenSecret req_count += 1 consumer = oauth2.Consumer(key=consumerKey, secret=consumerSecret) token = oauth2.Token(key=accessToken, secret=accessTokenSecret) client = oauth2.Client(consumer, token) resp, content = client.request( url, method=http_method, body=post_body , headers=http_headers ) return content |
La variabile req_count è il numero di volte in cui ho utilizzato l'API nell'esecuzione del mio programma. Sto riscontrando il seguente errore con il codice fornito:
TypeError: Unicode-objects must be encoded before hashing
Per evitare questo, sto modificando post_body=”” in post_body=b”” e questo risolve il problema.
Utilizzo e riferimento dell'API di Twitter
È tempo di impostare l'URL dell'API per ottenere i dati di Twitter. Sto utilizzando il parametro min_faves. Ecco la spiegazione dell'URL e alcuni trucchi di ottimizzazione:
‘min_faves’ viene utilizzato per impostare il numero minimo di preferiti che un tweet dovrebbe avere nei dati. È una funzionalità molto utile ma non è menzionata nella documentazione dell'API di Twitter.
‘q’ rappresenta la query o le parole chiave che desideri inserire. Qui è importante assicurarsi di inserire il minor numero possibile di parole chiave. Ad esempio, immaginiamo di volere tweet su Facebook e Google. Se inserisco entrambi come parole chiave, ad esempio FACEBOOK e GOOGLE, mi restituirà solo un massimo di 100 tweet, poiché si tratta di una restrizione. Ma se eseguo la query due volte – una con Facebook e una con Google, posso ottenere un totale di 200 tweet. In breve, è meglio utilizzare una sola parola chiave per query.
‘lang’ rappresenta la lingua dei tweet filtrati. Poiché desidero ottenere tweet in inglese, lo sto impostando su ‘en’.
‘since’ è la data di inizio del periodo a partire dal quale desideri cercare i tweet. Questa data di inizio dovrebbe rientrare negli ultimi 7 giorni. Questa è un'altra funzionalità che non è documentata nella documentazione dell'API di Twitter.
‘until’ rappresenta la data di fine del periodo desiderato. Logicamente, dovrebbe anch'essa rientrare negli ultimi 7 giorni. Inoltre, non è documentata nella documentazione dell'API di Twitter.
‘result_type’ rappresenta il tipo di tweet che desideri. Ha 3 valori:
‘recent’ fornisce i tweet più recenti, ovvero i tweet alla fine del periodo selezionato.
‘popular’ fornisce i tweet più popolari e quindi tralascia molti tweet. Otterresti sempre i tweet con il maggior numero di preferiti e retweet. La min_faves funzionalità non sarebbe di alcuna utilità qui.
‘mixed’ fornisce un mix di tweet recenti e popolari.
‘count’ rappresenta il numero massimo di tweet nel risultato. Il valore predefinito è impostato su 15 e il massimo è 100.
Con il misto result_type e l'uso di min_faves, possiamo ottenere il massimo dei tweet eseguendo la query più volte.
|
1 2 3 |
def get_tweets(min_faves): global keyword, start_date, end_date, lang return oauth_req( 'https://api.twitter.com/1.1/search/tweets.json?' + '&q=' + keyword + '&lang=' + lang + '%20since%3A' + start_date + '%20until%3A' + end_date + '%20min_faves%3A' + str(min_faves) +'&result_type=mixed&count=100') |
Per ulteriori funzionalità documentate, puoi anche consultare la Twitter’s API Documentation.
Salvataggio/Salvataggio automatico dei dati dei tweet recuperati
Come passaggio successivo, devi definire un metodo di salvataggio/salvataggio automatico che abbia un parametro ‘saveOverride’. Questo passaggio è semplicemente necessario per rimuovere la restrizione temporale del salvataggio automatico e salvare il file. Per fare questo, creo un t_last per salvare l'ora di inizio del programma. Quindi accedo allo stesso nel programma e verifico se sono passati 5 minuti da t_last (ultimo orario di salvataggio). Se sono passati più di 5 minuti, contrassegno ‘saveStatus’ come True.
Successivamente, verifico ‘saveOverride’, il che significa semplicemente che devo dare istruzioni al mio programma affinché, a prescindere da tutto, il file venga salvato ora. Per fare questo, imposto saveStatus su True.
Quindi, se ‘saveStatus’ è True, lo script cambierà il t_last con l'ora corrente. Successivamente, il codice crea un oggetto dizionario e stampa “Salvataggio automatico alle [time]” in modo da sapere che i dati vengono salvati automaticamente.
Successivamente, verifico se il file di output esiste già. In caso affermativo, unisco i dati e i dati di un file già salvato. Dopo averli uniti, li scrivo nello stesso file. Se non esiste, creo un nuovo file e poi scrivo i dati in quel file.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import os import json import time import datetime t_last = time.time() def autosave(saveOverride = False): global t_last saveStatus = (time.time() > t_last + 300) if(saveOverride == True):en" saveStatus = True if(saveStatus): t_last=time.time() tmp = {} print("Salvataggio automatico a " + str(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))) fnamea = keyword + "-st-" + start_date + "-ed-"+ end_date + '.json' if os.path.exists(fnamea) == True: with open(fnamea,'r+') as f: tmp = json.load(f) for i in data.keys(): tmp[i] = data[i] with open(fnamea,'w+') as f: json.dump(tmp,f) |
Di conseguenza, ho programmato quasi tutta la funzionalità che desideravo.
Ottimizzare ulteriormente
Finalmente è giunto il momento di utilizzare queste funzioni. Sto scrivendo un ciclo while(1), il che significa while(True). Questo fondamentalmente fa sì che l'istruzione venga eseguita all'infinito finché non viene chiamata un'istruzione ‘break’ o non viene sollevata un'eccezione.
Per prima cosa, raccolgo i dati dei tweet nel dizionario ‘d’ utilizzando json.loads che converte i dati in un formato dizionario. Quindi, eseguo un try-catch/except sul blocco di codice che estrae gli stati dai dati. Uso try-catch perché a volte l'API di Twitter non restituisce dati ma un JSON che menziona l'errore. Non voglio che il mio programma si interrompa in questi casi. Inoltre, voglio che recuperi a quale numero di richiesta sta accadendo e che salvi i miei dati di Twitter utilizzando il comando autosave. Twitter ci consente di effettuare 180 richieste ogni 15 minuti. Sono circa 12 richieste al minuto o una richiesta ogni cinque secondi. Per sicurezza, aggiungo un comando sleep per far dormire il mio programma per 5 secondi dopo l'esecuzione di un'iterazione.
Dopodiché, il codice mostrerà il numero di tweet che lo script ha raccolto finora.
Infine, è giunto il momento per il principale trucco di ottimizzazione. Ho testato questo script per quasi una settimana e ho ottenuto il seguente numero di tweet per ciascun min_faves valore. Posso ottenere un massimo di 100 tweet per richiesta e voglio ottenerne il maggior numero possibile. Attualmente non ci sono molti tweet con valori più alti di min_faves ma vogliamo tenere conto dei momenti in cui, forse, l'azienda o la parola chiave sono di tendenza. Il valore massimo di min_faves può essere 999999.
| Valore di min_faves | Numero di tweet |
| 100,000 | 1 |
| 90,000 | 1 |
| 80,000 | 1 |
| 70,000 | 2 |
| 60,000 | 3 |
| 50,000 | 6 |
| 40,000 | 6 |
| 30,000 | 12 |
| 25,000 | 12 |
Pertanto, sto utilizzando una logica che otterrebbe i tweet da un min_faves valore di 60000 per poi diminuirlo di 10000 ogni volta fino a raggiungere 10000. Ma se, ad esempio, la parola chiave è di tendenza e ottengo 100 tweet quando lavoro con il valore di min_faves pari a 30000, questo aumenterà il min_faves a 35000 e poi ottenere nuovamente i risultati. Quindi ora la nuova logica è 5000 invece di 10000. Tuttavia, se la variazione scende a meno di 1000, chiedo di ignorare e procedere con la sottrazione di 1000.
Sto specificando un intervallo fisso di 1000 di cui min_faves dovrebbe diminuire se min_faves è minore o uguale a 10000.
Alla fine del programma, il programma ti informerà che il lavoro è completato mostrando ‘End’.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
min_faves=60000 change=10000 #forte riduzione di min_faves per estrarre i dati interval = 500 #riduzione normale di min_faves per estrarre i dati while(1): d = json.loads(get_tweets(min_faves)) try: for i in d['statuses']: data[i['id']] = i c = len(d['statuses']) except Exception as e: print("Errore alla richiesta : " + str(req_count)) autosave(True) print("Alla richiesta: " + str(req_count) + " Tweet totali raccolti: " + str(len(data)) + " con Min Faves: " + str(min_faves) ) if c==100 and min_faves>10000: if (change>1000): change /= 2 min_faves += change else: min_faves -= change elif min_faves>10000: min_faves -= change else: min_faves -= interval if(min_faves < 0): fnamea = keyword + '.json' autosave(True) break autosave() time.sleep(5) print("End") |
Puoi trovare l'intero codice su GitHub.
Questo è tutto. Nel prossimo tutorial sui dati di Twitter, ti insegnerò come recuperare i tweet in tempo reale utilizzando lo strumento per big data ‘Flume’. Resta sintonizzato!
Commenti
Ancora nessun commento. Scrivi il primo.