Bruke sosiale medier til å lokalisere øyenvitner Twitter API

Dette er den andre av en todelt serie om bruk av sosiale medier for å finne øyenvitner til viktige hendelser. I del ett viste jeg deg hvordan du bruker Instagram API for å finne øyenvitner til et livevideo av Macklemores i Seattle. I denne delen bruker vi Twitter API for å finne deltakere av president Obamas tale i Selma på Edmund Pettus Bridge.

Du kan laste ned koden for begge episodene ved å bruke GitHub-repository-lenken i sidefeltet. Du kan også være interessert i min Tuts + -serie, Bygg med Twitter-API.

Twitters geosearchfunksjoner er mer begrensede og krever derfor litt mer detaljert kode å bruke. Geotagged innlegg på Twitter kan bare bli funnet fra de siste syv dagene. Og de er bare søkbare etter dato (ikke tid), så du må filtrere API-resultatene for presisjon. 

Jeg deltar i diskusjonene nedenfor. Hvis du har et spørsmål eller et emneforslag, vennligst legg inn en kommentar nedenfor. Du kan også nå meg på Twitter @ reifman eller email meg direkte. 

Hva vi dekket i første del

Telefonene vi bærer i lommene, registrerer alle våre bevegelser, deler det med celleleverandører og ofte tredjeparts programvarefirmaer der motivasjonene generelt fokuserer på profitt. 

Mange mennesker skjønner ikke at de har forlatt geotagging på sine sosiale medier apps, fullt ut publisere sin plassering med alle sosiale medier innlegg. Dette inkluderte GOP-kongressen Aaron Schock. AP brukte sin Instagram-kontoens geotags for å avsløre bruken av skattebetalers midler for ekstravagante private fly og andre luksuriøse aktiviteter. 


Så, geotagging kan brukes til gode. I denne serien undersøker vi hvordan journalister eller rettshåndhevelse kan finne potensielle øyenvitner til viktige hendelser som en forbrytelse eller ulykkesscene ved hjelp av sosiale medier.

Men geotagging kan også brukes abusively. Berkeley datavitenskapere og lærere bygget Klar eller Ikke? app for å demonstrere hvordan geotagging i Twitter og Instagram registrerer hvert eneste trekk. 

Her er Apple grunnlegger Steve Wozniaks Twitter-konto i appen:

Geotagging på Instagram og Twitter er nøyaktig nok til å tillate noen å enkelt bestemme din bolig, arbeidssted og reise rutine.

I denne episoden vil jeg veilede deg gjennom å bruke Twitter API. Jeg har gitt et GitHub-depot (lenken er i sidefeltet) for å laste ned for å prøve koden. Min "Eyewitness app" er skrevet i Yii Framework for PHP, som du kan lære mer om i min programmering med Yii2-serien for Tuts+. 

Hvis du ikke ønsker å dele posisjonen din for at offentligheten skal se - eller å forlate en historisk sti av dine reiser - Klar eller Ikke? app tilbyr koblinger og guider for å slå disse funksjonene av (se etter linken på hjemmesiden). Oppriktig, jeg har slått av meg og jeg oppfordrer deg til å gjøre det også.

Hvis du er et rettshåndhevingsbyrå eller en mediaenhet som ønsker mer informasjon, kan du gjerne kontakte meg direkte. Jeg ville også være interessert i noen vellykkede bruksområder av denne koden (for godt) - de ville lage en interessant oppfølgingshistorie.

Hva vi gjorde med Instagram

Siste episode, vi brukte Instagram API for å finne øyenvitner til Mackelmores live 2013 videoopptak for White Cadillac. Ganske enkelt klarte vi å finne Instagram-medlem Joshua Lewis foto av Macklemore som gikk ut av sitt kjøretøy (kult, va?):

Nå, la oss begynne å bruke Twitter API.

Bruk Twitter API

Som med Instagram, må du logge på Twitter-kontoen din og registrere et utviklerprogram. Du bør registrere en app slik:

Twitter vil vise deg dine søknadsdetaljer:

Her er innstillingssiden:

Her er nøklene og tilgangstokenene for søknaden. Legg merke til disse.

Deretter ruller du ned og lager tilgangsfunksjoner for kontoen din. Legg merke til disse også.

Legg alle fire konfigurasjonstastene og hemmelighetene til din /var/secure/eyew.ini fil:

mysql_host = "localhost" mysql_db = "eyew" mysql_un = "xxxxxxxxx" mysql_pwd = "xxxxxxxxxxxx" instagram_client_id = "4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx7" instagram_client_secret = "1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx4" twitter_key = "zxxxxxxxxxxxxxxxxxxxx2" twitter_secret = "4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxp" twitter_oauth_token = "1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxs" twitter_oauth_secret = "exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxV" 

Deretter oppretter vi en aktiv postflytting for å lage vår Twitter-modell. Dette lagrer tweets vi mottar fra API-anropene.

db-> drivernavn === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> createTable ('twitter', ['id' => Skjema :: TYPE_PK, 'moment_id' => Skjema :: TYPE_INTEGER. 'NOT NULL', 'tweet_id' => Skjema :: TYPE_BIGINT. 'NOT NULL', 'twitter_id' => Skjema :: TYPE_BIGINT. 'NOT NULL', 'screen_name' => Skjema :: TYPE_STRING. 'IKKE NULLVALT 0', 'text' => Skjema :: TYPE_TEXT. ' IKKE NULL ',' tweeted_at '=> Skjema :: TYPE_INTEGER.' IKKE NULL ',' created_at '=> Skjema :: TYPE_INTEGER.' NOT NULL ',' updated_at '=> Skjema :: TYPE_INTEGER.' NOT NULL ' , $ tableOptions); $ this-> addForeignKey ('fk_twitter_moment', '% twitter', 'moment_id', 'moment', 'id', 'CASCADE', 'CASCADE');  offentlig funksjon ned () $ this-> dropForeignKey ('fk_twitter_moment', '% twitter'); $ Dette-> dropTable ( '% twitter');  

Akkurat som vi gjorde i del ett, må du kjøre overføringen:

./ Yii migrere / opp Yii Migreringsverktøy (basert på Yii v2.0.3) Totalt 1 ny migrering som skal brukes: m150309_174014_create_twitter_table Bruk overføringen ovenfor? (ja | nei) nei: ja *** bruk m150309_174014_create_twitter_table> opprett bord % twitter ... ferdig (tid: 0.008s)> legg til utenlandsk nøkkel fk_twitter_moment: % twitter (moment_id) referanser  % øyeblikk (id) ... ferdig (tid: 0.007s) *** brukt m150309_174014_create_twitter_table (tid: 0.019s) Migrert opp med hell.

Deretter brukte jeg Yii2s kodegenerator, Gii, til å lage modell og CRUD-kontroller for Twitter-modellen. Hvis du får den nyeste GitHub-depotkoden ved hjelp av sidebar-koblingen på denne opplæringen, har du også koden.

Opprett et nytt øyeblikk

Fordi Twitter begrenser geolokasjonssøk i løpet av den siste uken, valgte jeg til slutt president Obamas Selma 50-årsjubileum på Edmund Pettus-broen.

Jeg brukte Google Maps igjen for å få GPS-koordinatene til broen:

Deretter skapte jeg et øyeblikk for talen å søke. Jeg oppdaterte det noen ganger for å finjustere søketes geografiske radius (det er en bro) og tidsintervallet:

Søk ved hjelp av Twitter API

Begrensningene til Twitter API er at den bare lar deg søke etter dato, f.eks. 2015-03-07, mens Instagram er indeksert av presise Unix tidsstempler. Derfor må vi begynne vår Twitter-søk en hel dag fremover og søke bakover.

Siden vi sannsynligvis vil få mange tweets utenfor vårt ønskede tidsintervall, må vi foreta gjentatte anrop til Twitter API. Twitter returnerer opptil 100 tweets per API-forespørsel, og tillater 180 forespørsler per 15-minutters vindu.

Jeg bruker James Mallisons Twitter API-bibliotek for PHP. Slik oppretter du biblioteket for å ringe:

 \ 'Yami :: $ app-> params [' twitter '] [' oauth_token '],' oauth_access_token_secret '=> \ Yii :: $ app-> params [' twitter '] [' oauth_secret '],' consumer_key '=> \ Yii :: $ app-> params ['twitter'] ['key'], 'consumer_secret' => \ Yii :: $ app-> params ['twitter'] ['hemmelig'];); // Koble til Twitter $ twitter = ny TwitterAPIExchange ($ innstillinger);

I utgangspunktet ber vi om 100 resultater fra Twitter på våre GPS koordinater til en bestemt dato. 

offentlig funksjon searchTwitter () date_default_timezone_set ('America / Los_Angeles'); Yii :: trace ('start searchTwitter' .date ('y-m-d h: m')); // Last inn Twitter-tastene dine $ settings = array ('oauth_access_token' => \ Yii :: $ app-> params ['twitter'] ['oauth_token'], 'oauth_access_token_secret' => \ Yii :: $ app-> params ['twitter'], 'consumer_key' => \ Yii :: $ app-> params ['twitter'] ['key'], 'consumer_secret' => \ Yii :: $ app-> params ['twitter'] ['hemmelig'],); // Koble til Twitter $ twitter = ny TwitterAPIExchange ($ innstillinger); // Søkeinnstillinger for søk $ url = 'https://api.twitter.com/1.1/search/tweets.json'; $ requestMethod = 'GET'; // rate grense på 180 spørringer $ limit = 180; $ QUERY_COUNTandre = 1; $ teller = 100; $ result_type = 'recent'; // beregne gyldig tidsstempelområde $ valid_start = $ this-> start_at; // $ til_date og $ valid_end = // starttid + varighet $ valid_end = $ this-> start_at + ($ this-> varighet * 60); Yii :: trace ('Gyldig rekkevidde:'. $ Valid_start. '->'. $ Valid_end); $ until_date = date ('Y-m-d', $ valid_end + (24 * 3600)); // legg til en dag $ distance_km = $ this-> avstand / 1000; // avstand i km // Ubenyttet: & siden = $ since_date // $ since_date = '2015-03-05'; // Utfør første spørring med until_date $ getfield = "? Result_type = $ result_type & geocode =". $ This-> latitude. ",". $ This-> lengdegrad. ",". $ Distance_km. "Mi & include_entities = false & til = $ til_date & count = $ count ";

Vi registrerer kun tweets innenfor vårt presise tidsrom, og ignorerer de andre resultatene. Når vi behandler disse, merker vi oss om den laveste tweet-IDen mottatt.

 $ tweets = json_decode ($ twitter-> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest ()); hvis (isset ($ tweets-> feil)) Yii :: $ app-> session-> setFlash ('error', 'Twitter Rate Limit Reached.'); Yii :: feil ($ tweets-> feil [0] -> melding); komme tilbake;  $ max_id = 0; Yii :: trace ('Count Statuses:' .count ($ tweets-> statuser)); Yii :: trace ('Max Tweet Id:'. $ Max_id); foreach ($ tweets-> statuser som $ t) // sjekk om tweet i gyldig tidsintervall $ unix_created_at = strtotime ($ t-> created_at); Yeti :: trace ('Tweet @'. $ T> created_at. ". $ Unix_created_at. ':'. $ T> bruker-> skjermnavn.". (Isset ($ t-> tekst) tekst: ")), hvis ($ unix_created_at> = $ valid_start && $ unix_created_at <= $valid_end)  // print_r($t); $i = new Twitter(); $i->legge til ($ dette-> id, $ t> id_str, $ t> bruker-> id_str, $ t> bruker-> SCREEN_NAME, $ unix_created_at, (isset ($ t> tekst)? $ t-> tekst : $); hvis ($ max_id == 0) $ max_id = intval ($ t-> id_str); annet $ max_id = min ($ max_id, intval ($ t-> id_str))

Så vi sløyfe, gjør gjentatte forespørsler til Twitter (opptil 179 ganger), og ber om ytterligere poster som er tidligere enn den forrige batchens laveste tweet-ID. Med andre ord, på etterfølgende forespørsler, i stedet for å spørre frem til en bestemt dato, spør vi om maksimalverdien av den laveste tweet-IDen som vi har mottatt.

Vi stopper når mindre enn 100 poster blir returnert eller når returnerte tweets er tidligere enn vår faktiske rekkevidde. 

Hvis du trenger tilgang til mer enn 18.000 tweets, må du implementere en bakgrunnsoppgave for å ringe Twitter API, som vi har gjort i vår andre Twitter API-serie.

Når vi behandler API-resultater, må vi filtrere tweets, bare registrere de som ligger innenfor vår faktiske starttid og sluttid.

Merk: Twitter API har mange frustrerende quirks som gjør personsøking vanskeligere enn det skal være. Ganske ofte returnerer Twitter ingen resultater uten en feilkode. Andre ganger fant jeg det å returnere et lite antall resultater, men det innebar ikke at en annen forespørsel ikke ville returnere mer. Det er ingen veldig klare måter å vite når Twitter er ferdig med å returnere resultater til deg. Det er inkonsekvent. Dermed kan du merke at koden min har noen interessante løsninger i den, f.eks. undersøke $ count_max_repeats.

 $ count_repeat_max = 0; // Utfør alle etterfølgende søk med tillegg av oppdatert maximum_tweet_id mens ($ query_count<=$limit)  $prior_max_id = $max_id; $query_count+=1; Yii::trace( 'Request #: '.$query_count); // Perform subsequent query with max_id $getfield ="?result_type=$result_type&geocode=".$this->breddegrad "" $ dette-> lengdegrad "" $ distance_km "mi & include_entities = false & max_id = $ max_id & count = $ teller".....; $ tweets = json_decode ($ twitter-> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest ()); hvis (isset ($ tweets-> feil)) Yii :: $ app-> session-> setFlash ('error', 'Twitter Rate Limit Reached.'); Yii :: feil ($ tweets-> feil [0] -> melding); komme tilbake;  // noen ganger twitter api mislykkes hvis (! isset ($ tweets-> statuses)) fortsetter; Yii :: trace ('Count Statuses:' .count ($ tweets-> statuser)); Yii :: trace ('Max Tweet Id:'. $ Max_id); foreach ($ tweets-> statuser som $ t) // sjekk om tweet i gyldig tidsintervall $ unix_created_at = strtotime ($ t-> created_at); hvis ($ unix_created_at> = $ valid_start && $ unix_created_at <= $valid_end)  $i = new Twitter(); $i->legge til ($ dette-> id, $ t> id_str, $ t> bruker-> id_str, $ t> bruker-> SCREEN_NAME, $ unix_created_at, (isset ($ t> tekst)? $ t-> tekst : ")); annet hvis ($ unix_created_at < $valid_start)  // stop querying when earlier than valid_start return;  $max_id = min($max_id,intval($t->id_str)) - 1;  hvis ($ prior_max_id - $ max_id <=1 OR count($tweets->statuser)<1)  $count_repeat_max+=1;  if ($count_repeat_max>5) // når api ikke returnerer flere resultater break;  // ende mens 

En av de første resultatene som ble returnert, inkluderte tweetet nedenfor av Fred Davenport som viser president Obama på scenen:

Her er det på Twitter:

Deretter, ettersom du blar gjennom resultatene videre, kan du finne mange flere personer som presenterer tweeting om Obama-inkludert media:

La oss nå gjøre et mer lokalt søk.

En annen, mer lokal søk

Key Arena er Seattles store konsert- og idrettsarena. Denne helga holdt de Pac-12 Women's Basketball Tournament:

La oss få våre GPS koordinater for Key Arena fra Google Maps:

Deretter opprettet jeg og tweaked et øyeblikk for å finne et lengre tidsrom for helgen av tweets:

Og her er noen av resultatene. Min favoritt er:

"Jeg vil forlate dette basketballspillet. Jeg hater basketball."

For det meste synes jeg at Instagrams API er langt sterkere enn Twitter, og gir generelt mer spennende resultater. Det er imidlertid avhengig av hvilken type person du leter etter. Hvis du bare vil identifisere folk som var der, fungerer enten API godt.

Hva vi har lært

Jeg håper du har hatt glede av denne serien. Jeg fant det fascinerende og imponert over resultatene. Og det fremhever de bekymringene vi alle bør ha om vår grad av personvern i denne sammenkoblede digitale tidsalderen.

APIene for Instagram og Twitter er begge utrolig kraftige tjenester for å finne sosiale medier brukere som var i nærheten bestemte steder på bestemte tider. Denne informasjonen kan brukes til godt og det kan bli misbrukt. Du bør nok vurdere å slå av geolocation-posteringen din - følg koblingene på Klar eller Ikke? app.

Du vil kanskje også sjekke ut byggingen min med Twitter API-serien, også på Tuts+.

Ta gjerne inn dine spørsmål og kommentarer nedenfor. Du kan også nå meg på Twitter @ reifman eller email meg direkte. Jeg vil spesielt sette pris på å høre fra journalister og rettshåndhevelse som benytter seg av disse eksemplene.

Du kan også bla gjennom min Tuts + instruktørside for å se andre opplæringsprogrammer jeg har skrevet. 

Relaterte linker

  • Twitter API
  • Instagram API
  • Klar eller ikke? (Undervisningspersonell)
  • Hvordan vi fanget savnet Wired Magazine Writer Evan Ratliff
  • Yii2 Developer Exchange