Neste artigo iremos mostrar como você pode fazer para coletar tweets diretamente da STREAM API do Twitter, utilizando qualquer um dos filtros oferecidos pela API.
Para armazenar os tweets utilizaremos o ElasticSearch, que funciona como uma base de dados e é focada principalmente em consulta, e o Kibana para montar dashboards de consulta ao ElasticSearch. Tudo isso rodará sob um sistema operacional Ubuntu.
1. Instalando o ElasticSearch
Comece baixando o ElasticSearch. No momento em que escrevo este artigo, a versão corrente é a 0.90.10. Como estou instalando num sistema operacional Ubuntu, optei por baixar o pacote “.deb”, que facilita muito a instalação no sistema para ser rodado como um serviço.
Se você está usando um servidor sem interface gráfica, para baixar utilize o comando: https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.10.deb
Agora, para realizar a instalação do pacote baixado basta executar o comando:
sudo dpkg -i elasticsearch-0.90.10.deb
Agora iremos gerar o arquivo de configurações do elasticsearch. Para tanto, editaremos o arquivo /etc/elasticsearch/elasticsearch.yml, alterando/adicionando os seguintes parâmetros:
cluster.name: twitter_stream node.name: "twitter_node" node.master: true node.data: true index.number_of_shards: 5 index.number_of_replicas: 1 network.host: 0.0.0.0 #ip da máquina aonde o serviço estará rodando transport.tcp.port: 9300 http.port: 9200
Pronto, seu elasticsearch já está pronto para começar a “rodar”. Para facilitar o acompanhamento do estado do servidor, vamos instalar mais dois plugins. O primeiro deles é o elasticsearch-head e o segundo é o paramedic. Para instalar os plugins, a maneira mais fácil é usando o próprio elasticsearch, num modelo de “repositório”. Para instalar o elasticsearch-head basta executar o seguinte comando:
/usr/share/elasticsearch/bin/plugin -install mobz/elasticsearch-head
Ele irá baixar e instalar o plugin. Já o paramedic precisa do comando abaixo:
/usr/share/elasticsearch/bin/plugin -install karmi/elasticsearch-paramedic
Pronto, caso o elasticsearch já esteja rodando basta reiniciá-lo. Caso contrário, basta iniciá-lo. Como instalamos o elasticsearch via pacote “.deb”, ele está disponível como um serviço do sistema. Assim, para iniciá-lo, pará-lo ou reiniciá-lo, temos os seguintes três comandos, respectivamente:
sudo service elasticsearch start sudo service elasticsearch stop sudo service elasticsearch restart
Agora você já consegue acessá-lo pelo seguinte endereço: http://<ip_da_maquina_aonde_ele_esta_rodando>:9200/_plugin/heade http://<ip_da_maquina_aonde_ele_esta_rodando>:9200/_plugin/paramedic
2. Lendo tweets e armazenando
O próximo passo agora é ler o stream do Twitter, coletar o que desejamos e salvar no elasticsearch. Antes de mais nada é importante dizer que a API do Twitter só permite acesso a 1% dos tweets mundiais, se a sua consulta, porventura, chegar a esse limite, você receberá uma amostra dos tweets que gostaria de receber. Além disso, pelo que pude entender, esse limite de 1% é “por requisição”.
Há diversas maneiras de se fazer isso. Pode-se montar um shell script, já que o ElasticSearch é pensado para ser “gerido” via requisições GET/POST, enviando e recebendo JSONs. Mas eu prefiro usar as libs python desenvolvidas pelo pessoal do elasticsearch e do twitter que faz muito bem o serviço.
Vale destacar que uma outra opção seria utilizar um plugin do elasticsearch chamado “twitter-river”. Porém sua implementação ainda é muito parcial e ele não suporta filtro por idiomas, o que atrapalha muito a nossa vida, já que com o limite de 1% seria bom filtrar os twittes só pelos em “pt”. Aliás, essa é uma outra questão. Dos diversos filtros existentes na API, o de geolocalização não é muito preciso (não recomendo utilizarem) e o de idioma é muito bom!
Voltando ao nosso script com a lib Python… Primeiramente vamos instalar as dependências necessárias. Para tanto, vou usar o “pip” do python; então você precisa dele instalado (“sudo apt-get install python-pip“). As duas bibliotecas que precisamos instalar são a Elasticsearch e a TwitterAPI:
sudo pip install elasticsearch sudo pip install twitterapi
Antes de ir ao nosso script, você precisa ter uma conta no Twitter e solicitar uma chave de conexão à API (é automático e instantâneo o processo) – https://dev.twitter.com/discussions/631
Agora o código do script que faz a mágica toda acontecer:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Importando as bibliotecas
from TwitterAPI import TwitterAPI
import elasticsearch
import logging
import rfc822
import datetime
import numbers
import time
from subprocess import Popen, PIPE
def patch_tweet(d):
"""A API do twitter retorna as datas num formato que o elasticsearch não consegue reconhecer,
então precisamos parsear a data para um formato que o ES entende, essa função faz isso.
"""
if 'created_at' in d:
# twitter uses rfc822 style dates. elasticsearch uses iso dates.
# we translate twitter dates into datetime instances (pyes will
# convert datetime into the right iso format understood by ES).
new_date = datetime.datetime(*rfc822.parsedate(d['created_at'])[:6])
d['created_at'] = new_date
count_is_number = isinstance(d['retweet_count'], numbers.Number)
if 'retweet_count' in d and not count_is_number:
# sometimes retweet_count is a string instead of a number (eg. "100+"),
# here we transform it to a number (an attribute in ES cannot have
# more than one type).
d['retweet_count'] = int(d['retweet_count'].rstrip('+')) + 1
return d
def check_es_status():
"""Essa é uma função que verifica se o serviço do ElasticSearch está operando
e inicia-o ou reinicia-o caso seja necessário.
"""
cmd = Popen(["service", "elasticsearch", "status"], stdout=PIPE)
cmd_out, cmd_err = cmd.communicate()
print(cmd_out) #print para acompanhamento no shell
if "not running" in cmd_out:
print "Elastic Search Not Running, trying to start it"
cmd = Popen(["service", "elasticsearch", "start"], stdout=PIPE)
cmd_out, cmd_err = cmd.communicate()
print(cmd_out) #print para acompanhamento no shell
time.sleep(15)
# configurando traces e logs
log_dir = "/var/log/elasticsearch/"
tracer = logging.getLogger('elasticsearch.trace')
tracer.setLevel(logging.WARN)
tracer.addHandler(logging.FileHandler(log_dir + 'trace.log'))
default_logger = logging.getLogger('Elasticsearch')
default_logger.setLevel(logging.WARN)
default_logger.addHandler(logging.FileHandler(log_dir + 'default.log'))
# Criando conexão ao elasticsearch
es = elasticsearch.Elasticsearch(["<dominio_do_servidor>:9200"]) # domínio sem o http://
# Configurando as chaves de acesso à API do Twitter.
# Não esqueça de alterar os valores abaixo para os da sua conta.
twitter_api = TwitterAPI(consumer_key='consumer_key',
consumer_secret='consumer_secret',
access_token_key='access_token',
access_token_secret='access_token_secret')
#Aqui inicialmos os filtros que desejamos, para ver a documentação completa acesse:
# https://dev.twitter.com/docs/streaming-apis/parameters
# No caso iremos usar apenas o filtro de idioma e por "palavras" (os termos em "track")
# veja mais sobre como escolher as palavras aqui: https://dev.twitter.com/docs/streaming-apis/parameters#track
filters = {
"language": ["pt"],
"track": [ "software", "livre", "open", "source", "floss", "gnu", "gpl", "polignu" ]
}
#Agora é que a mágina acontece, esse é um código feito para rodar 24x7
while True:
#creates the stream object
stream = twitter_api.request('statuses/filter', filters)
#For each item in the stream (tweet data), save it on the elastisearch
for item in stream.get_iterator():
try:
# Saving the tweet on the ES
es.index(
index="tweets",
doc_type="tweet",
body=patch_tweet(item)
)
except:
#caso haja qualquer problema com o elasticsearch ele verifica o estado e reinicia se necessário
check_es_status()
es = elasticsearch.Elasticsearch(["<dominio_do_servidor>:9200"])
print ("Getting back to tweet recording")
Pronto, agora enquanto você deixar esse script rodando ele coletará os tweets e salvará na base de dados do elasticsearch.
Vale destacar que a API do Twitter retorna um JSON, que é armazenado na íntegra no ElasticSearch.
3. Analisando os dados com o Kibana
Mas de nada adianta armazenarmos quilos e quilos de dados sem analisá-los, não é verdade?
Então para fazer a análise utilizaremos o Kibana, que nada mais é que um conjunto de páginas estáticas (html+css) com um pouco de javascript para se conectar ao ElasticSearch e montar um dashboard lindão, podendo salvar diversos dashboards (ficam salvos como jsosn no próprio elasticsearch). [ex. do kibana: demo.kibana.org/#/dashboard ]
- Você pode encontrar o kibana para download aqui: http://www.elasticsearch.org/overview/kibana/installation/
- Link direto para a versão que estou usando: https://download.elasticsearch.org/kibana/kibana/kibana-3.0.0milestone4.tar.gz
Como o Kibana é baseado em páginas estáticas, precisamos de um servidor web rodando para servir as páginas. Sinta-se à vontade para escolher a sua opção (Apache, Nginx, etc). Descompacte o kibana na pasta pública do servido web e vamos configurá-lo para acessar o ES.
Na pasta principal do Kibana tem um arquivo “config.js“. O que precisamos fazer é alterá-lo para configurar o endereço do elasticsearch. Assim, procure a linha que contém “elasticsearch: ” e coloque ali o endereço de seu servidor. Salve o arquivo e acesse o endereço do servidor pelo navegador e boa diversão!



