Статьи

Использование twitter4j с Scala для доступа к потоковым твитам

Вступление

В моем предыдущем посте содержалось пошаговое руководство по использованию API потоковой передачи Twitter из командной строки, но твиты можно было более гибко получать и обрабатывать с помощью API для доступа к Twitter с использованием выбранного языка программирования. В этом уроке я рассмотрю базовую настройку и некоторые простые способы использования библиотеки twitter4j со Scala. Многое из того, что я здесь показываю, должно быть полезно для тех, кто использует другие языки JVM, такие как Clojure и Java. Если вы еще не ознакомились с предыдущим учебником, ознакомьтесь с ним, прежде чем приступить к работе, так как этот учебник охватывает большую часть того же материала, но использует twitter4j, а не HTTP-запросы.

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

Начало настройки

Простой способ использовать библиотеку twitter4j в контексте подобного учебного пособия заключается в том, что читатель может настроить новый проект SBT, объявить его как зависимость, а затем скомпилировать и запустить код в SBT. (См. Мое руководство по использованию Jerkson для обработки JSON с помощью Scala для другого примера.) Это сортирует процесс получения внешних библиотек и настройки пути к классам так, чтобы они были доступны. Следуйте инструкциям в этом разделе, чтобы сделать это.

1
2
3
$ mkdir ~/twitter4j-tutorial
$ cd ~/twitter4j-tutorial/
$ wget http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.12.2/sbt-launch.jar

Теперь сохраните следующее как файл ~ / twitter4j-tutorial / build.sbt. Имейте в виду, что важно сохранять пустые строки между каждым объявлением.

1
2
3
4
5
6
7
name := 'twitter4j-tutorial'
 
version := '0.1.0 '
 
scalaVersion := '2.10.0'
 
libraryDependencies += 'org.twitter4j' % 'twitter4j-stream' % '3.0.3'

Затем сохраните следующее как файл ~ / twitter4j-tutorial / build .

1
java -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -jar `dirname $0`/sbt-launch.jar '$@'

Сделайте этот файл исполняемым и запустите его, что покажет SBT, выполняющего кучу работы, а затем оставит вас с приглашением SBT. В приглашении SBT вызовите команду обновления .

1
2
3
4
5
6
7
8
9
$ cd ~/twitter4j-tutorial
$ chmod a+x build
$ ./build
[info] Set current project to twitter4j-tutorial (in build file:/Users/jbaldrid/twitter4j-tutorial/)
> update
[info] Updating {file:/Users/jbaldrid/twitter4j-tutorial/}default-570731...
[info] Resolving org.twitter4j#twitter4j-core;3.0.3 ...
[info] Done updating.
[success] Total time: 1 s, completed Feb 8, 2013 12:55:41 PM

Чтобы проверить, есть ли у вас доступ к twitter4j сейчас, перейдите в консоль SBT и импортируйте классы из основного пакета twitter4j.

1
2
3
4
5
6
7
8
9
> console
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).
Type in expressions to have them evaluated.
Type :help for more information.
 
scala> import twitter4j._
import twitter4j._

Если ничего больше не выводится, то все готово (выйдите из консоли, нажав CTRL-D). Если что-то не так (или если вы используете Scala REPL по умолчанию), вы увидите что-то вроде следующего.

1
2
3
4
scala> import twitter4j._
<console>:7: error: not found: value twitter4j
import twitter4j._
^

Если это то, что вы получили, попробуйте снова следовать приведенным выше инструкциям, чтобы убедиться, что ваши настройки точно такие же, как указано выше (проверьте версии и т. Д.). Если вы просто хотите увидеть некоторые примеры использования twitter4j в качестве API и с удовольствием добавляете его jar-файлы вручную в ваш путь к классу или используете IDE, например Eclipse, то нет необходимости выполнять настройку SBT — просто прочтите и адаптируйте примеры как нужно.

Написать, скомпилировать и запустить простой метод main

Чтобы подготовить почву для того, как мы будем запускать программы в этом руководстве, давайте создадим простой метод main и обеспечим его запуск в SBT. Сделайте следующее:

1
$ mkdir -p ~/twitter4j-tutorial/src/main/scala/

Затем сохраните следующий код как ~ / twitter4j-tutorial / src / main / scala / TwitterStream.scala .

1
2
3
4
5
6
7
package bcomposes.twitter
 
object StatusStreamer {
  def main(args: Array[String]) {
    println('hi')
  }
}

Затем, в приглашении SBT для проекта twitter4j-tutorial, используйте команду run-main следующим образом.

1
2
3
4
5
> run-main bcomposes.twitter.StatusStreamer
[info] Compiling 1 Scala source to /Users/jbaldrid/twitter4j-tutorial/target/scala-2.10/classes...
[info] Running bcomposes.twitter.StatusStreamer
hi
[success] Total time: 2 s, completed Feb 8, 2013 1:36:32 PM

SBT компилирует код, а затем запускает его. Это в общем удобный способ запуска кода со всеми доступными зависимостями, не беспокоясь о явной обработке пути к классам. Ниже мы уточним этот основной метод, чтобы сделать его более интересным.

Настройка авторизации

При использовании API потоковой передачи Twitter для доступа к твитам через HTTP-запросы необходимо указать имя пользователя и пароль Twitter. Чтобы использовать twitter4j, вы также должны предоставить данные для аутентификации; однако для этого вам нужно настроить аутентификацию OAuth. Это просто:

  1. Перейдите по адресу https://dev.twitter.com/apps и нажмите кнопку с надписью «Создать новое приложение» (конечно, чтобы сделать это, вам необходимо войти в систему с использованием имени пользователя и пароля Twitter).
  2. Заполните поля имени, описания и сайта. Не беспокойтесь об этом: добавьте в качестве названия и описания все, что захотите (например, «Мой пример приложения» и «Приложение для обучения»). Для веб-сайта укажите URL своей учетной записи Twitter, если у вас нет ничего лучше для использования.
  3. Новый экран появится для вашего приложения. Нажмите на кнопку внизу с надписью «Создать мой токен доступа».
  4. Нажмите на вкладку «OAuth tool», и вы увидите четыре поля для аутентификации, которые вам нужны для использования twitter4j для доступа к твитам и другой информации из Twitter: ключ потребителя, секрет потребителя, токен доступа и секрет токена доступа.

Основываясь на этих деталях авторизации, вам теперь нужно создать объект twitter4j.conf.Configuration , который позволит twitter4j получать доступ к API Twitter от вашего имени. Это можно сделать разными способами, включая переменные среды, файлы свойств и код. Чтобы сделать этот урок максимально простым, перейдем к последнему варианту.

Добавьте следующий объект после определения StatusStreamer , указав свои данные, а не описания, приведенные ниже.

1
2
3
4
5
6
7
8
object Util {
  val config = new twitter4j.conf.ConfigurationBuilder()
    .setOAuthConsumerKey('[your consumer key here]')
    .setOAuthConsumerSecret('[your consumer secret here]')
    .setOAuthAccessToken('[your access token here]')
    .setOAuthAccessTokenSecret('[your access token secret here]')
    .build
}

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

Вытащить твиты из потока пробы

В предыдущем уроке самый простой вид доступа состоял в том, чтобы получить случайную выборку твитов с https://stream.twitter.com/1/statuses/sample.json , поэтому давайте используем twitter4j, чтобы сделать то же самое.

Для этого мы собираемся создать экземпляр TwitterStream, который дает нам авторизованное соединение с Twitter API. Чтобы увидеть все методы, связанные с классом TwitterStream, обратитесь к документации API для TwitterStream . Экземпляр TwitterStream может получать твиты (и другую информацию), а затем предоставлять их всем слушателям, которые зарегистрировались в нем. Итак, чтобы сделать что-то полезное с твитами, вам нужно реализовать интерфейс StatusListener и подключить его к TwitterStream.

Прежде чем показывать код для создания и использования потока, давайте создадим StatusListener, который будет выполнять простое действие на основе потоковой передачи твитов. Добавьте следующий код в объект Util, созданный ранее.

1
2
3
4
5
6
7
8
def simpleStatusListener = new StatusListener() {
  def onStatus(status: Status) { println(status.getText) }
  def onDeletionNotice(statusDeletionNotice: StatusDeletionNotice) {}
  def onTrackLimitationNotice(numberOfLimitedStatuses: Int) {}
  def onException(ex: Exception) { ex.printStackTrace }
  def onScrubGeo(arg0: Long, arg1: Long) {}
  def onStallWarning(warning: StallWarning) {}
}

Этот метод создает объекты, которые реализуют StatusListener (хотя он только делает что-то полезное для метода onStatus и в противном случае игнорирует все другие отправленные ему события). Ясно, что он собирается взять статус Twitter (который представляет собой всю информацию, связанную с твитом, включая автора, ретвиты, географические координаты и т. Д.) И вывести текст статуса, то есть то, что мы обычно думаем как «твит».

Следующий код объединяет все это. Мы создаем объект TwitterStream с помощью TwitterStreamFactory и конфигурации, добавляем simpleStatusListener в поток, а затем вызываем пример метода TwitterStream, чтобы начать получать твиты. Если бы это была последняя строка программы, она просто продолжала бы получать твиты, пока процесс не был бы закрыт. Здесь я добавил 2-секундный сон, чтобы мы могли видеть некоторые твиты, затем очистил соединение и полностью его отключил. (Мы могли бы позволить ему работать бесконечно, но затем, чтобы убить процесс, нам нужно было бы использовать CTRL-C, который убьет не только этот процесс, но и процесс, на котором выполняется SBT.)

01
02
03
04
05
06
07
08
09
10
object StatusStreamer {
  def main(args: Array[String]) {
    val twitterStream = new TwitterStreamFactory(Util.config).getInstance
    twitterStream.addListener(Util.simpleStatusListener)
    twitterStream.sample
    Thread.sleep(2000)
    twitterStream.cleanUp
    twitterStream.shutdown
  }
}

Чтобы запустить этот код, просто введите в SBT ту же команду run-main, что и раньше.

1
> run-main bcomposes.twitter.StatusStreamer

Вы должны увидеть поток твитов в течение нескольких секунд, а затем вы вернетесь к приглашению SBT.

Потянув твиты с определенными свойствами

Как и в случае потоковой передачи HTTP, легко использовать twitter4j для отслеживания определенного набора пользователей, определенных поисковых терминов или твитов, созданных в определенных географических регионах. Все, что требуется, — это создать соответствующие объекты FilterQuery, а затем использовать метод фильтра TwitterStream, а не метод образца .

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

01
02
03
04
05
06
07
08
09
10
object FollowIdsStreamer {
  def main(args: Array[String]) {
    val twitterStream = new TwitterStreamFactory(Util.config).getInstance
    twitterStream.addListener(Util.simpleStatusListener)
    twitterStream.filter(new FilterQuery(Array(1344951,5988062,807095,3108351)))
    Thread.sleep(10000)
    twitterStream.cleanUp
    twitterStream.shutdown
  }
}

Это идентификаторы для журнала Wired (@wired), The Economist (@theeconomist), New York Times (@nytimes) и Wall Street Journal (@wsj). Добавьте код в TwitterStream.scala и затем запустите его в SBT. Обратите внимание, что я перевел программу в спящий режим на 10 секунд, чтобы дать больше времени для поступления твитов (так как это всего четыре аккаунта, и они будут иметь различную активность). Если вы ничего не видите, увеличьте время сна.

1
> run-main bcomposes.twitter.FollowIdsStreamer

Для отслеживания твитов, которые содержат определенные термины, создайте FilterQuery с конструктором по умолчанию, а затем вызовите метод track с массивом строк, который содержит интересующие вас условия запроса. Объект ниже делает это и использует args Array в качестве контейнера для условий запроса.

01
02
03
04
05
06
07
08
09
10
object SearchStreamer {
  def main(args: Array[String]) {
    val twitterStream = new TwitterStreamFactory(Util.config).getInstance
    twitterStream.addListener(Util.simpleStatusListener)
    twitterStream.filter(new FilterQuery().track(args))
    Thread.sleep(10000)
    twitterStream.cleanUp
    twitterStream.shutdown
  }
}

Когда все настроено таким образом, вы можете отслеживать произвольные запросы, указав их в командной строке.

1
2
3
> run-main bcomposes.twitter.SearchStreamer scala
> run-main bcomposes.twitter.SearchStreamer scala python java
> run-main bcomposes.twitter.SearchStreamer 'sentiment analysis' 'machine learning' 'text analytics'

Если условия поиска не очень распространены, вам нужно увеличить время ожидания.

Чтобы выполнить фильтрацию по местоположению, снова создайте FilterQuery с конструктором по умолчанию, но затем используйте метод location с аргументом Array [Array [Double]] — в основном это массив из двухэлементных массивов, каждый из которых содержит широту и долготу угол ограничительной рамки. Вот пример, который создает ограничительную рамку для Остина и использует ее.

01
02
03
04
05
06
07
08
09
10
11
object AustinStreamer {
  def main(args: Array[String]) {
    val twitterStream = new TwitterStreamFactory(Util.config).getInstance
    twitterStream.addListener(Util.simpleStatusListener)
    val austinBox = Array(Array(-97.8,30.25),Array(-97.65,30.35))
    twitterStream.filter(new FilterQuery().locations(austinBox))
    Thread.sleep(10000)
    twitterStream.cleanUp
    twitterStream.shutdown
  }
}

Чтобы сделать вещи более гибкими, мы можем взять ограничивающую рамку в командной строке, преобразовать строки в двойные и объединить их в пару.

01
02
03
04
05
06
07
08
09
10
11
object LocationStreamer {
  def main(args: Array[String]) {
    val boundingBoxes = args.map(_.toDouble).grouped(2).toArray
    val twitterStream = new TwitterStreamFactory(Util.config).getInstance
    twitterStream.addListener(Util.simpleStatusListener)
    twitterStream.filter(new FilterQuery().locations(boundingBoxes))
    Thread.sleep(10000)
    twitterStream.cleanUp
    twitterStream.shutdown
  }
}

Мы можем вызвать LocationStreamer с несколькими ограничивающими прямоугольниками, например, следующим образом для Остина, Сан-Франциско и Нью-Йорка.

1
> run-main bcomposes.twitter.LocationStreamer -97.8 30.25 -97.65 30.35 -122.75 36.8 -121.75 37.8 -74 40 -73 41

Вывод

Это показывает начало того, как вы можете использовать twitter4j с Scala для потоковой передачи. Он также поддерживает программный доступ к действиям, которые может выполнять любой пользователь Twitter, включая отправку сообщений, ретвит, подписку и многое другое. Я расскажу об этом в следующем уроке. Кроме того, некоторые примеры использования twitter4j скоро появятся в проекте tshrldu .

Ссылка: Использование twitter4j со Scala для доступа к потоковым твитам от нашего партнера по JCG Джейсона Болдриджа в блоге Bcomposes .