Escrevendo uma aplicação com python-twitter (parte 3 - final)

Categoria: Python Publicado: Domingo, 03 Abril 2011 Escrito por Helio Loureiro Imprimir

Após as partes 1 e 2 sobre como escrever uma aplicação com python-twitter, onde foi visto como instalar o pacote python-twitter ou via fonte ou via pacote Debian, e como registrar sua aplicação no Twitter, finalmente chegamos ao final: escrevendo a aplicação em python.

O objetivo de toda essa série de descrição de como utilizar uma aplicação de twitter-python era mostrar como fiz um script para automatizar o #FF, enviado às sexta-feiras.  

Inicialmente escrevi o seguinte script que fazia exatamente o #FF para todos os meus seguidores:

#! /usr/bin/python
import twitter

# App python-tweeter
# https://dev.twitter.com/apps/815176
api = twitter.Api(
    consumer_key = 'xxxxxxx',
    consumer_secret = 'yyyyyyyy',
    access_token_key = 'zzzzzzz',
    access_token_secret = 'zzzzzzzz'
    )
FOLLOWERS = []
users = api.GetFollowers()
for u in users:
        sc_name = str(u.screen_name)
        FOLLOWERS.append(['@' + sc_name])

SIZE = 140
MSG = "#FF"
i = 1
api.PostUpdate("Automated python-twitter-#FF mode=on")
for uid in FOLLOWERS:
    print i, uid
    if ( len(MSG + " " + uid) > SIZE):
        print MSG
        api.PostUpdate(MSG)
        sleep(60)
        MSG = "#FF " + uid
    else:
        MSG += " " + uid
    i += 1

print MSG
api.PostUpdate(MSG)

Esse pequeno script mostrou uma limitação do uso do python-twitter 0.8.1: a lista de usuários era buscada somente com os último 100 seguidores.  O demais não retornavam.  Eu corrigi esse comportamento e lançei o "0.8.2", mas na verdade ainda não foi aprovado.

Basicamente o módulo twitter, ou classe, permite buscar todos os seguidores com o método GetFollowers().  Cada seguidor retornado volta como uma matriz (array) de seguidores, com seus parâmetros como atributo do objeto retornado.  Então como exemplo um dos meus seguidores:

>>> print users[0]
{"description": "Expert in software development, photographer, open networker, 
 writer, handyman, old DJ+radiohost, idealist, creative, easily inspired, 
 very independent, spunky", 
"favourites_count": 44, 
"followers_count": 27800, 
"friends_count": 30580, 
"geo_enabled": true, 
"id": 5377742, 
"location": "Copenhagen, Denmark", 
"name": "J\u00f8rgen Larsen", 
"profile_background_color": "000000", 
"profile_background_tile": true, 
"profile_image_url": 
 "http://a0.twimg.com/profile_images/728474665/J_rgen_Larsen_org_nobackground_small_128x128_normal.png", 
"profile_link_color": "000000", 
"profile_sidebar_fill_color": 
 "http://a1.twimg.com/profile_background_images/78764489/background3.jpg", 
"profile_text_color": "333333", 
"protected": false, 
"screen_name": "porcupinex", 
"status": {"created_at": "Fri Apr 01 06:36:13 +0000 2011", 
    "favorited": false, 
    "id": 53707220474544128, 
    "source": "HootSuite", 
    "text": "RT @renejsum: RT @tinybuddha \"We must accept finite disappointment, but never lose infinite hope.\"
        ~Martin Luther King Jr. (Til @jesperdahl)", 
    "truncated": false}, 
"statuses_count": 1500, 
"time_zone": "Copenhagen", 
"url": "http://on.fb.me/porcupinex", 
"utc_offset": 3600}

chamando cada user[] como follower (for follower in user:), é possível verificar seus atributos usando algo como follower.url, follow.screen_name e assim por diante.  Em geral o que se vê no twitter é no formato @helioloureiro, que é uma referência ao atributo screen_name, esse sem o "@" originalmente.

Para publicar algo usando python-twitter, basta utilizar o método PostUpdate()

 

api.PostUpdate("Testando via twitter...")

Tudo isso já estaria de bom tamanho se não fossem duas coisas: o @ale_borba reclamou do flood de #FFs e realmente eu não queria mandar #FF para todo mundo, mas somente para quem realmente participa no Twitter.  Como eu tenho a política de seguir de volta quem me segue, tem muitos "robôs" que eu gostaria de evitar.  Então resolvi criar um grupo "amigos" e buscar somente os seguidores desse grupo:

 

Acabei escrevendo a busca de seguidores por grupo sem utlizar a API do python-twitter, com urllib2 e json:

 

lstname = 'Amigos'
AMIGOS = []
NOMES = {}
FOLLOWERS = {}
parameters = {}
parameters['cursor'] = -1
ic = 0
while (parameters['cursor'] != 0):
    url = '%s/%s/%s/members.json' % (api.base_url, user,lstname)
    
    json = api._FetchUrl(url, parameters=parameters)
    data = simplejson.loads(json)
    for u in data['users']:
        AMIGOS.append(u)
    parameters['cursor'] = int(data['next_cursor_str'])

    if (ic == 10): break
    ic += 1

Para evitar ainda um flood de mensagens (ou trollada), inclui ainda um randrange() pra criar uma aleatoriedade nos #FFs.  Comecei com 50%, mas aumentei pra 33% (1/3).  Também adicionei um belo sleep() para evitar o envio massivo de #FF, tornando um pouco mais suave as indicações.

O código final que utilizo atualmente é esse:

#! /usr/bin/python
import twitter
from time import sleep
from sys import exit
import simplejson
from random import randrange

# App python-tweeter
# https://dev.twitter.com/apps/815176
api = twitter.Api(
    consumer_key = 'xxxxxx',
    consumer_secret = 'yyyyyy',
    access_token_key = 'zzzzzzz',
    access_token_secret = 'kkkkkkkk'
    )

user = 'helioloureiro'
lstname = 'Amigos'
AMIGOS = []
NOMES = {}
FOLLOWERS = {}
parameters = {}
parameters['cursor'] = -1
ic = 0
while (parameters['cursor'] != 0):
    url = '%s/%s/%s/members.json' % (api.base_url, user,lstname)
    
    json = api._FetchUrl(url, parameters=parameters)
    data = simplejson.loads(json)
    for u in data['users']:
        AMIGOS.append(u)
    parameters['cursor'] = int(data['next_cursor_str'])

    if (ic == 10): break
    ic += 1

for a in AMIGOS:
    NOMES[a['screen_name']] = 1

users = api.GetFollowers()
for u in users:
    status = ""
    try:
        if (NOMES[u.screen_name] == 1):
            FOLLOWERS['@' + u.screen_name] = 1
            status = "OK"
    except:
        status = "NOT"

    print u.screen_name, status
    
SIZE = 140
MSG = "#FF"
i = 1
api.PostUpdates("Automated python-twitter-#FF mode=on")
for uid in FOLLOWERS.keys():
    if not (randrange(0,2)):
        print "Nao foi:", uid
        continue
    print i, uid
    if ( len(MSG + " " + uid) > SIZE):
        print MSG
        api.PostUpdate(MSG)
        sleep(60)
        MSG = "#FF " + uid
    else:
        MSG += " " + uid
    i += 1

sleep(60)
print MSG
api.PostUpdate(MSG)

api.PostUpdates("Python Twitter #rockz!!!")
api.PostUpdates("Automated python-twitter-#FF mode=off")

Com esse princípio de uso do python-twitter já criei várias aplicações, inclusive para re-enviar minhas publicações daqui e ainda utilizando o eri.cx para encurtar os link.

Acessos: 7152