Använda sociala medier för att lokalisera ögonvittnen Twitter API

Det här är den andra i tvådelade serier om att använda sociala medier för att lokalisera ögonvittnen till viktiga händelser. I del ett visade jag dig hur du använder Instagram API för att hitta ögonvittnen till en levande videospel av Macklemores i Seattle. I den här delen använder vi Twitter API för att hitta deltagare av president Obamas tal i Selma vid Edmund Pettus Bridge.

Du kan ladda ner koden för båda episoderna genom att använda länk GitHub-arkivet i sidofältet. Du kanske också är intresserad av min Tuts + -serie, Bygg med Twitter-API.

Twitters geosearchfunktioner är mer begränsade och kräver därför lite mer detaljerad kod att använda. Geotagged inlägg på Twitter kan bara hittas från de senaste sju dagarna. Och de är bara sökbara efter datum (inte tid), så du måste filtrera API-resultaten för precision. 

Jag deltar i diskussionerna nedan. Om du har en fråga eller ett ämnesförslag, vänligen skriv en kommentar nedan. Du kan också nå mig på Twitter @ reifman eller maila mig direkt. 

Vad vi täckte i första delen

De telefoner som vi bär i våra fickor registrerar alla våra drag, dela den med cellleverantörer och ofta programvaruföretag från tredje part vars motivation i allmänhet fokuserar på vinst. 

Många människor inser inte att de har lämnat geotagging på sina sociala medier, fullt ut publicerar sin plats med varje social media post. Detta inkluderade GOP-kongressen Aaron Schock. AP tillämpade hans Instagram-kontoens geotags för att avslöja sin användning av skattebetalarnas medel för extravaganta privata flygningar och andra lyxiga aktiviteter. 


Så, geotagging kan användas för gott. I denna serie utforskar vi hur journalister eller brottsbekämpning kan hitta potentiella ögonvittnen till viktiga händelser som ett brott eller olycksplats med sociala medier.

Geotagging kan dock också användas abusively. Berkeley datavetenskapare och lärare byggde redo eller inte? app för att visa hur geotagning i Twitter och Instagram spelar in alla våra drag. 

Här är Apple grundare Steve Wozniaks Twitter konto i appen:

Geotagging på Instagram och Twitter är tillräckligt exakt för att någon lätt ska kunna bestämma din bostad, arbetsplats och resrutiner.

I det här avsnittet guidar jag dig genom att använda Twitter API. Jag har gett ett GitHub-arkiv (länken finns i sidofältet) för att du ska ladda ner för att prova koden. Mitt "Eyewitness app" är skrivet i Yii Framework for PHP, som du kan lära dig mer om i min programmering med Yii2-serien för Tuts+. 

Om du inte vill dela din plats för allmänheten att se - eller att lämna ett historiskt spår av dina resor - Ready or Not? app erbjuder länkar och guider för att stänga av dessa funktioner (leta efter länken på sin hemsida). Uppriktigt sagt, jag har stängt av och jag uppmuntrar dig att göra det också.

Om du är en brottsbekämpande myndighet eller medieföretag som vill ha mer information, var god kontakta mig direkt. Jag skulle också vara intresserad av några framgångsrika användningar av denna kod (för gott) -de göra en intressant uppföljningsberättelse.

Vad vi gjorde med Instagram

Förra avsnittet använde vi Instagram API för att hitta ögonvittnen till Mackelmores live 2013-videospel för White Cadillac. Helt enkelt lyckades vi hitta Instagram-medlem Joshua Lewis foto av Macklemore som gick ut ur sitt fordon (coolt va?):

Nu, låt oss börja använda Twitter API.

Använda Twitter API

Precis som med Instagram måste du logga in på ditt Twitter-konto och registrera ett utvecklingsprogram. Du bör registrera en app så här:

Twitter kommer att visa dig dina ansökningsuppgifter:

Här är inställningssidan:

Här är nycklarna och åtkomsttoken för ansökan. Notera dessa.

Bläddra sedan ner och skapa access tokens för ditt konto. Notera dessa också.

Lägg till alla fyra konfigurationsnycklarna och hemligheterna till 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" 

Då skapar vi en migrerad aktiv post för att skapa vår Twitter-modell. Detta lagrar de tweets vi mottar från API-samtal.

db-> drivrutinName === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> createTable ('twitter', ['id' => Schema :: TYPE_PK, 'moment_id' => Schema :: TYPE_INTEGER. 'NOT NULL', 'tweet_id' => Schema :: TYPE_BIGINT. 'NOT NULL', 'twitter_id' => Schema :: TYPE_BIGINT. 'NOT NULL', 'screen_name' => Schema :: TYPE_STRING. 'INTE NULLSTÄLLD 0', 'text' => Schema :: TYPE_TEXT. NOT NULL ',' tweeted_at '=> Schema :: TYPE_INTEGER.' INTE NULL ',' created_at '=> Schema :: TYPE_INTEGER.' NOT NULL ',' updated_at '=> Schema :: TYPE_INTEGER.' NOT NULL ' , $ tableOptions); $ this-> addForeignKey ("fk_twitter_moment", "twitter", "moment_id", "moment", "id", "CASCADE", "CASCADE");  Offentlig funktion ner () $ this-> dropForeignKey ('fk_twitter_moment', '% twitter'); $ This-> dropTable ( '% twitter');  

Precis som vi gjorde i del ett måste du köra migreringen:

./ yii migrera / uppåt Yii Migrationsverktyg (baserat på Yii v2.0.3) Totalt 1 ny migration som ska tillämpas: m150309_174014_create_twitter_table Använd ovanstående migrering? (ja) nej: ja *** tillämpa m150309_174014_create_twitter_table> skapa tabell % twitter ... gjort (tid: 0.008s)> lägg till främmande nyckel fk_twitter_moment: % twitter (moment_id) referenser  % moment (id) ... gjort (tid: 0.007s) *** tillämpas m150309_174014_create_twitter_table (tid: 0.019s) Migrerad framgångsrikt.

Sedan använde jag Yii2s kodgenerator, Gii, för att skapa modell och CRUD-kontroller för Twitter-modellen. Om du får den senaste GitHub-arkivkoden med hjälp av sidofältet i denna handledning har du också koden.

Skapa en ny stund

Eftersom Twitter begränsar geolokationssökningar under den senaste veckan valde jag så småningom president Obamas Selma 50-årsjubileums tal vid Edmund Pettus-bron.

Jag använde Google Maps igen för att få GPS-koordinaterna för bron:

Sedan skapade jag en stund för talet att söka. Jag uppdaterade det några gånger för att finjustera sökens geografiska radie (det är en bro) och tidsintervallet:

Sök med hjälp av Twitter API

Gränserna för Twitter API är att det bara låter dig söka efter datum, t.ex. 2015-03-07, medan Instagram indexeras av exakta Unix tidsstämplar. Därför måste vi börja vår Twitter-sökning en hel dag framåt och söka bakåt.

Eftersom vi sannolikt kommer att få många tweets utanför vårt önskade tidsintervall måste vi göra upprepade samtal till Twitter API. Twitter returnerar upp till 100 tweets per API-begäran och tillåter 180 förfrågningar per 15-minuters fönster.

Jag använder James Mallisons Twitter API-bibliotek för PHP. Så här skapar vi biblioteket för att ringa:

 \ Yii :: $ 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'] ['hemlighet']; // Anslut till Twitter $ twitter = ny TwitterAPIExchange ($ inställningar);

Ursprungligen begär vi 100 resultat från Twitter på våra GPS-koordinater upp till ett visst datum. 

allmän funktion searchTwitter () date_default_timezone_set ('America / Los_Angeles'); Yii :: spår ('start searchTwitter' .date ('y-m-d h: m')); // Ladda dina Twitter-applikationsknappar $ 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'] ['secret'],); // Anslut till Twitter $ twitter = ny TwitterAPIExchange ($ inställningar); // Fråga inställningar för sökning $ url = 'https://api.twitter.com/1.1/search/tweets.json'; $ requestMethod = 'GET'; // betygsgräns på 180 frågor $ limit = 180; $ Query_count = 1; $ count = 100; $ result_type = 'recent'; // beräkna giltigt tidsstämpelområde $ valid_start = $ this-> start_at; // $ till_datum och $ valid_end = // starttid + varaktighet $ valid_end = $ this-> start_at + ($ this-> duration * 60); Yii :: spår ('Giltigt område:'. $ Valid_start. '->'. $ Valid_end); $ till_datum = datum ('Y-m-d', $ valid_end + (24 * 3600)); // lägg till en dag $ distance_km = $ this-> distance / 1000; // avstånd i km // Oanvänd: & sedan = $ since_date // $ since_date = '2015-03-05'; // Utför första fråga med till_datum $ getfield = "? Result_type = $ result_type & geocode =". $ This-> latitude. ",". $ This-> longitude. ",". $ Distance_km. "Mi & include_entities = false & till = $ till_datum och count = $ count ";

Vi registrerar bara tweets inom vårt exakta tidsintervall och ignorerar de andra resultaten. När vi behandlar dessa noterar vi det lägsta tweet-ID som tagits emot.

 $ tweets = json_decode ($ twitter-> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest ()); om (isset ($ tweets-> fel)) Yii :: $ app-> session-> setFlash ('error', 'Twitter Rate Limit Reached'); Yii :: fel ($ tweets-> fel [0] -> meddelande); lämna tillbaka;  $ max_id = 0; Yii :: trace ('Count Statuses:' .count ($ tweets-> statuser)); Yii :: spår ('Max Tweet Id:'. $ Max_id); foreach ($ tweets-> statuser som $ t) // kolla om tweet i giltigt tidsintervall $ unix_created_at = strtotime ($ t-> created_at); Yii :: trace ('Tweet @'. $ T> created_at. ". $ Unix_created_at. ':'. $ T> user-> screen_name.". (Isset ($ t-> text) text: ")), om ($ unix_created_at> = $ valid_start && $ unix_created_at <= $valid_end)  // print_r($t); $i = new Twitter(); $i->lägga ($ this-> id, $ t-> id_str, $ t-> user-> id_str, $ t-> user-> SCREEN_NAME, $ unix_created_at (isset ($ t-> text)? $ t-> text : $); om $ max_id == 0) $ max_id = intval ($ t-> id_str); annat $ max_id = min ($ max_id, intval ($ t-> id_str))

Sedan gick vi och gjorde upprepade förfrågningar till Twitter (upp till 179 gånger), och begärde ytterligare poster som är tidigare än föregående partiets lägsta tweet-ID. Med andra ord, i efterföljande förfrågningar, i stället för att fråga fram till ett visst datum, frågar vi till max_id av det lägsta tweet-ID som vi fått.

Vi slutar när mindre än 100 poster returneras eller när återvände tweets är tidigare än vårt faktiska sortiment. 

Om du behöver tillgång till mer än 18 000 tweets måste du implementera en bakgrundsuppgift för att ringa Twitter API, som vi gjort i vår andra Twitter API-serie.

När vi bearbetar API-resultat måste vi filtrera tweets, bara inspelning de som faller inom vår faktiska starttid och sluttid.

Obs! Twitter API har många frustrerande quirks som gör sökningen svårare än det borde vara. Ofta returnerar Twitter inga resultat utan en felkod. Andra gånger fann jag att det återvände ett litet antal resultat, men det innebar inte att en annan förfrågan inte skulle återvända mer. Det finns inga väldigt tydliga sätt att veta när Twitter är klar och ger resultat till dig. Det är inkonsekvent. Således kan du märka att min kod har några intressanta lösningar i den, t.ex. granska $ count_max_repeats.

 $ count_repeat_max = 0; // Utför alla efterföljande frågor med tillägg av uppdaterad maximum_tweet_id medan ($ 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->latitud "" $ this-> longitud "" $ distance_km "mi & include_entities = false & max_id = $ max_id & räkna = count $"..... $ tweets = json_decode ($ twitter-> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest ()); om (isset ($ tweets-> fel)) Yii :: $ app-> session-> setFlash ('error', 'Twitter Rate Limit Reached'); Yii :: fel ($ tweets-> fel [0] -> meddelande); lämna tillbaka;  // Ibland misslyckas api misslyckas om (! isset ($ tweets-> statuses)) fortsätt; Yii :: trace ('Count Statuses:' .count ($ tweets-> statuser)); Yii :: spår ('Max Tweet Id:'. $ Max_id); foreach ($ tweets-> statuser som $ t) // kolla om tweet i giltigt tidsintervall $ unix_created_at = strtotime ($ t-> created_at); om ($ unix_created_at> = $ valid_start && $ unix_created_at <= $valid_end)  $i = new Twitter(); $i->lägga ($ this-> id, $ t-> id_str, $ t-> user-> id_str, $ t-> user-> SCREEN_NAME, $ unix_created_at (isset ($ t-> text)? $ t-> text : ")); annars om ($ unix_created_at < $valid_start)  // stop querying when earlier than valid_start return;  $max_id = min($max_id,intval($t->id_str)) - 1;  om ($ prior_max_id - $ max_id <=1 OR count($tweets->statusar)<1)  $count_repeat_max+=1;  if ($count_repeat_max>5) // när api inte returnerar fler resultat bryta;  // slutet medan 

Ett av de första resultaten återvände inkluderade tweet nedan av Fred Davenport som visar president Obama på scenen:

Här är det på Twitter:

Då, som du bläddra i resultaten vidare, kan du hitta många fler människor närvarande tweeting om Obama-inklusive media:

Nu, låt oss göra en mer lokal sökning.

En andra, mer lokal sökning

Key Arena är Seattles stora konserthus och idrottsarena. Den här helgen höll de Pac-12 Women's Basketball Tournament:

Låt oss få våra GPS-koordinater för Key Arena från Google Maps:

Sedan skapade jag och tweaked ett ögonblick för att hitta ett längre tidsintervall för helgen av tweets:

Och här är några av resultaten. Min favorit är:

"Jag vill lämna detta basketspel. Jag hatar basket."

För det mesta verkar det som om Instagrams API är mycket kraftfullare än Twitter och ger generellt mer spännande resultat. Det beror dock på vilken typ av person du letar efter. Om du bara vill identifiera personer som var där, fungerar antingen API bra.

Vad vi har läst

Jag hoppas att du har haft den här serien. Jag tyckte det var fascinerande och imponerad av resultaten. Och det lyfter fram de oro som vi alla bör ha om vår nivå av integritet i denna sammanlänkade digitala tidsålder.

API: erna för Instagram och Twitter är båda otroligt effektiva tjänster för att hitta sociala medier som var på vissa platser vid vissa tillfällen. Denna information kan användas för gott och det kan missbrukas. Du bör noga överväga att stänga av din geolocation-postning - följ länkarna på Ready or Not? app.

Du kanske också vill kolla in min byggnad med Twitter API-serien, även på Tuts+.

Var snäll och posta dina frågor och kommentarer nedan. Du kan också nå mig på Twitter @ reifman eller maila mig direkt. Jag skulle särskilt uppskatta att höra från journalister och brottsbekämpning som använder sig av dessa exempel.

Du kan även bläddra i min Tuts + instruktörssida för att se andra handledning som jag har skrivit. 

relaterade länkar

  • Twitter API
  • Instagram API
  • Redo eller inte? (Undervisningssäkerhet)
  • Hur vi föll saknade Wired Magazine Writer Evan Ratliff
  • Yii2 Developer Exchange