Social media gebruiken om ooggetuigen op te sporen de Twitter-API

Dit is de tweede van een tweedelige serie over het gebruik van sociale media om ooggetuigen te lokaliseren voor belangrijke gebeurtenissen. In deel een heb ik je laten zien hoe je de Instagram-API kunt gebruiken om ooggetuigen te vinden voor een live video-opname van Macklemore's in Seattle. In dit deel gebruiken we de Twitter API om deelnemers aan de speech van president Obama in Selma te vinden op de Edmund Pettus-brug.

Je kunt code voor beide afleveringen downloaden door de koppeling GitHub-repository in de zijbalk te gebruiken. Mogelijk bent u ook geïnteresseerd in mijn Tuts + -serie, Building With the Twitter API.

De geografische mogelijkheden van Twitter zijn beperkter en vereisen daarom een ​​beetje meer gedetailleerde code om te gebruiken. Geotagged berichten op Twitter zijn alleen te vinden vanaf de laatste zeven dagen. En ze kunnen alleen worden doorzocht op datum (niet op tijd), dus u moet de API-resultaten filteren op nauwkeurigheid. 

Ik neem wel deel aan de onderstaande discussies. Als je een vraag of een suggestie voor een onderwerp hebt, plaats dan een commentaar hieronder. Je kunt me ook bereiken via Twitter @reifman of mij rechtstreeks een e-mail sturen. 

Wat we in deel één behandelden

De telefoons die we in onze eigen zak hebben, registreren elke beweging en delen deze met mobiele providers en vaak met externe softwarebedrijven waarvan de motivatie meestal gericht is op winst. 

Veel mensen realiseren zich niet dat ze geotagging hebben verlaten in hun apps voor sociale media, en hun locatie volledig bekend maken met elke post op sociale media. Dit omvatte GOP Congreslid Aaron Schock. De AP gebruikte de geotags van zijn Instagram-account om zijn gebruik van belastinggeld voor extravagante privévluchten en andere luxueuze activiteiten bloot te leggen. 


Dus geotaggen kan voorgoed worden gebruikt. In deze serie onderzoeken we hoe journalisten of wetshandhavers potentiële ooggetuigen kunnen lokaliseren bij belangrijke gebeurtenissen, zoals een misdaad of een ongeluk met behulp van sociale media..

Geotags kunnen echter ook verkeerd worden gebruikt. Berkeley computerwetenschappers en opvoeders bouwden de Ready of Not? app om te laten zien hoe geocodering op Twitter en Instagram elke beweging registreren. 

Dit is het Twitter-account van Apple mede-oprichter Steve Wozniak in de app:

De geotagging op Instagram en Twitter is nauwkeurig genoeg om iemand in staat te stellen om eenvoudig je verblijf, werkplek en reisroutine te bepalen.

In deze aflevering zal ik u helpen met het gebruik van de Twitter API. Ik heb een GitHub-repository (de link staat in de zijbalk) voor je om te downloaden om de code uit te proberen. Mijn "Eyewitness-app" is geschreven in het Yii Framework voor PHP, waar je meer over kunt leren in mijn Programming With Yii2-serie voor Tuts+. 

Als u uw locatie niet wilt delen zodat het publiek een historisch spoor van uw reizen kan bekijken of verlaten, is het gereed of niet? app biedt links en handleidingen om deze functies uit te schakelen (kijk voor de link op de startpagina). Eerlijk gezegd heb ik de mijne afgewezen en ik moedig je aan om dat ook te doen.

Als u een wetshandhavingsinstantie of een media-entiteit bent die meer informatie wenst, kunt u contact met mij opnemen. Ik zou ook geïnteresseerd zijn in een succesvol gebruik van deze code (ten goede) - ze zouden een interessant vervolgverhaal maken.

Wat we deden met Instagram

In de laatste aflevering hebben we de Instagram-API gebruikt om ooggetuigen te vinden voor de live video-opnames van Mackelmore in 2013 voor White Cadillac. Heel gemakkelijk, we zijn erin geslaagd om de foto van Instagramlid Joshua Lewis te vinden van Macklemore die uit zijn voertuig stapte (cool, hè?):

Laten we nu aan de slag gaan met de Twitter API.

De Twitter API gebruiken

Net als bij Instagram moet je je aanmelden bij je Twitter-account en een ontwikkelaarstoepassing registreren. U moet een app als deze registreren:

Twitter toont u uw applicatiegegevens:

Dit is de instellingenpagina:

Hier zijn de sleutels en toegangstokens voor de toepassing. Noteer deze.

Blader vervolgens naar beneden en maak toegangstokens voor je account. Noteer deze ook.

Voeg alle vier deze configuratiesleutels en geheimen aan uw toe /var/secure/eyew.ini het dossier:

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" 

Vervolgens maken we een Active Record-migratie om ons Twitter-model te maken. Hiermee worden de tweets opgeslagen die we ontvangen van de API-aanroepen.

db-> driverName === 'mysql') $ tableOptions = 'KARAKTER 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. 'NOT NULL DEFAULT 0', 'text' => Schema :: TYPE_TEXT. ' NOT NULL ',' tweeted_at '=> Schema :: TYPE_INTEGER.' NOT 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');  public function down () $ this-> dropForeignKey ('fk_twitter_moment', '% twitter'); $ This-> dropTable ( '% twitter');  

Net zoals we in deel één hebben gedaan, moet u de migratie uitvoeren:

./ yii migreer / up Yii Migration Tool (gebaseerd op Yii v2.0.3) Totaal 1 nieuwe migratie die moet worden toegepast: m150309_174014_create_twitter_table Pas de bovenstaande migratie toe? (yes | no) [nee]: yes *** apply m150309_174014_create_twitter_table> create table % twitter ... done (time: 0.008s)> voeg buitenlandse sleutel toe fk_twitter_moment: % twitter (moment_id) references  % moment (id) ... klaar (tijd: 0.007s) *** toegepast m150309_174014_create_twitter_table (tijd: 0.019s) Migratie succesvol uitgevoerd.

Vervolgens gebruikte ik de codegenerator van Yii2, Gii, om het model en de CRUD-controllers voor het Twitter-model te maken. Als je de nieuwste GitHub-repositorycode hebt met behulp van de zijbalklink in deze tutorial, heb je de code ook.

Maak een nieuw moment

Omdat Twitter de geolocatie-zoekopdrachten beperkt tot de afgelopen week, heb ik uiteindelijk de Selma 50-jarig jubileumrede van president Obama op de Edmund Pettus-brug gekozen.

Ik heb Google Maps opnieuw gebruikt om de GPS-coördinaten voor de brug te krijgen:

Vervolgens maakte ik een moment voor de spraak om te zoeken. Ik heb het een paar keer bijgewerkt om de geografische straal van de zoekopdracht (het is een brug) en het tijdbereik aan te passen:

Zoeken met behulp van de Twitter API

De beperkingen van de Twitter-API zijn dat u alleen op datum kunt zoeken, bijvoorbeeld 2015-03-07, terwijl Instagram wordt geïndexeerd door precieze Unix-tijdstempels. Daarom moeten we onze Twitter-zoekopdracht een volledige dag vooruit beginnen en achteruit zoeken.

Aangezien we waarschijnlijk veel tweets buiten het door ons gewenste tijdbereik krijgen, moeten we herhaaldelijk naar de Twitter API bellen. Twitter retourneert maximaal 100 tweets per API-aanvraag en biedt 180 verzoeken per kwartier.

Ik gebruik de Twitter API-bibliotheek van James Mallison voor PHP. Zo stellen we de bibliotheek in om te bellen:

 \ 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'] ['geheim'],); // Maak verbinding met Twitter $ twitter = nieuwe TwitterAPIExchange ($ settings);

In eerste instantie vragen we 100 resultaten van Twitter op onze GPS-coördinaten tot een specifieke datum. 

publieke functie searchTwitter () date_default_timezone_set ('America / Los_Angeles'); Yii :: trace ('start searchTwitter' .date ('y-m-d h: m')); // Laad je Twitter-applicatiesleutels $ settings = array ('oauth_access_token' => \ 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'] ['geheim'],); // Maak verbinding met Twitter $ twitter = nieuwe TwitterAPIExchange ($ settings); // Zoekopdrachtinstellingen voor zoeken $ url = 'https://api.twitter.com/1.1/search/tweets.json'; $ requestMethod = 'GET'; // snelheidslimiet van 180 zoekopdrachten $ limiet = 180; $ Query_count = 1; $ count = 100; $ result_type = 'recent'; // bereken geldig tijdstempelbereik $ valid_start = $ this-> start_at; // $ until_date and $ valid_end = // starttijd + duur $ valid_end = $ this-> start_at + ($ this-> duration * 60); Yii :: trace ('Geldig bereik:'. $ Valid_start. '->'. $ Valid_end); $ until_date = date ('Y-m-d', $ valid_end + (24 * 3600)); // voeg een dag $ distance_km = $ this-> distance / 1000 toe; // afstand in km // Niet gebruikt: & since = $ since_date // $ since_date = '2015-03-05'; // Voer de eerste query uit met until_date $ getfield = "? Result_type = $ result_type & geocode =". $ This-> latitude. ",". $ This-> longitude. ",". $ Distance_km. "Mi & include_entities = false & until = $ until_date & count = $ count ";

We nemen alleen tweets op binnen ons precieze tijdsbereik en negeren de andere resultaten. Terwijl we deze verwerken, noteren we de laagste tweet-ID die is ontvangen.

 $ tweets = json_decode ($ twitter-> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest ()); if (isset ($ tweets-> errors)) Yii :: $ app-> session-> setFlash ('error', 'Twitter Rate Limit Reached.'); Yii :: fout ($ tweets-> fouten [0] -> bericht); terug te keren;  $ max_id = 0; Yii :: trace ('Telstatussen:' .count ($ tweets-> statussen)); Yii :: trace ('Max tweet ID:'. $ Max_id); foreach ($ tweets-> statussen als $ t) // controleer of tweet binnen geldig tijdsbereik $ unix_created_at = strtotime ($ t-> created_at); Yii :: trace ('Tweet @'. $ T-> created_at. ". $ Unix_created_at. ':'. $ T-> user-> screen_name.". (Isset ($ t-> text)? $ T-> text: ")); if ($ unix_created_at> = $ valid_start && $ unix_created_at <= $valid_end)  // print_r($t); $i = new Twitter(); $i->toe te voegen ($ this-> id, $ t-> id_str, $ t-> gebruikers-> id_str, $ t-> gebruikers-> screen_name, $ unix_created_at, (isset ($ t-> tekst)? $ t-> text : ")); if ($ max_id == 0) $ max_id = intval ($ t-> id_str); else $ max_id = min ($ max_id, intval ($ t-> id_str));

Vervolgens lussen we en maken we herhaalde verzoeken aan Twitter (tot 179 keer meer), waarbij we om aanvullende records verzoeken die ouder zijn dan de laagste tweet-ID van de vorige batch. Met andere woorden, bij volgende aanvragen, in plaats van het opvragen van een specifieke datum, vragen we naar de max_id van de laagste tweet-ID die we hebben ontvangen.

We stoppen wanneer minder dan 100 records worden geretourneerd of wanneer geretourneerde tweets eerder zijn dan ons werkelijke bereik. 

Als u toegang tot meer dan 18.000 tweets nodig heeft, moet u een achtergrondtaak implementeren om de Twitter API te bellen, zoals we hebben gedaan in onze andere Twitter API-reeks.

Terwijl we API-resultaten verwerken, moeten we tweets filteren, alleen die tweeten die binnen onze werkelijke start- en eindtijd vallen.

Opmerking: de Twitter-API heeft veel frustrerende eigenaardigheden die paging moeilijker maken dan zou moeten. Heel vaak levert Twitter geen resultaten op zonder een foutcode. Andere keren vond ik dat het een klein aantal resultaten opleverde, maar dat betekende niet dat een ander verzoek niet meer zou terugkeren. Er zijn geen duidelijke manieren om te weten wanneer Twitter klaar is en de resultaten naar u worden geretourneerd. Het is inconsistent. U ziet dus dat mijn code een aantal interessante oplossingen bevat, bijvoorbeeld onderzoeken $ count_max_repeats.

 $ count_repeat_max = 0; // Voer alle volgende query's uit met toevoeging van bijgewerkte maximum_tweet_id terwijl ($ 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->breedtegraad "" $ this-> lengte "" $ distance_km "mi & include_entities = false & max_id = $ max_id & count = $ count".....; $ tweets = json_decode ($ twitter-> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest ()); if (isset ($ tweets-> errors)) Yii :: $ app-> session-> setFlash ('error', 'Twitter Rate Limit Reached.'); Yii :: fout ($ tweets-> fouten [0] -> bericht); terug te keren;  // soms faalt twitter api als (! isset ($ tweets-> statussen)) doorgaan; Yii :: trace ('Telstatussen:' .count ($ tweets-> statussen)); Yii :: trace ('Max tweet ID:'. $ Max_id); foreach ($ tweets-> statussen als $ t) // controleer of tweet binnen geldig tijdsbereik $ unix_created_at = strtotime ($ t-> created_at); if ($ unix_created_at> = $ valid_start && $ unix_created_at <= $valid_end)  $i = new Twitter(); $i->toe te voegen ($ this-> id, $ t-> id_str, $ t-> gebruikers-> id_str, $ t-> gebruikers-> screen_name, $ unix_created_at, (isset ($ t-> tekst)? $ t-> text : ")); else if ($ unix_created_at < $valid_start)  // stop querying when earlier than valid_start return;  $max_id = min($max_id,intval($t->id_str)) - 1;  if ($ previous_max_id - $ max_id <=1 OR count($tweets->statussen)<1)  $count_repeat_max+=1;  if ($count_repeat_max>5) // wanneer de api niet meer resultaten teruggeeft;  // einde terwijl 

Een van de eerste resultaten die werden geretourneerd, was de tweet hieronder door Fred Davenport die president Obama op het podium liet zien:

Hier is het op Twitter:

Als u vervolgens verder bladert over de resultaten, kunt u veel meer mensen vinden die tweeten over Obama, inclusief de media:

Laten we nu een meer lokale zoekopdracht uitvoeren.

Een tweede, meer lokale zoekopdracht

Key Arena is de grote concert- en sportarena van Seattle. Afgelopen weekend hielden ze het Pac-12 Women's Basketball Tournament:

Laten we onze GPS-coördinaten voor Key Arena ophalen op Google Maps:

Vervolgens heb ik een moment gemaakt en aangepast om een ​​langere periode te vinden voor het weekend tweets:

En, hier zijn enkele resultaten. Mijn favoriet is:

"Ik wil dit basketbalspel verlaten, ik haat basketbal."

Voor het grootste deel lijkt het erop dat de API van Instagram veel krachtiger is dan Twitter en over het algemeen intrigerende resultaten oplevert. Het hangt echter af van het soort persoon dat u zoekt. Als u alleen mensen wilt identificeren die er waren, werkt beide API goed.

Wat we hebben geleerd

Ik hoop dat je deze serie leuk vond. Ik vond het fascinerend en was onder de indruk van de resultaten. En het benadrukt de zorgen die we allemaal zouden moeten hebben over ons niveau van privacy in dit onderling verbonden digitale tijdperk.

De API's voor Instagram en Twitter zijn beide ongelooflijk krachtige services voor het vinden van gebruikers van sociale media die op bepaalde tijden in de buurt waren van bepaalde plaatsen. Deze informatie kan voorgoed worden gebruikt en kan worden misbruikt. Overweeg om uw geolocatie-posting uit te schakelen - volg de links bij Ready of Not? app.

Je kunt ook mijn Building With the Twitter API-serie bekijken, ook op Tuts+.

Aarzel niet om uw vragen en opmerkingen hieronder te plaatsen. Je kunt me ook bereiken via Twitter @reifman of mij rechtstreeks een e-mail sturen. Ik zou vooral het op prijs stellen van journalisten en wetshandhavers die van deze voorbeelden gebruik maken, op prijs stellen.

Je kunt ook bladeren door mijn Tuts + instructeur-pagina om andere tutorials te bekijken die ik heb geschreven. 

Gerelateerde Links

  • De Twitter API
  • De Instagram-API
  • Zelfs als je niet klaar bent? (Privacy onderwijzen)
  • How We Caught Missing Wired Magazine Writer Evan Ratliff
  • Yii2 Developer Exchange