Twitter není jen rozšířeným zdrojem zpráv, je to zdaleka jeden z nejlepších vzorků myšlenek světa. S více než 330 miliony aktivních uživatelů je to jedna z předních platforem, kde lidé rádi sdílejí své myšlenky. Data z Twitteru lze využít k různým účelům, jako je například výzkum, poznatky o spotřebitelích, demografické poznatky, a mnoho dalších.
Hlavním cílem tohoto návodu je proto naučit vás, jak získat vzorek dat z Twitteru relevantní pro váš projekt nebo podnikání.
Než budete pokračovat, ujistěte se, že máte po ruce všechny tyto proměnné:
- Consumer Key
- Consumer Secret
- Access Token
- Access Token Secret
Pokud chcete vědět, jak získat výše uvedené údaje, přečtěte si tento příspěvek na blogu, který napsal můj kolega Dattatray Upase.
Teď si pojďme trochu zaprogramovat!
Definování vstupních proměnných
Nejprve musíte definovat některé globální proměnné, které budete pro program potřebovat:
|
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="Enter_Your_Consumer_Key_Here" consumerSecret="Enter_Your_Consumer_Secret_Here" accessToken="Enter_Your_Access_Token_Here" accessTokenSecret="Enter_Your_Access_Token_Secret_Here" keyword= sys.argv[3] #"tcs" lang="en" #podívejte se, co twitter nabízí pro filtrování jazyků data={} |
Importuji ‘sys’, abych získal argumenty příkazové řádky, protože možná budu chtít změnit klíčová slova, počáteční nebo koncové datum. Pro jazyk jsem vybral angličtinu, ale možná budete chtít zkontrolovat, jaké další jazyky jsou podporovány. Výsledky budou uloženy v ‘data’ na konci.
Výsledkem je, že typické použití skriptu by vypadalo takto:
python script.py start_date end_date keyword
Přístup k Twitter API
|
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 |
Proměnná req_count představuje počet, kolikrát jsem použil API při spuštění mého programu. S uvedeným kódem se potýkám s následující chybou:
TypeError: Unicode-objects must be encoded before hashing
Abych se tomu vyhnul, měním post_body=”” na post_body=b”” a to problém vyřeší.
Použití a reference Twitter API
Je čas nastavit URL adresu API pro získání dat z Twitteru. Používám parametr min_faves. Zde je vysvětlení URL adresy a několik optimalizačních triků:
‘min_faves’ se používá k nastavení minimálního počtu oblíbených položek, které by měl tweet v datech mít. Je to velmi užitečná funkce, ale v dokumentaci k rozhraní Twitter API není zmíněna.
‘q’ představuje dotaz nebo klíčová slova, která chcete zadat. Zde je důležité se ujistit, že zadáte co nejméně klíčových slov. Představme si například, že chci tweety o Facebooku a Google. Pokud zadám obě jako klíčová slova, řekněme FACEBOOK a GOOGLE, vrátí mi to pouze maximálně 100 tweetů, protože to je omezení. Pokud ale dotaz spustím dvakrát – jednou s Facebookem a jednou s Googlem, mohu získat celkem 200 tweetů. Zkrátka a dobře, je lepší použít jedno klíčové slovo na dotaz.
‘lang’ představuje jazyk filtrovaných tweetů. Vzhledem k tomu, že chci získat tweety v angličtině, nastavuji jej na ‘en’.
‘since’ je počáteční datum období, od kterého chcete tweety vyhledávat. Toto počáteční datum by mělo být z posledních 7 dnů. To je další funkce, která není zdokumentována v dokumentaci k rozhraní Twitter API.
‘until’ představuje koncové datum vámi požadovaného období. Logicky by mělo být také z posledních 7 dnů. V dokumentaci k rozhraní Twitter API to také není zdokumentováno.
‘result_type’ představuje druh tweetů, které chcete. Má 3 hodnoty:
‘recent’ poskytuje nejnovější tweety, tj. tweety na konci vybraného období.
‘popular’ poskytuje nejoblíbenější tweety, a proto jich spoustu vynechá. Vždy byste získali tweety s nejvyšším počtem oblíbených položek a retweetů. Funkce min_faves by zde byla k ničemu.
‘mixed’ poskytuje směs nejnovějších a oblíbených tweetů.
‘count’ představuje maximální počet tweetů ve výsledku. Výchozí hodnota je nastavena na 15 a maximum je 100.
Se smíšeným result_type a použitím min_faves, můžeme získat maximum tweetů vícenásobným spuštěním dotazu.
|
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') |
Další zdokumentované funkce naleznete také v Twitter’s API Documentation.
Ukládání/automatické ukládání získaných dat o tweetech
V dalším kroku musíte definovat metodu automatického ukládání/ukládání, která má parametr ‘saveOverride’. Tento krok je jednoduše zapotřebí k odstranění časového omezení automatického ukládání a uložení souboru. Chcete-li to provést, vytvořím t_last pro uložení času spuštění programu. Poté k němu v programu přistoupím a zkontroluji, zda od t_last (času posledního uložení) uplynulo více než 5 minut. Pokud uplynulo více než 5 minut, označím ‘saveStatus’ jako True.
Dále zkontroluji ‘saveOverride’, což jednoduše znamená, že musím dát svému programu pokyn, aby se soubor bez ohledu na cokoli uložil hned. Za tímto účelem nastavím saveStatus na True.
Pokud je pak ‘saveStatus’ True, skript změní t_last na aktuální čas. Poté kód vytvoří objekt slovníku a vypíše “Automatické uložení v [time]”, abyste věděli, že se data automaticky ukládají.
Dále kontroluji, zda výstupní soubor již existuje. Pokud ano, spojuji data a data z již uloženého souboru. Po spojení je zapíšu do stejného souboru. Pokud neexistuje, vytvořím nový soubor a poté do něj data zapíšu.
|
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("Automatické ukládání v " + 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) |
Díky tomu jsem naprogramoval téměř celou funkčnost, kterou jsem chtěl.
Další optimalizace
Konečně nastal čas tyto funkce využít. Píšu cyklus while(1), což znamená while(True). To v podstatě způsobí, že instrukce běží navždy, dokud není zavolán příkaz ‘break’ nebo vyvolána nějaká výjimka.
Nejprve shromáždím data o tweetech do slovníku ‘d’ pomocí json.loads, což převede data do formátu slovníku. Poté spustím try-catch/except na blok kódu, který z dat extrahuje stavy. Používám try-catch, protože Twitter API někdy nevrátí data, ale JSON s chybovou zprávou. Nechci, aby se můj program v takových případech zastavil. Také chci, aby zjistil, u jakého čísla požadavku k tomu dochází, a uložil moje data z Twitteru pomocí příkazu autosave. Twitter nám umožňuje provést 180 požadavků za 15 minut. To je přibližně 12 požadavků za minutu nebo jeden požadavek každých pět sekund. Pro jistotu přidávám příkaz sleep, aby program po provedení jedné iterace na 5 sekund usnul.
Poté kód zobrazí počet tweetů, které skript dosud shromáždil.
Konečně je čas na hlavní optimalizační trik. Tento skript jsem testoval téměř týden a pro každou hodnotu min_faves jsem získal následující počet tweetů. Na jeden požadavek mohu získat maximálně 100 tweetů a chci jich získat co nejvíce. V současné době není mnoho tweetů s vyššími hodnotami min_faves, ale chceme vzít v úvahu situace, kdy je firma nebo klíčové slovo populární. Maximální hodnota min_faves může být 999999.
| Hodnota min_faves | Počet 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 |
Proto používám logiku, která získá tweety od min_faves s hodnotou 60000 a poté ji pokaždé sníží o 10000, dokud nedosáhne 10000. Ale pokud je například klíčové slovo populární a já získám 100 tweetů, když pracuji s hodnotou min_faves nastavenou na 30000, zvýší to min_faves na 35000 a poté znovu získat výsledky. Takže nyní je nová logika 5000 namísto 10000. Pokud se však změna sníží na méně než 1000, požádám o ignorování a pokračování s odečtením 1000.
Určuji pevný interval 1000, o který se min_faves má snížit, pokud min_faves je menší nebo rovno 10000.
Na konci programu vás program upozorní na dokončení práce zobrazením ‘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 #vysoké snížení min_faves pro extrakci dat interval = 500 #běžné snížení min_faves pro extrakci dat 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("Chyba při požadavku: " + str(req_count)) autosave(True) print("Při požadavku: " + str(req_count) + " Celkem stažených tweetů: " + str(len(data)) + " s 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") |
Celý kód najdete na GitHub.
To je vše. V dalším tutoriálu o twitterových datech vás naučím, jak získávat tweety v reálném čase pomocí nástroje pro big data ‘Flume’. Zůstaňte na příjmu!
Komentáře
Zatím žádné komentáře. Buďte první.