Twitter nije samo prošireni izvor vijesti, on je daleko jedan od najboljih uzoraka svjetskih razmišljanja. S više od 330 milijuna aktivnih korisnika, to je jedna od vodećih platformi na kojoj ljudi vole dijeliti svoja razmišljanja. Podaci s Twittera mogu se koristiti u razne svrhe kao što su istraživanje, uvidi u potrošače, demografski uvidi, i još mnogo toga.
Stoga je primarni cilj ovog vodiča naučiti vas kako dobiti uzorak podataka s Twittera koji su relevantni za vaš projekt ili poslovanje.
Prije nego što nastavite, provjerite imate li sve ove varijable pri ruci:
- Consumer Key
- Consumer Secret
- Access Token
- Access Token Secret
Ako želite saznati kako dobiti gore navedene pojedinosti, pročitajte taj blog post koji je napisao moj kolega Dattatray Upase.
Sada idemo malo kodirati!
Definiranje ulaznih varijabli
Prvo morate definirati neke od globalnih varijabli koje će vam trebati za program:
|
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" #pogledajte što twitter nudi za filtriranje jezika data={} |
Uvozim ‘sys’ kako bih dobio argumente naredbenog retka, jer bih možda želio promijeniti ključne riječi, početni datum (start-date) ili završni datum (end-date). Za jezik sam odabrao engleski, ali možda biste trebali provjeriti koji su drugi jezici podržani. Rezultati će biti pohranjeni u ‘data’ na kraju.
Kao rezultat toga, tipična upotreba skripte izgledala bi ovako:
python script.py start_date end_date keyword
Pristupanje Twitter API-ju
|
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 |
Varijabla req_count predstavlja broj koliko sam puta koristio API tijekom izvršavanja svog programa. Suočavam se sa sljedećom pogreškom s navedenim kodom:
TypeError: Unicode-objects must be encoded before hashing
Kako bih to izbjegao, mijenjam post_body=”” u post_body=b”” i to rješava problem.
Korištenje i referenca Twitter API-ja
Vrijeme je da postavite URL API-ja za preuzimanje podataka s Twittera. Koristim parametar min_faves. Ovdje je objašnjenje URL-a i nekoliko trikova za optimizaciju:
‘min_faves’ se koristi za postavljanje minimalnog broja favorita koje bi tvit trebao imati u podacima. To je vrlo korisna značajka, ali se ne spominje u dokumentaciji Twitter API-ja.
‘q’ predstavlja upit ili ključne riječi koje želite unijeti. Ovdje je važno osigurati da unesete što manje ključnih riječi. Na primjer, zamislimo da želim tvitove o Facebooku i Googleu. Ako unesem obje kao ključne riječi, recimo, FACEBOOK i GOOGLE, vratit će mi najviše 100 tvitova, jer je to ograničenje. Ali ako pokrenem upit dvaput – jednom s Facebookom i jednom s Googleom, mogu dobiti ukupno 200 tvitova. Ukratko, bolje je koristiti jednu ključnu riječ po upitu.
‘lang’ predstavlja jezik filtriranih tvitova. Budući da želim dobiti tvitove na engleskom jeziku, postavljam ga na ‘en’.
‘since’ je početni datum razdoblja iz kojeg želite tražiti tvitove. Ovaj početni datum trebao bi biti unutar zadnjih 7 dana. Ovo je još jedna značajka koja nije dokumentirana u dokumentaciji Twitter API-ja.
‘until’ predstavlja završni datum vašeg željenog razdoblja. Logično, također bi trebao biti unutar zadnjih 7 dana. Također nije dokumentiran u dokumentaciji Twitter API-ja.
‘result_type’ predstavlja vrstu tvitova koje želite. Ima 3 vrijednosti:
‘recent’ daje najnovije tvitove, tj. tvitove na kraju odabranog razdoblja.
‘popular’ daje najpopularnije tvitove i stoga propušta mnogo tvitova. Uvijek biste dobili tvitove s najviše favorita i retvitova. Značajka min_faves ovdje ne bi bila od koristi.
‘mixed’ daje mješavinu nedavnih i popularnih tvitova.
‘count’ predstavlja maksimalan broj tvitova u rezultatu. Zadana vrijednost je postavljena na 15, a maksimalna je 100.
S mješovitim result_type i upotrebom min_faves, možemo dobiti maksimalan broj tvitova pokretanjem upita više puta.
|
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') |
Za više dokumentiranih značajki, također možete pogledati Twitter’s API dokumentaciju.
Spremanje/Automatsko spremanje dohvaćenih podataka o tvitovima
Kao sljedeći korak, trebate definirati metodu automatskog spremanja/spremanja koja ima parametar ‘saveOverride’. Ovaj korak je jednostavno potreban kako bi se uklonilo vremensko ograničenje automatskog spremanja i spremila datoteka. Kako bih to učinio, kreiram t_last kako bih spremio vrijeme početka programa. Zatim pristupam istom u programu i provjeravam je li prošlo 5 minuta od t_last (vremena zadnjeg spremanja). Ako je prošlo više od 5 minuta, označavam ‘saveStatus’ kao True.
Zatim provjeravam ‘saveOverride’, što jednostavno znači da moram dati uputu svom programu da se datoteka mora spremiti sada, bez obzira na sve. Za to postavljam saveStatus na True.
Zatim, ako je ‘saveStatus’ True, skripta će promijeniti t_last na trenutno vrijeme. Nakon toga kod stvara objekt rječnika i ispisuje “Automatsko spremanje u [time]” kako biste znali da se podaci automatski spremaju.
Zatim provjeravam postoji li već izlazna datoteka. Ako postoji, kombiniram podatke i podatke iz već spremljene datoteke. Nakon kombiniranja, zapisujem ih u istu datoteku. Ako ne postoji, kreiram novu datoteku i zatim zapisujem podatke u tu datoteku.
|
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("Automatsko spremanje u " + 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) |
Kao rezultat toga, programirao sam gotovo cijelu funkcionalnost koju sam želio.
Daljnja optimizacija
Napokon, vrijeme je da iskoristimo ove funkcije. Pišem while(1) petlju, što znači while(True). To u osnovi omogućuje da se naredba izvodi beskonačno dok se ne pozove naredba ‘break’ ili dok se ne pojavi iznimka.
Prvo prikupljam podatke o tvitovima u rječnik ‘d’ koristeći json.loads koji pretvara podatke u format rječnika. Zatim pokrećem try-catch/except na bloku koda koji izdvaja statuse iz podataka. Koristim try-catch jer ponekad Twitter API ne vraća podatke, već JSON koji navodi pogrešku. Ne želim da se moj program zaustavi u takvim slučajevima. Također, želim da dohvati na kojem se broju zahtjeva to događa i da spremi moje Twitter podatke pomoću naredbe za automatsko spremanje. Twitter nam omogućuje 180 zahtjeva svakih 15 minuta. To je otprilike 12 zahtjeva u minuti ili jedan zahtjev svakih pet sekundi. Za svaki slučaj, dodajem naredbu sleep kako bi moj program spavao 5 sekundi nakon izvršavanja jedne iteracije.
Nakon toga, kod će prikazati broj tvitova koje je skripta do sada prikupila.
Napokon, vrijeme je za glavni trik za optimizaciju. Testirao sam ovu skriptu gotovo tjedan dana i dobio sam sljedeći broj tvitova za svaku min_faves vrijednost. Mogu dobiti najviše 100 tvitova po zahtjevu, a želim ih dobiti što je više moguće. Trenutačno nema mnogo tvitova s višim vrijednostima min_faves ali želimo uzeti u obzir trenutke kada je, možda, tvrtka ili ključna riječ u trendu. Maksimalna vrijednost min_faves može biti 999999.
| Vrijednost min_faves | Broj tvitova |
| 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 |
Stoga koristim logiku koja bi dohvatila tvitove od min_faves vrijednosti od 60000 i zatim je svaki put smanjuje za 10000 dok ne dosegne 10000. Ali ako je, recimo, ključna riječ u trendu i dobijem 100 tvitova kada radim s vrijednošću min_faves od 30000, to će povećati min_faves na 35000 i zatim ponovno dohvatiti rezultate. Dakle, sada je nova logika 5000 umjesto 10000. Međutim, ako se promjena smanji na manje od 1000, tražim da to zanemari i nastavi s oduzimanjem 1000.
Određujem fiksni interval od 1000 za koji min_faves se treba smanjiti ako je min_faves manji od ili jednak 10000.
Na kraju programa, program će vas obavijestiti da je rad završen prikazivanjem ‘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 #veliko smanjenje u min_faves za izdvajanje podataka interval = 500 #uobičajeno smanjenje u min_faves za izdvajanje podataka 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("Greška kod zahtjeva: " + str(req_count)) autosave(True) print("Kod zahtjeva: " + str(req_count) + "  Ukupno prikupljeno tweetova: " + 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") |
Cijeli kod možete pronaći na GitHub.
To je sve. U sljedećem vodiču za Twitter podatke naučit ću vas kako dohvatiti tweetove u stvarnom vremenu pomoću alata za velike podatke ‘Flume’. Ostanite s nama!
Komentari
Još nema komentara. Budite prvi.