Доступ к Твиттеру из командной строки

Используйте Твиттер для создания интересных приложений для командной строки

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

Арпан Сен, технический директор, Synapti Computer Aided Design Pvt Ltd

Арпан Сен (Arpan Sen) – ведущий инженер, работающий над разработкой программного обеспечения в области автоматизации электронного проектирования. На протяжении нескольких лет он работал над некоторыми функциями UNIX, в том числе Solaris, SunOS, HP-UX и IRIX, а также Linux и Microsoft Windows. Он проявляет живой интерес к методикам оптимизации производительности программного обеспечения, теории графов и параллельным вычислениям. Арпан является аспирантов в области программных систем.



27.05.2013

Введение

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

Эта статья не является введением в Твиттер, в котором он на самом деле и не нуждается. В ней показывается, как можно получить доступ к платформе Твиттера для создания интересных приложений для командной строки. Работать с Твиттером можно с помощью различных языков программирования, включая C++, Java™, Perl, Ruby, PHP и Python. Для каждого языка существует богатый выбор библиотек или пакетов, способных взять на себя выполнение наиболее сложных задач. Итак, приступим.

Статья начинается с использования Ruby для доступа к Твиттер. Желательно, чтобы вы обладали хотя бы минимальным знанием Ruby, но даже если это и не так, то вы сможете легко освоить основы Ruby по ходу статьи.


Установка gem-пакета для Твиттера

Для доступа к Твиттеру в Ruby имеется несколько gem-пакетов (см. ссылки с дополнительной информацией в разделе "Ресурсы"). В этой статье я выбрал пакет twitter. Это Ruby-оболочка для Твиттера, написанная Джоном Ньюнмейкером (John Nunemaker). Установите этот пакет с помощью следующей команды:

bash$ gem install twitter

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

require 'rubygems'
require 'twitter'

Первый Твиттер-сценарий

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

Листинг 1. Отслеживание местоположения пользователей
require 'rubygems'
require 'twitter'

def track
  ARGV.each do |name|
     puts name + " => " + Twitter.user("#{name}").location
  end
end

track

Что происходит в данном фрагменте кода? Если вы не очень хорошо знакомы с Ruby, то ARGV – это массив, через который сценарий получает доступ к параметрам командной строки. Вызов Twitter.user возвращает большое количество информации о пользователе, но в данный момент нас интересует только местоположение. Запустим сценарий, чтобы узнать, где находятся в данный момент Леди Гага (lady gaga), Эштон Катчер (aplusk) и Опфра Уинфри (Orphah).

bash$ ./location_tracker.rb ladygaga aplusk Oprah
ladygaga => New York, NY
aplusk => Los Angeles, California
Oprah => Chicago, IL

Теперь давайте найдём какого-нибудь определенного пользователя, уже зарегистрированного в Твиттере. Если вы можете предположить имя учетной записи Твиттера для этого пользователя, то просто воспользуйтесь следующей строкой:

require 'rubygems'
require 'twitter'
puts "User exists" if Twitter.user?(ARGV[0])

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

require 'rubygems'
require 'twitter'
names = Twitter.user_search("Arpan")

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

Листинг 2. Сообщение об ошибке, возникшей при поиске пользователя
Twitter::Unauthorized: GET https://api.twitter.com/1/users/search.json?q=Arpan%
20Sen: 401: Could not authenticate you.
        from D:/Ruby/lib/ruby/gems/1.8/gems/twitter-1.6.2/lib/faraday/response/r
aise_http_4xx.rb:12:in `on_complete'
        from D:/Ruby/lib/ruby/gems/1.8/gems/faraday-0.7.4/lib/faraday/response.r
b:9:in `call'
        from D:/Ruby/lib/ruby/gems/1.8/gems/faraday-0.7.4/lib/faraday/response.r
b:62:in `on_complete'

Из этой информации становится понятно, что прежде чем начать что-либо делать в Твиттере, необходимо пройти аутентификацию. Для этого вам не потребуется вводить имя/пароль от собственной учётной записи, так как аутентификацию необходимо пройти вашему сценарию (или приложению в терминологии Твиттера). Поэтому вам необходимо зайти на страницу http://dev.twitter.com/apps и ввести там имя/пароль от собственной учётной записи в Твиттере. После того как вы укажете эту информацию, вам предоставят четыре значения, которые ваш сценарий сможет использовать для собственной аутентификации.

  • Consumer key - (ключ пользователя);
  • Consumer secret token - (секретный маркер пользователя);
  • Consumer OAuth key - (OAuth-ключ пользователя);
  • Consumer OAuth secret token - (секретный OAuth-маркер пользователя).

Теперь в коде Ruby вам необходимо поместить эти значения внутрь объекта Twitter.configure, как показано в листинге 3.

Листинг 3. Настройка сценария для последующей аутентификации
Twitter.configure do |config|
  config.consumer_key = "mT4atgBEKvNrrpV8GQKYnQ"
  config.consumer_secret = "BiQX47FXa938sySCLMxQCTHiTHjuTTRDT3v6HJD6s"
  config.oauth_token = "22652054-Yj6O38BSwhwTx9jnsPafhSzGhXvcvNQ"
  config.oauth_token_secret = "o9JuQuGxEVF3QDzMGPUQS0gmZNRECFGq12jKs"
end

Обратите внимание, что в листинге 3 для заполнения атрибутов используются демонстрационные данные, а вы должны будете использовать полученные вами значения. После выполнения аутентификации вы сможете найти всех пользователей, использующих учётную запись Arpan, c помощью сценария, показанного в листинге 4.

Листинг 4. Поиск пользователей в Твиттере
require 'rubygems'
require 'Twitter'

Twitter.configure do |config|
  config.consumer_key = "mT4atgBEKvNrrpV8GQKYnQ"
  config.consumer_secret = "BiQX47FXa938sySCLMxQCTHiTHjuTTRDT3v6HJD6s"
  config.oauth_token = "22652054-Yj6O38BSwhwTx9jnsPafhSzGhXvcvNQ"
  config.oauth_token_secret = "o9JuQuGxEVF3QDzMGPUQS0gmZNRECFGq12jKs"
end

users = Twitter.user_search(ARGV[0])
users.each do |user|
  print "\n"  + user.name + " => " 
  print user.location unless user.location.nil?
end

Теперь можно сохранить сценарий в файле search_for.rb и запустить его командой ./search_for.rb Arpan, чтобы получить список имён, приведённый в листинге 5.

Листинг 5. Результат запуска кода из листинга 4
Arpan Jhaveri => New York
Arpan Boddishv =>
Arpan Peter => Bangalore,India
Arpan Podduturi => NYC
Arpan Kumar De => IIT Kharagpur
Arpan Shrestha => Kathmandu, Nepal
Arpan Divanjee => Mumbai,India
Arpan Bajaj => Bay Area, CA

Возможно, вы ожидали увидеть несколько больше результатов. Имя Arpan (Арпан) – это довольно распространённое индийское имя, так почему же было найдено всего несколько пользователей с таким именем? Это связано с тем, что вызов user_search может принимать на вход необязательный параметр (хеш-таблицу Ruby); в нем можно указать опции, которые помогут вернуть больше результатов. Поэтому немного изменим код в листинге 5 для передачи хеш-таблицы (#), заполненной необходимыми значениями. Например, если нам требуется, чтобы результат поиска был представлен в виде набора страниц, каждая из которых содержала бы по 15 записей, то можно использовать код из листинга 6.

Листинг 6. Отображение 15 найденных записей на странице
require 'rubygems'
require 'twitter'

#.. здесь должен находиться код для аутентификации
users = Twitter.user_search(ARGV[0], {:per_page => 15})
#... аналогично листингу 5

Значит ли это, что вы можете выводить по сто записей на страницу? Нет, так как вызов Twitter.user_search ограничивает максимальное число записей на странице двадцатью записями. В листинге 7 приведён код, позволяющий получить 10 страниц, содержащих по 20 записей.

Листинг 7. Отображение 20 найденных записей на странице
#.. здесь должен находиться код для аутентификации

pagecount = 0
while pagecount < 10
  u = Twitter.user_search("#{ARGV[0]}", {:per_page => 20, :page => pagecount})
  u.each do |user| 
    print "\n" + user.name + " => " + user.screen_name
    print " => " + user.location unless user.location.nil?
  end unless u.size < 20
  pagecount += 1
end

Уже лучше, так как теперь в информации о пользователе выводится имя, указанное вами, и псевдоним, установленный самим пользователем. Перейдём к более сложным задачам и попробуем найти пользователей с именем Nick, находящихся в данный момент в Нью-Йорке (New York) и увлекающихся Ruby. Вы можете получить информацию об имени и местоположении пользователя из вызова user_search, но как узнать отношение пользователя к Ruby? Для этого нам придётся изучить ещё одну возможность Twitter API: пользовательские поисковые клиенты (custom search clients).

Использование класса Twitter::Search

Класс Twitter::Search можно использовать для создания собственных поисковых клиентов, как показано в листинге 8.

Листинг 8. Пример использования класса Twitter::Search
#... код для аутентификации 
pagecount = 0
while pagecount < 10
  u = Twitter.user_search("#{ARGV[0]}", {:per_page => 20, :page => pagecount})
  u.each do |w| 
    if w.location == "New York"
      results = Twitter::Search.new.from(w.screen_name).containing("ruby").fetch
      puts w.screen_name if results.size > 10
    end
  end unless u.size < 20
  pagecount += 1
end

Что происходит в данном фрагменте кода? Он начинается с создания поискового клиента с помощью вызова Twitter::Search.new. Затем вы используете поисковый клиент для получения всех твитов (сообщений) соответствующего пользователя, содержащих слово ruby. В конце вызов fetch возвращает массив с результатами, и если слово ruby упоминается в твитах данного пользователя более 10 раз, это может свидетельствовать о его интересе к этому языку программирования.

Попробуем извлечь массив твитов с хештегом #ruby с помощью кода, показанного ниже:

#... код для аутентификации пользователя
results = search.hashtag("ruby").fetch
results.each do |r|
  puts r.text + " from " + r.from_user
end

Но это ещё не все, так как вы наверняка ожидали получить сотни записей для такого популярного хештега, как #ruby. Снова воспользуемся поисковым клиентом, чтобы извлекать полученные им результаты постранично. Код в листинге 9 извлекает 10 страниц, содержащих твиты, посвященные языку Ruby.

Листинг 9. Отображение нескольких страниц, полученных в результатах поиска
#... код для аутентификации пользователя
results = search.hashtag("ruby").fetch
count = 0

while count < 10 
  results.each do |r|
    puts r.text + " from " + r.from_user
  end
  results = search.fetch_next_page
  count += 1
end

Поисковый клиент предлагает и другие интересные возможности, например, поиск твитов, написанных на определённом языке или опубликованных в конкретной стране. Вы также можете искать твиты, в которых упоминаются конкретные пользователи, или соответствующие определенным условиям. С помощью кода, показанного ниже, можно найти все твиты, в которых упоминается Ruby, но отсутствует слово Rails.

search.containing("ruby").not_containing("rails").fetch

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

search.containing("ruby").not_containing("rails").mentioning("username").from("place-id")

Поиск определённой фразы также выполняется интуитивно просто, как в примере ниже:

search.phrase("ruby on rails").fetch

Узнав все эти необходимые сведения, мы можем приступить к более сложным задачам!

Ограничение по количеству запросов к Твиттеру

Так как мы продолжаем изучать возможности Твиттера, то пришло время усвоить один важный аспект в работе с Твиттером, который называется rate limiting (ограничение по количеству выполненных запросов). Твиттер очень серьёзно относится к этому ограничению, позволяя вашему сценарию выполнять в час только определенное количество запросов. Как уже было показано, некоторые типы приложений не требуют явной аутентификации, в то время как другие должны аутентифицировать себя перед выполнением запроса. Для приложений, не использующих OAuth-маркер, ограничение составляет 150 запросов в час, приложения, обладающие таким маркером, могут выполнять до 350 запросов в час. Актуальную информацию о политике Твиттера по ограничению максимального числа запросов можно найти в разделе "Ресурсы". Чтобы узнать ваш текущий лимит, добавьте следующую строку в сценарий, который содержит код для аутентификации в Твиттере.

puts Twitter.rate_limit_status

В результате запуска сценария будет выведено сообщение наподобие следующего:

<#Hashie::Mash hourly_limit=350 remaining_hits=350 reset_time="Sat Aug 13 21:48:
59 +0000 2011" reset_time_in_seconds=1313272139>

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

Twitter.rate_limit.status.remaining_hits

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

<#Hashie::Mash hourly_limit=150 remaining_hits=77 reset_time="Sat Aug 13 21:13:5
0 +0000 2011" reset_time_in_seconds=1313270030>

Обновление статуса в Твиттере, ретвиты и другие возможности

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

#... код для выполнения аутентификации
Twitter.update (ARGV [0])

Сохраним этот код в файле update.rb и вызовем его из командной строки, как показано ниже.

ruby update.rb "Hello World from Ruby Script"

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

#... код для выполнения аутентификации
Twitter.direct_message_create("username", "Hi")

Отправляя сообщение, для определения его получателя можно использовать либо отображаемое имя пользователя (screen name) либо его числовой идентификатор. Также в Твиттере присутствует интересная возможность, обеспечивающая быстрый доступ к 20 последним собственным отправленным или полученным сообщениям.

#... код для выполнения аутентификации
Twitter.direct_messages_sent.each do | s | 
  puts "Sent to: " + s.recipient_screen_name
  puts "Text: " + s.text
end

Если вы хотите узнать, насколько вы авторитетны в глазах других пользователей, то для этого существует хороший способ. Достаточно проверить, как другие пользователи ретвитят ваши сообщения (т.е. ссылаются на них в своих сообщениях). С помощью кода, приведённого ниже, вы можете получить список из 20 последних своих сообщений, на которые ссылались другие пользователи.

#... код для аутентификации
Twitter.retweets_of_me.each do |rt|
  print rt.text
  puts " retweet count = " + rt.retweet_count.to_s
end

Конечно, было бы интересно узнать, кто именно цитирует ваши сообщения, но, к сожалению, сделать это напрямую через вызов retweets_of_me не получится. Для этой цели используется другой вызов API – retweeters_of. Напомню, что у каждого сообщения имеется уникальный идентификатор, который и нужно передать в вызов retweeters_of, как показано в листинге 10.

Листинг 10. Поиск пользователей, ссылающихся на ваши сообщения
#... код для аутентификации
Twitter.retweets_of_me.each do |rt|
  print rt.text
  print " retweeted by " 
  Twitter.retweeters_of(rt.id).each do |user|
    puts user.screen_name
  end
end

Что ещё можно делать с Твиттером

С помощью подобных сценариев вы можете выполнять и множество других интересных действий. Например, если вы хотите узнать, какие темы наиболее популярны в глобальном сообществе Твиттера на данный момент, то следующий фрагмент кода вернёт список, содержащий 10 самых популярных тем.

Twitter.trends.each do | trend | 
  puts trend.name
end

Твиттер специально ограничивает размер этого списка десятью записями (объяснение этому можно найти в разделы "Ресурсы"). Но обычно пользователей интересуют темы, относящиеся к тому региону, где они проживают. Твиттер может предоставить подобную информацию, если указать WOEID-идентификатор региона (where-on-earth ID) и если в данном регионе ведётся рейтинг тем. Вот так я могу узнать, какие темы популярны в Индии:

Twitter.local_trends(12586534 ).each do | trend | 
  puts trend  #local_trends returns String
end

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

Twitter.suggestions("technology").users.each do | user | 
  puts  user.screen_name
end

Я специально проверил результаты, предоставленные этим сценарием. Факт, что в список 10 самых популярных пользователей попал timoreilly (директор известного издательства технической литературы O'Reilly), говорит о том, что сценарий работает правильно. В Твиттере имеются несколько категорий, описывающих интересы пользователей, и вы можете напрямую обратиться к ним через вызов Twitter.suggestions. У каждой категории есть своё краткое название (англ. slug в терминологии Твиттера), и это название нужно передать в вызов Twitter.suggestions, чтобы получить список наиболее популярных пользователей в данной категории. В листинге 11 приведён список самых популярных пользователей по категории "technology" (технология).

Листинг 11. Популярные пользователи, пишущие на технологические темы
gruber
dannysullivan
AlecJRoss
timoreilly
Padmasree
tedtalks
OpenGov
twitter
BBCClick
woot
anildash
laughingsquid
digiphile
jennydeluxe
biz
ForbesTech
chadfowler
leolaporte

Мы завершим нашу статью поиском наиболее популярных читателей (фолловеров в терминологии Твиттера) блога известного игрока в крикет Сачина Тендулкара (Sachin Tendulkar). Идентификатор учётной записи Сачина – sachin_rt. Вы можете узнать количество читателей его блога с помощью вызова Twitter.user("sachin_rt").follower_count и проверить подлинность его учетной записи с помощью вызова Twitter.user("sachin_rt").verified.

Теперь с помощью вызова Twitter.follower_ids("sachin_rt") можно узнать количество читателей блога Сачина. По умолчанию вы получите список из 5000 пользователей, и это даже больше, чем нам потребуется. Чтобы узнать, как получить полный список читателей, можно прочесть в документации Твиттера разделы, посвященные работе с друзьями (friends) и читателями (followers) с помощью Twitter API. Вот как это можно сделать:

#... аутентификация
puts Twitter.follower_ids("sachin_rt").ids.size

Теперь выделим из этих 5000 пользователей 50, обладающих максимальном числом читателей.

#... аутентификация
puts Twitter.follower_ids("sachin_rt").ids[0..49].sort!{|a, b|   \ 
	Twitter.user(a).followers_count <=>   \
	Twitter.user(b).followers_count}.reverse.first.name

Символ ! после вызова sort показывает, что метод sort непосредственно изменяет переданный в него массив, а не возвращает новый. В фигурных скобках {} располагается код, в котором выполняется сравнение. Этот пример демонстрирует ещё одно преимущество Ruby: задачу, решение которой на языке C++ потребовало бы 20 строк кода, нам удалось решить фактически в одной строке кода.


Заключение

Создание сценариев командной строки для Твиттера - это интересное занятие, предоставляющее вам возможности, которые (пока ещё) нельзя получить от Твиттера "естественным способом" через пользовательский интерфейс. Так, вы можете искать определённых пользователей по собственным критериям (от местных пользователей, интересующихся определёнными технологиями, до экспертов с мировым именем) или публиковать сообщения напрямую из командной строки. Напоследок я бы хотел дать ещё два важных совета. Твиттер очень серьёзно относится к ограничению на максимальное число запросов, поэтому полученные результаты стоит кэшировать в коде. Также не забывайте просматривать ресурсы по REST API Twitter, вызовы которого постоянно используются Твиттер-клиентами в других API-вызовах. На этом прощаюсь и желаю вам приятной работы с Твиттером!

Ресурсы

Научиться

Получить продукты и технологии

  • Узнайте больше о Twitter Ruby API.
  • Если вас заинтересовали возможности Ruby, представленные в этой статье, то познакомьтесь с полной документацией данного языка.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=931485
ArticleTitle=Доступ к Твиттеру из командной строки
publish-date=05272013