Статьи

Использование социальных сетей для поиска очевидцев: API Twitter

Чириканье о президенте Обаме, выходящем на сцену в Сельме

Это вторая из двух частей серии об использовании социальных сетей для поиска свидетелей важных событий. В первой части я показал вам, как использовать API Instagram, чтобы найти очевидцев для прямой видеосъемки «Макклемора» в Сиэтле. В этой части мы будем использовать API Twitter, чтобы найти участников выступления президента Обамы в Сельме на мосту Эдмунда Петтуса.

Вы можете скачать код для обоих эпизодов, используя ссылку на репозиторий GitHub на боковой панели. Вы также можете быть заинтересованы в моей серии Tuts +, Создание с помощью API Twitter .

Возможности Twitter для геоисследований более ограничены, и поэтому для их использования требуется более подробный код. Сообщения с геотегами в Twitter можно найти только за последние семь дней. И они доступны только для поиска по дате (а не по времени), поэтому вам нужно отфильтровать результаты API для точности.

Я участвую в обсуждениях ниже. Если у вас есть вопрос или предложение по теме, пожалуйста, оставьте комментарий ниже. Вы также можете связаться со мной в Twitter @reifman или написать мне напрямую.

Телефоны, которые мы носим в наших карманах, записывают каждый наш шаг, делясь им с сотовыми провайдерами и часто сторонними компаниями-разработчиками программного обеспечения, мотивация которых, как правило, фокусируется на прибыли.

Многие люди не понимают, что они оставили геотеги в своих приложениях для социальных сетей, полностью публикуя информацию о своем местоположении в каждой публикации в социальных сетях. Это включало конгрессмена Республиканской партии Аарона Шока. AP использовал геотеги своего аккаунта в Instagram, чтобы разоблачить использование средств налогоплательщиков для экстравагантных частных перелетов и других роскошных мероприятий.

Конгрессмен Аарон Шок в Южной Америке

Таким образом, геотеггинг может быть использован навсегда. В этой серии мы исследуем, как журналисты или правоохранительные органы могут найти потенциальных свидетелей важных событий, таких как место преступления или происшествия, с помощью социальных сетей.

Тем не менее, геотеггинг также может быть использован неправомерно. Компьютерные ученые и преподаватели из Беркли построили Готово или Нет? приложение, чтобы продемонстрировать, как геотеггинг в Twitter и Instagram записывают каждый наш шаг.

Вот аккаунт соучредителя Apple Стива Возняка в Твиттере в приложении:

Готов или нет приложение Стив Возняк Twitter История геолокации

Географические метки в Instagram и Twitter достаточно точны, чтобы кто-то мог легко определить ваше место жительства, место работы и рутину путешествия.

В этом эпизоде ​​я проведу вас через API Twitter. Я предоставил вам GitHub-репозиторий (ссылка находится на боковой панели), чтобы вы могли загрузить его, чтобы опробовать код. Мое «приложение для свидетелей» написано в Yii Framework для PHP , о котором вы можете узнать больше в моей серии «Программирование с Yii2 для Tuts +».

Если вы не хотите делиться своим местоположением с общественностью, чтобы увидеть — или оставить исторический след ваших путешествий — Готов или нет? Приложение предлагает ссылки и руководства по отключению этих функций (ищите ссылку на своей домашней странице). Честно говоря, я выключил свою, и я призываю вас сделать это тоже.

Если вы являетесь сотрудником правоохранительных органов или СМИ, и вам нужна дополнительная информация, свяжитесь со мной напрямую . Я также был бы заинтересован в любом успешном использовании этого кода (навсегда) — они сделали бы интересную последующую историю.

В последнем эпизоде ​​мы использовали API Instagram, чтобы найти свидетелей прямой видеосъемки Mackelmore 2013 года для White Cadillac. Довольно легко, нам удалось найти фотографию участника Джошуа Льюиса в Instagram, когда Макклмор выходил из своего автомобиля (круто, а?):

Маклмор прибыл, найденный с Instagram API

Теперь давайте начнем использовать API Twitter.

Как и в Instagram, вам необходимо войти в свою учетную запись Twitter и зарегистрировать приложение для разработчиков . Вы должны зарегистрировать приложение, как это:

Регистрация приложения в Twitter

Twitter покажет вам детали вашего приложения:

Подробная информация очевидца приложения Twitter

Вот страница настроек:

Детали приложения Twitter

Вот ключи и токены доступа для приложения. Запишите это.

Ключи приложений Twitter и токены доступа

Затем прокрутите вниз и создайте токены доступа для своей учетной записи. Запишите это тоже.

Жетоны доступа к учетной записи приложения Twitter

Добавьте все четыре из этих ключей и секретов конфигурации в ваш файл /var/secure/eyew.ini :

01
02
03
04
05
06
07
08
09
10
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»

Затем мы создадим миграцию Active Record для создания нашей модели Twitter. Это будет хранить твиты, которые мы получаем от вызовов API.

01
02
03
04
05
06
07
08
09
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
<?php
 
use yii\db\Schema;
use yii\db\Migration;
 
class m150309_174014_create_twitter_table extends Migration
{
    public function up()
    {
          $tableOptions = null;
          if ($this->db->driverName === ‘mysql’) {
              $tableOptions = ‘CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB’;
          }
 
          $this->createTable(‘{{%twitter}}’, [
              ‘id’ => Schema::TYPE_PK,
              ‘moment_id’ => Schema::TYPE_INTEGER .
              ‘tweet_id’ => Schema::TYPE_BIGINT .
              ‘twitter_id’ => Schema::TYPE_BIGINT .
              ‘screen_name’ => Schema::TYPE_STRING .
              ‘text’ => Schema::TYPE_TEXT .
              ‘tweeted_at’ => Schema::TYPE_INTEGER .
              ‘created_at’ => Schema::TYPE_INTEGER .
              ‘updated_at’ => Schema::TYPE_INTEGER .
          ], $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}}’);
    }
}

Как и в первой части , вам нужно запустить миграцию:

01
02
03
04
05
06
07
08
09
10
11
12
13
./yii migrate/up
Yii Migration Tool (based on Yii v2.0.3)
 
Total 1 new migration to be applied:
    m150309_174014_create_twitter_table
 
Apply the above migration?
*** applying m150309_174014_create_twitter_table
    > create table {{%twitter}} … done (time: 0.008s)
    > add foreign key fk_twitter_moment: {{%twitter}} (moment_id) references {{%moment}} (id) … done (time: 0.007s)
*** applied m150309_174014_create_twitter_table (time: 0.019s)
 
Migrated up successfully.

Затем я использовал генератор кода Yii2, Gii, для создания модели и контроллеров CRUD для модели Twitter. Если вы получите последний код репозитория GitHub, используя ссылку на боковую панель в этом руководстве, у вас также будет этот код.

Поскольку Твиттер ограничивает поиск геолокации на прошлой неделе, я в конечном итоге выбрал речь президента Обамы, посвященную 50-летию Сельмы, у моста Эдмунда Петтуса .

Я снова использовал Google Maps, чтобы получить координаты GPS для моста:

Мост Эдмунда Петтуса Сельма Алабама Геолокация

Затем я создал момент для речи для поиска. Я обновил его несколько раз, чтобы настроить географический радиус поиска (это мост) и временной диапазон:

Мост Эдмунда Петтуса Момент геолокации Сельма Алабама

Ограничения API Twitter состоят в том, что он позволяет выполнять поиск только по дате, например, 2015-03-07, тогда как Instagram индексируется по точным временным меткам Unix. Поэтому мы должны начать наш поиск в Твиттере на целый день вперед и искать в обратном направлении.

Поскольку мы, вероятно, получим много твитов за пределами желаемого диапазона времени, нам придется совершать повторные звонки в Twitter API. Twitter возвращает до 100 твитов на запрос API и разрешает 180 запросов за 15-минутное окно.

Я использую библиотеку Twitter API Джеймса Маллисона для PHP . Вот как мы настроили библиотеку для звонков:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
 
namespace app\models;
 
use Yii;
use yii\db\ActiveRecord;
use app\models\Gram;
use Instagram;
use TwitterAPIExchange;
 
 
public function searchTwitter() {
   date_default_timezone_set(‘America/Los_Angeles’);
   Yii::trace(‘start searchTwitter ‘.date(‘ymd h:m ‘));
   // Load your Twitter application keys
   $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’][‘secret’],
   );
   // Connect to Twitter
   $twitter = new TwitterAPIExchange($settings);

Первоначально мы запрашиваем 100 результатов из Twitter по нашим GPS-координатам до определенной даты.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public function searchTwitter() {
  date_default_timezone_set(‘America/Los_Angeles’);
  Yii::trace(‘start searchTwitter ‘.date(‘ymd h:m ‘));
  // Load your Twitter application keys
  $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’][‘secret’],
  );
  // Connect to Twitter
  $twitter = new TwitterAPIExchange($settings);
  // Query settings for search
  $url = ‘https://api.twitter.com/1.1/search/tweets.json’;
  $requestMethod = ‘GET’;
  // rate limit of 180 queries
  $limit = 180;
  $query_count=1;
  $count = 100;
  $result_type = ‘recent’;
  // calculate valid timestamp range
  $valid_start = $this->start_at;
  // $until_date and $valid_end = // start time + duration
  $valid_end = $this->start_at + ($this->duration*60);
  Yii::trace( ‘Valid Range: ‘.$valid_start.’ -> ‘.$valid_end);
  $until_date = date(‘Ym-d’,$valid_end+(24*3600));
  $distance_km = $this->distance/1000;
  // Unused: &since=$since_date
  // $since_date = ‘2015-03-05’;
  // Perform first query with until_date
  $getfield =»?result_type=$result_type&geocode=».$this->latitude.»,».$this->longitude.»,».$distance_km.»mi&include_entities=false&until=$until_date&count=$count»;

Мы записываем твиты только в пределах нашего точного временного диапазона, игнорируя другие результаты. Обрабатывая их, мы отмечаем самый низкий полученный твит ID.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$tweets = json_decode($twitter->setGetfield($getfield)
                   ->buildOauth($url, $requestMethod)
                   ->performRequest());
       if (isset($tweets->errors)) {
         Yii::$app->session->setFlash(‘error’, ‘Twitter Rate Limit Reached.’);
         Yii::error($tweets->errors[0]->message);
         return;
       }
      $max_id = 0;
      Yii::trace( ‘Count Statuses: ‘.count($tweets->statuses));
      Yii::trace( ‘Max Tweet Id: ‘.$max_id);
      foreach ($tweets->statuses as $t) {
        // check if tweet in valid time range
        $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();
        }
        if ($max_id ==0) {
          $max_id = intval($t->id_str);
        } else {
          $max_id = min($max_id, intval($t->id_str));
        }
      }

Затем мы выполняем цикл, повторяя запросы к Twitter (до 179 раз), запрашивая дополнительные записи, которые являются более ранними, чем самый низкий идентификатор твита предыдущего пакета. Другими словами, при последующих запросах вместо запросов до определенной даты мы запрашиваем max_id самого низкого идентификатора твита, который мы получили.

Мы останавливаемся, когда возвращается менее 100 записей или когда возвращенные твиты раньше нашего фактического диапазона.

Если вам нужен доступ к более чем 18 000 твитов, вам необходимо реализовать фоновую задачу для вызова API Twitter, как мы делали в нашей другой серии Twitter API .

Когда мы обрабатываем результаты API, нам нужно фильтровать твиты, записывая только те из них, которые соответствуют нашему фактическому времени начала и окончания.

Примечание. В API Twitter есть много неприятных особенностей, которые делают подкачку более сложной, чем она должна быть. Довольно часто Твиттер не возвращает результатов без кода ошибки. В других случаях я обнаружил, что он возвращает небольшое количество результатов, но это не значит, что другой запрос не вернет больше. Не существует очень четких способов узнать, когда Твиттер закончил, возвращая вам результаты. Это противоречиво. Таким образом, вы можете заметить, что в моем коде есть несколько интересных решений, например, изучить $ count_max_repeats.

01
02
03
04
05
06
07
08
09
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
38
39
40
41
42
43
44
$count_repeat_max =0;
      // Perform all subsequent queries with addition of updated maximum_tweet_id
      while ($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->latitude.»,».$this->longitude.»,».$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::error($tweets->errors[0]->message);
           return;
         }
         // sometimes twitter api fails
         if (!isset($tweets->statuses)) continue;
          
         Yii::trace( ‘Count Statuses: ‘.count($tweets->statuses));
         Yii::trace( ‘Max Tweet Id: ‘.$max_id);
        foreach ($tweets->statuses as $t) {
          // check if tweet in valid time range
          $unix_created_at = strtotime($t->created_at);
          if ($unix_created_at >= $valid_start && $unix_created_at <= $valid_end)
          {
             $i = new Twitter();
          } 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 ($prior_max_id — $max_id <=1 OR count($tweets->statuses)<1) {
          $count_repeat_max+=1;
        }
        if ($count_repeat_max>5) {
          // when the api isn’t returning more results
          break;
        }
      } // end while

Один из первых возвращенных результатов включал в себя твит Фреда Дэвенпорта, показанный ниже, показывающий президента Обаму на сцене:

Первые результаты для Selma 50th через API поиска в Twitter

Вот это в Твиттере:

Президент Обама в Сельме через API Twitter

Затем, по мере того, как вы просматриваете результаты, вы можете найти гораздо больше людей, которые пишут в Твиттере об Обаме, включая СМИ:

Больше результатов Selma Twitter API

Теперь давайте сделаем более локальный поиск.

Key Arena — большая концертная и спортивная арена Сиэтла. В прошедшие выходные они провели турнир по баскетболу среди женщин Pac-12:

Календарь событий Key Arena

Давайте получим наши GPS-координаты для Key Arena из Google Maps:

Ключевая арена геолокации на Google Maps

Затем я создал и настроил момент, чтобы найти больший диапазон времени для выходных твитов:

Создайте момент для поиска Key Arena Basketball Tournament

И вот некоторые из результатов. Мой любимый:

«Я хочу покинуть эту баскетбольную игру. Я ненавижу баскетбол».

Результаты поиска в Твиттере для Key Arena Tournament

По большей части мне кажется, что API Instagram гораздо более мощный, чем Twitter, и дает в целом более интригующие результаты. Однако это зависит от того, какого человека вы ищете. Если вы просто хотите идентифицировать людей, которые были там, любой API работает хорошо.

Надеюсь, вам понравился этот сериал. Я нашел это захватывающим и был впечатлен результатами. И это подчеркивает озабоченность, которую мы все должны проявлять в отношении уровня конфиденциальности в эту взаимосвязанную цифровую эпоху.

API для Instagram и Twitter — невероятно мощные сервисы для поиска пользователей социальных сетей, которые были в определенных местах в определенное время. Эта информация может быть использована для пользы и злоупотребления. Вам, вероятно, следует подумать об отключении публикации геолокации — перейдите по ссылкам Готов или Нет? приложение

Вы также можете ознакомиться с моей серией «Построение с помощью API Twitter» , также на Tuts +.

Пожалуйста, не стесняйтесь оставлять свои вопросы и комментарии ниже. Вы также можете связаться со мной в Twitter @reifman или написать мне напрямую. Я был бы особенно признателен журналистам и правоохранительным органам, которые используют эти примеры.

Вы также можете просмотреть мою страницу инструктора Tuts +, чтобы увидеть другие уроки, которые я написал.