A Twitter nem csupán egy kibővített hírforrás, hanem messze az egyik legjobb minta a világ gondolataiból. Több mint 330 millió aktív felhasználójával az egyik legnépszerűbb platform, ahol az emberek szívesen megosztják gondolataikat. A Twitter-adatok számos célra felhasználhatók, mint például kutatás, fogyasztói betekintések, demográfiai betekintések, és még sok más.
Ezért ennek az útmutatónak az elsődleges célja, hogy megtanítsa, hogyan szerezhet be a projektje vagy vállalkozása számára releváns Twitter-adatmintát.
Mielőtt továbblépne, győződjön meg arról, hogy kéznél vannak a következő változók:
- Consumer Key
- Consumer Secret
- Access Token
- Access Token Secret
Ha szeretné megtudni, hogyan szerezheti be a fent említett adatokat, olvassa el ezt a blogbejegyzést, amelyet kollégám, Dattatray Upase írt.
Most pedig kódoljunk egy kicsit!
A bemeneti változók meghatározása
Először meg kell határoznia néhány globális változót, amelyekre szüksége lesz a programhoz:
|
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="Írd_Ide_A_Consumer_Key-t" consumerSecret="Írd_Ide_A_Consumer_Secret-et" accessToken="Írd_Ide_A_Access_Token-t" accessTokenSecret="Írd_Ide_A_Access_Token_Secret-et" keyword= sys.argv[3] #"tcs" lang="en" #nézd meg, mit kínál a twitter a nyelvszűréshez data={} |
Azért importálom a ‘sys’ modult, hogy lekérjem a parancssori argumentumokat, mivel előfordulhat, hogy meg akarom változtatni a kulcsszavakat, a kezdő dátumot vagy a végdátumot. Nyelvnek az angolt választottam, de érdemes lehet ellenőrizni, hogy milyen más nyelvek támogatottak. Az eredmények a végén a ‘data’ változóban lesznek tárolva.
Ebből adódóan a szkript tipikus használata így nézne ki:
python script.py start_date end_date keyword
A Twitter API elérése
|
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 |
A req_count változó azt mutatja meg, hányszor használtam az API-t a programom futtatása során. A megadott kóddal a következő hibába ütközöm:
TypeError: Unicode-objects must be encoded before hashing
Ennek elkerülése érdekében a post_body=”” értéket post_body=b”” értékre változtatom , és ez megoldja a problémát.
Twitter API használat és referencia
Itt az ideje beállítani az API URL-t a Twitter adatok lekéréséhez. A min_faves paramétert használom. Íme az URL magyarázata és néhány optimalizálási trükk:
‘min_faves’ arra szolgál, hogy beállítsa a tweetek minimális kedvelésszámát az adatokban. Ez egy nagyon hasznos funkció, de nem szerepel a Twitter API dokumentációjában.
‘q’ a lekérdezést vagy a megadni kívánt kulcsszavakat jelöli. Itt fontos megbizonyosodni arról, hogy a lehető legkevesebb kulcsszót add meg. Képzeljük el például, hogy a Facebookról és a Google-ről szeretnék tweeteket kapni. Ha mindkettőt megadom kulcsszóként, mondjuk FACEBOOK és GOOGLE, akkor legfeljebb 100 tweetet fog visszaadni, mivel ez egy korlátozás. De ha kétszer futtatom le a lekérdezést – egyszer a Facebookkal és egyszer a Google-lel, összesen 200 tweetet kaphatok. Röviden: jobb lekérdezésenként egy kulcsszót használni.
‘lang’ a szűrt tweetek nyelvét jelöli. Mivel angol nyelvű tweeteket szeretnék kapni, ezt ‘en’ értékre állítom.
‘since’ az az időszak kezdő dátuma, amelytől kezdve tweeteket szeretnél keresni. Ennek a kezdő dátumnak az elmúlt 7 napból kell származnia. Ez egy másik olyan funkció, amely nem szerepel a Twitter API dokumentációjában.
‘until’ a kívánt időszak végdátumát jelöli. Logikusan ennek is az elmúlt 7 napból kell származnia. Ez szintén nem szerepel a Twitter API dokumentációjában.
‘result_type’ a kívánt tweetek típusát jelöli. 3 értéke lehet:
‘recent’ a legfrissebb tweeteket adja vissza, azaz a kiválasztott időszak végén lévő tweeteket.
‘popular’ a legnépszerűbb tweeteket adja vissza, ezért sok tweetről lemarad. Mindig a legtöbb kedveléssel és retweettel rendelkező tweeteket kapod meg. A min_faves funkciónak itt nem lenne haszna.
‘mixed’ a legfrissebb és a legnépszerűbb tweetek keverékét adja vissza.
‘count’ az eredményben szereplő tweetek maximális számát jelöli. Az alapértelmezett érték 15, a maximum pedig 100.
A vegyes result_type és a min_faves használatával a lekérdezés többszöri futtatásával a maximális számú tweetet kaphatjuk meg.
|
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') |
További dokumentált funkciókért látogass el a Twitter’s API Documentation.
A letöltött tweet adatok mentése/automatikus mentése
Következő lépésként meg kell határoznod egy automatikus mentési/mentési metódust, amelynek van egy ‘saveOverride’ paramétere. Erre a lépésre egyszerűen azért van szükség, hogy feloldjuk az automatikus mentés időbeli korlátozását és elmentsük a fájlt. Ennek érdekében létrehozok egy t_last változót a program kezdési idejének mentésére. Ezután hozzáferek ehhez a programban, és ellenőrzöm, hogy eltelt-e 5 perc a t_last (utolsó mentési idő) óta. Ha több mint 5 perc telt el, a ‘saveStatus’ értékét True-ra állítom.
Ezután ellenőrzöm a ‘saveOverride’ paramétert, ami egyszerűen azt jelenti, hogy utasítanom kell a programomat, hogy a fájlt most mindenképpen mentse el. Ehhez a saveStatus értékét True-ra állítom.
Ezután, ha a ‘saveStatus’ értéke True, a szkript átírja a t_last értékét a jelenlegi időre. Ezt követően a kód létrehoz egy szótár (dictionary) objektumot, és kiírja az “Autosave at [time]” üzenetet, hogy tudd, az adatok automatikusan mentésre kerülnek.
Ezután ellenőrzöm, hogy a kimeneti fájl létezik-e már. Ha igen, összefésülöm az adatokat a már elmentett fájlban lévő adatokkal. Az összefésülés után ugyanabba a fájlba írom őket. Ha nem létezik, létrehozok egy új fájlt, majd abba írom az adatokat.
|
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("Automatikus mentés ekkor: " + 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) |
Ennek eredményeként szinte a teljes kívánt funkcionalitást leprogramoztam.
További optimalizálás
Végül itt az ideje, hogy használatba vegyük ezeket a függvényeket. Egy while(1) ciklust írok, ami a while(True) ciklust jelenti. Ez alapvetően azt eredményezi, hogy az utasítás örökké fut, amíg egy ‘break’ utasítás meg nem hívódik, vagy valamilyen kivétel nem keletkezik.
Először összegyűjtöm a tweetek adatait a ‘d’ szótárba a json.loads segítségével, ami az adatokat szótár formátumba konvertálja. Ezután futtatok egy try-catch/except azon a kódblokkon, amely kinyeri az állapotokat az adatokból. Azért használok try-catch-et, mert a Twitter API néha nem adatokat ad vissza, hanem egy hibaüzenetet tartalmazó JSON-t. Nem szeretném, hu a programom leállna ilyen esetekben. Emellett szeretném lekérdezni, hogy ez hanyadik kérésnél történik, és elmenteni a Twitter-adataimat az autosave paranccsal. A Twitter 15 percenként 180 kérést engedélyez számunkra. Ez körülbelül percenként 12 kérést vagy öt másodpercenként egy kérést jelent. A biztonság kedvéért hozzáadok egy sleep parancsot, hogy a programom 5 másodpercig aludjon egy iteráció végrehajtása után.
Ezt követően a kód megjeleníti az eddig összegyűjtött tweetek számát.
Végül elérkezett az idő a fő optimalizálási trükkhöz. Majdnem egy hétig teszteltem ezt a szkriptet, és a következő számú tweetet kaptam minden egyes min_faves értékre. Kérésenként legfeljebb 100 tweetet kaphatok, és a lehető legtöbbet szeretném megszerezni. Jelenleg nincs sok tweet magasabb min_faves értékkel, de szeretnénk számolni azokkal az időkkel is, amikor esetleg a cég vagy a kulcsszó felkapottá válik. A min_faves maximális értéke 999999 lehet.
| min_faves érték | Tweetek száma |
| 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 |
Ezért olyan logikát használok, amely lekéri a tweeteket a min_faves 60000-es értékétől kezdve, majd minden alkalommal 10000-rel csökkenti azt, amíg el nem éri a 10000-et. De ha mondjuk a kulcsszó felkapott, és 100 tweetet kapok, amikor a min_faves értéke 30000, akkor ez növelni fogja a min_faves 35000-re, majd kérje le újra az eredményeket. Így most az új logika 5000 a 10000 helyett. Ha azonban a változás 1000 alá csökken, arra kérem, hogy hagyja figyelmen kívül, és folytassa az 1000 levonásával.
Egy rögzített, 1000-es intervallumot határozok meg, amellyel a min_faves értékének csökkennie kell, ha a min_faves kisebb vagy egyenlő, mint 10000.
A program végén a program az ‘End’ kiírásával jelzi, hogy a munka befejeződött.
|
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 #nagy csökkenés a min_faves értékben az adatok kinyeréséhez interval = 500 #normál csökkenés a min_faves értékben az adatok kinyeréséhez 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("Hiba a kérésnél : " + str(req_count)) autosave(True) print("A kérésnél: " + str(req_count) + " Összes összegyűjtött tweet: " + str(len(data)) + " Min Faves értékkel: " + 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") |
A teljes kódot megtalálja a GitHub.
Ez minden. A következő Twitter-adatokról szóló útmutatóban megmutatom, hogyan hívhat le valós idejű tweeteket a ‘Flume’ big data eszközzel. Maradjon velünk!
Hozzászólások
Még nincsenek hozzászólások. Legyen Ön az első.