Derrotado a La Inflacion en Venezuela

Primero que nada siempre han habido tiempos malos en nuestra sociedad, quizá nunca hayamos tenido ningún tiempo como el presente pero eso es otra historia, en la biblia dice que aprovechemos el tiempo por que los días son malos… En conclusión Dios siempre esta al control de todo, y es por esto que debemos encomendar nuestros planes según su Buena Voluntad…

Bueno quizá estas pensando  que hacer con ese dinero que tienes de las utilidades o algún dinero extra que tengas y pensándolo bien con el Dolar subiendo mas y mas cada día si lo metes en el Banco es posible que lo absorba la inflación y por ejemplo 200BsF hoy mañana sean solo 190 y así cada día no estoy exagerando en 2 idas el dolar a pasado de 2100 a 2479 BsF según Dolar Today es terrible la situación que vivimos en Venezuela..

No me gusta suponer ni mucho menos decirte que hacer con tu dinero pero a mi me gusta arriesgar(confiando en que Dios ponga en mi corazón discernimiento, en realidad de arriesgar quizá tenga muy poco jejeje) y es por eso que voy a hablar de finanza en este Blog debido a la Gran Crisis de Venezuela, Recuerda que Dios tiene un plan para todos… y bueno imagina comprar 100 dolares hace 3 meses cuando el dolar valía cerca de 1200BsF habrías Gastado 120.000BsF y ahora mismo tendrías cerca de 240.000BsF en realidad no habrías ganado mucho ya que los precios de los productos van en aumento a medida que el dolar se va estabilizando… Dios lo puede todo, te invito a leer 2 Reyes 7 del 1 al 3, claro que nosotros debemos buscar la manera de no malgastar nuestro dinero y meterlo al banco es malgastarlo ahora mismo

Y bueno comprar dolares solo sirve para mantener tus activos pero que tal si te digo que podríamos agregar una variable mas aunque es ligeramente arriesgado, El Bitcoin, si el Bitcoin es una moneda Digital mas cara que el ORO por algo sera, mucha gente teme usar la moneda pero es una moneda mas peor son los billetes de Venezuela que tienen ídolos de la Santería y aun así debemos usarlos pero no adorarlos ojo…

Y bueno si hacemos la misma cuenta, pero ahora incluimos comprar Bitcoins con los dolares que teníamos hace 3 meses, hace 3 meses 1 Bitcoin costaba entre 500 y 600 dolares, es decir que por encima podriamos comprar 1/6 de Bitcoins o lo que es lo mismo 16.666.667 Satoshis y ahora mismo el Bitcoin cuesta 750 Dolares, es decir habríamos ganado con 1 Bitcoin 1/4 de lo invertido es decir 25 Dolares ahora si  te tome la atención 😀

Tu dirás el Hubiera es pasado ahora es que quiero invertir :S, hace poco empresas como BBVA, Movistar, Grupo Santander, hasta Google y Facebook segun rumores estan invirtiendo en esta tecnología y la buena noticia es que mientras vaya aumentando el comercio Digital el valor del Bitcoin sera mas alto, Claro si no Viene Nuestro Señor Jesucristo Antes, pero imagina que te pregunte que hiciste con el Dinero que te Dio? no lo donaste, no ofrendaste, ni nada, dejaste que se lo comiera la inflación…

Bueno yo espero que a finales del año que viene el Bitcoin se coloque en 1500 Dolares, y el Dolar Baje por lo menos en Venezuela a 1500BsF… y entonces Diras por que invertir en Dolares o Bitcoin entonces, simple no pienso en comprar y vender como hace la mayoría de la gente eso mas bien destruye el Pais, ya que las Divisas salen del País y no hay retorno… Lo que quiero hacer es invertir por ejemplo  en Minería en la nube para comenzar con planes de 1 año y asi como esta el retorno seria en 5 a 7 meses y lo demas es ganancia es decir ganarías si inviertes 100 Dolares como mínimo 70 dolares mas lo que pueda subir el Bitcoin… en la proxima entrada espero tener mi Cloud ya funcionando para mostrarle como invertir en las mejores y ams fiables Cloud como mover su dinero de Bitcoins a Dolares o Bolivares y un par de calculadoras de suposiciones que pienso hacer para ver la trazabilidad de LA INVERSION, dicen que lleva riesgos epro en el peor de los casos en 4 meses tendras casi toda tu inversion…

Hace 1 año exactamente le dije a un tío que dice el tiene mucho Dinero, pero para mi es realmente Pobre por que no sabe de números y lo mas importante no tiene a Dios en su Corazón, le dije que invirtiera 360$ en 1 Bitcoin con lo que podía comprar un AntMiner S5 y de 5 a 7 meses tendría el retorno y luego ganaría Dividendos hasta que el Antminer muera es decir de 3 a 5 años como mínimo, y estaba un poco dispuesto y todo el mundo no hubo uno solo le dijo que si estaba loco, bueno con el dolar a 700BsF mas o menos y el Bitcoin a 360$ imagínate cuanto no tendría ahora mismo de Retorno… Bueno cosas asi me han pasado por no tener Dinero jeje, pero ahora mismo Dios esta Bendiciendo mi vida y quiero invertir no para mi si no para ayudar a tanta gente que no tiene la visión que Dios me ha dado, no económicamente si no mas bien usar el dinero para cursos seminarios Teológicos y de Tecnología, para las misiones y otras cosas… Bueno es lo que quiero esperemos que Dios me lo permita según su Buena y perfecta Voluntad…

Saludos Dios les Bendiga

 

 

Anuncios

Python Scraping NFL [Parte 1]

Al final decidí hacer la parte 1 de esta interesante serie, estamos bastante desfasados :S, pero esta semana creo que podre terminar esta serie hasta la parte del scraping… ya la parte del análisis espero tenerla este año, y sera para la próxima temporada que podremos usarla a tope… Hoy vamos a ver el codigo de como extraer los datos para cada juego, solo vamos a extraer los score de cada equipo por separado, ya luego podemos hacer un for para que nos los agrupe de 2 en 2 y asi saber a quien se enfrento cada equipo….

Aqui el codigo, aunque pienso cambiarlo un poco en como aplicar el get.TEXT, luego algun comentario del codigo:

import requests, urllib2
from bs4 import BeautifulSoup
import re

import math

lista_regular_season = [range(1, 6)]

### Pagina primaria para buscar los datos

url_1er = 'http://www.nfl.com/scores/2016/REG'
for semana in lista_regular_season[0]:
  
    print "      " 
    print "      " 

    print "      " 
    print "Que semana esta: ", semana 
    print "      " 
    print "      " 
    print "      " 

    url_1er = 'http://www.nfl.com/scores/2016/REG'+str(semana)
    
    print url_1er

    url_1er = 'http://www.nfl.com/scores/2016/REG'

            
    page_1era = urllib2.urlopen(url_1er)
            
    soup_1er = BeautifulSoup(page_1era, 'lxml')

    divicion_Diviciones = soup_1er.find_all('div',class_="new-score-box-wrapper" )
    
    quarters_total = soup_1er.find_all('p',class_="total-score" )
    if "--" in quarters_total:
      print "Este juego No se ha jugado"
      pass
    else:
      
      
        results_total = []
        results_first = []
        results_second = []
        results_third = []
        results_fourth = []
        nombres_equipos = []

        ### Total
        quarters_total = soup_1er.find_all('p',class_="total-score" )
        results_total.append([headers.get_text() for headers in quarters_total])
        results_total = results_total[0]


        ### nombre Equipo
        nombre_equipo= soup_1er.find_all('p',class_="team-name" )
        nombres_equipos.append([headers.get_text() for headers in nombre_equipo])
        nombres_equipos = nombres_equipos[0][2:]
        
        ### Primer cuarto
        first_qt = soup_1er.find_all('span',class_="first-qt" )
        results_first.append([data.get_text() for data in first_qt])
        results_first = results_first[0][2:]

        ### segundo cuarto

        second_qt = soup_1er.find_all('span',class_="second-qt" )
        results_second.append([data.get_text() for data in second_qt])
        results_second = results_second[0][2:]

        ### tercer cuarto

        third_qt = soup_1er.find_all('span',class_="third-qt" )
        results_third.append([data.get_text() for data in third_qt])
        results_third = results_third[0][2:]

        ### cuarto cuarto

        fourth_qt = soup_1er.find_all('span',class_="fourth-qt" )
        results_fourth.append([data.get_text() for data in fourth_qt])
        
        ## Debo cambiar la linea anterior para obtener 1 sola lista 😀
        results_fourth = results_fourth[0][2:]





        i = 0
        for datos in nombres_equipos:
                print "Nombre Equipo", datos
                primer_cuarto =  results_first[i]
                primer_cuarto =  int(primer_cuarto)
        

                segundo_cuarto = results_second[i]
                segundo_cuarto =  int(segundo_cuarto)

        
                tercer_cuarto =  results_third[i]
                tercer_cuarto =  int(tercer_cuarto)

        
                cuarto_cuarto =  results_fourth[i]
                cuarto_cuarto =  int(cuarto_cuarto)
                print "1er Cuarto:  ", primer_cuarto,"2do Cuarto:  " ,segundo_cuarto,"3er Cuarto:  ", tercer_cuarto,"4to Cuarto:  ", cuarto_cuarto
        

                total_total = primer_cuarto + segundo_cuarto +tercer_cuarto + cuarto_cuarto
                total = results_total[i]
                
                print "Total", total_total
        
        
        

                i += 1

No hay mucho que comentar solo que la pagina usada para extraer los datos es http://www.nfl.com/scores/2016/REG y se le agrega un numero que corresponde a la semana o jornada de la temporada…

También la linea data.get_text() debo modificarla para hacer el código mas viable 😀

Las otras partes son faciles de entender si has seguido mis entradas 😀

Hasta luego Feliz Dia y que Dios te Bendiga

Pensando en la Proxima entrada y cosas que nos quedan por hacer en Python

Les cuento que esta semana he estado trabajando Full Time programando en Openerp v7, aunque me gustaría subir por lo menos el vídeo de lo que hice debo preguntar si puedo :S… mas o menos los tiros van así, he estado rehaciendo una API de una Aerolinea para extraer los datos de unos archivos llamados PNR, vaya que ni me imaginaba ese mundillo :S, al final todo salio bien gracias a Dios con muchos momentos de frustración al estar en terreno desconocido, pero al final corrió el código y aunque le faltan bastantes detalles(esto es bueno por que tengo trabajo :D) ya esta consumiendo los archivos en cuestión 😀

Debo comunicarles que me he decidido implementar la Base de Datos directamente a ODOO, les hablo del scrapping de la NFL que estaba haciendo, les cuento que tengo mas de 1 semana con una Otitis terrible y ya Gracias a Dios se me esta pasando, Voy a implementarla directamente en ODOO por que asi tendremos un mapeo de la base de datos y vistas interesantes en ODOO ojo que pronto subo un Vídeo 😀

Voy a ir subiendo Vídeos de entradas anteriores para los que no les gusta leer(aunque háganlo un habito :D), voy a comenzar con un Cursito de Python para Dummies en vídeo, así como también un vídeo de buenas practicas debugueando código en python si Dios nos lo permite claro 😀

Hay varias series que hay que retomar si o si, pero ahora trabajo 8 horas al día, y otras 3 copadas, mas 2 en otros proyectos me quedan como 3 libres :S bueno algo haré :D, por ejemplo Criptografia, APIS le tengo el ojo a Google :D, entre otras……. hay bastante que elegir en este blog :S

Bueno hasta aquí esta micro entrada informativa, me despido que Dios les bendiga les ilumine sus pasos y les de discernimiento…

Manejando SQL (Sqlite3) en Python [Parte 1]

Les cuento he estado haciendo algunas pruebas para optar en un trabajo en BairesDev y de verdad me he dado cuenta que me faltan conocimientos en: Javascript, Jquery(claro), SQL y algunos otros pero no tanto como en estas 3, podría trabajar en un proyecto pero mas pronto que tarde tendría que estar buscando la manera de hacer algo que nunca he hecho en estos 3 lenguajes(por darles un nombre) y tendría que recurrir a libros o ayuda online lo que retrasaría un poco mi desempeño, es por esto que voy a comenzar esta serie, ya que estoy leyendo este tutorial de SQL http://sql-principiantes.blogspot.com/ claro que entiendo el código pero aveces se me olvida y el manual esta dirigido a Windows, y también algunos de Python y sqlite3 :S por lo que decidí crear la entrada para tener la información y practicar….

El primer código consiste en crear una Base de Datos e insertar unos datos aquí el código, que con los conocimientos obtenidos en La especialización de python Genere(Claro vamos a ir haciéndole mejoras :D):


import sqlite3

conn = sqlite3.connect('empresa.sqlite3')

cur = conn.cursor()

cur.execute('DROP TABLE IF EXISTS personas ')
cur.execute('''CREATE TABLE Personas ( id INTEGER PRIMARY KEY AUTOINCREMENT, Nombre char(20) NOT NULL, Apellidos char(30) NOT NULL, Direccion char(40) NOT NULL, Ciudad char(10) NOT NULL) ''')

cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Marco Antonio','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Martha Beatriz','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Juana Elvira','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Nora Zulma','Trejo Lemus','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Laura Lucero','Sobrevilla Trejo','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Maria de la luz','Trejo Campos','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Trinidad','Trejo Bautista','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)',('Marcel Abisag','Sobrevilla Trejo','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Jose Abraham','Sobrevilla Trejo','Calle E 822','Tampico') )
cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', ('Samuel Salomon','Olmeda Trejo','Calle E 822','Tampico'))
cur.execute('select * from Personas')

for row in cur:
print row

conn.close()

Recuerda esto es python y esta es la salida:

(1, u'Marco Antonio', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(2, u'Martha Beatriz', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(3, u'Juana Elvira', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(4, u'Nora Zulma', u'Trejo Lemus', u'Calle E 822', u'Tampico')
(5, u'Laura Lucero', u'Sobrevilla Trejo', u'Calle E 822', u'Tampico')
(6, u'Maria de la luz', u'Trejo Campos', u'Calle E 822', u'Tampico')
(7, u'Trinidad', u'Trejo Bautista', u'Calle E 822', u'Tampico')
(8, u'Marcel Abisag', u'Sobrevilla Trejo', u'Calle E 822', u'Tampico')
(9, u'Jose Abraham', u'Sobrevilla Trejo', u'Calle E 822', u'Tampico')
(10, u'Samuel Salomon', u'Olmeda Trejo', u'Calle E 822', u'Tampico')

Ya logramos una parte del ejercicio pero en python siempre hay una manera mas fácil de hacer las cosas :D, si por ejemplo tenemos los datos en una lista y los vamos agregando así:


import sqlite3

conn = sqlite3.connect('empresa.sqlite3')

cur = conn.cursor()

cur.execute('DROP TABLE IF EXISTS personas  ')


cur.execute('''CREATE TABLE Personas ( id INTEGER PRIMARY KEY AUTOINCREMENT, Nombre char(20) NOT NULL, Apellidos char(30) NOT NULL, Direccion char(40) NOT NULL, Ciudad char(10) NOT NULL) ''')


datos = [
    ('Marco Antonio','Trejo Lemus','Calle E 822','Tampico'),
    ('Martha Beatriz','Trejo Lemus','Calle E 822','Tampico'),
    ('Juana Elvira','Trejo Lemus','Calle E 822','Tampico'),
    ('Nora Zulma','Trejo Lemus','Calle E 822','Tampico'),
    ('Laura Lucero','Sobrevilla Trejo','Calle E 822','Tampico'),
    ('Maria de la luz','Trejo Campos','Calle E 822','Tampico'),
    ('Trinidad','Trejo Bautista','Calle E 822','Tampico'),
    ('Marcel Abisag','Sobrevilla Trejo','Calle E 822','Tampico'),
    ('Jose Abraham','Sobrevilla Trejo','Calle E 822','Tampico'),    
    ('Samuel Salomon','Olmeda Trejo','Calle E 822','Tampico'),
]
for dato in datos:
    cur.execute('INSERT INTO Personas (Nombre,Apellidos,Direccion,Ciudad) VALUES ( ?,? , ?, ?)', dato)
  


cur.execute('select * from Personas')

for row in cur:
    print row

conn.close()


La salida es la misma solo quería agregarlos datos con un ciclo for sin necesidad de agregar linea por linea, aunque ya algo hemos visto en la otra serie de Twitter, les recuerdo que voy a comenzar  a hablar  de Javascript en el blog y en un futuro cercano colocar algunas entradas en ingles 😀

Saludos Dios les Bendiga e Ilumine sus caminos

 

De Json a Histogramas con Matplotlib[Parte 1]

Al pensar en crear gráficas con los datos de la API de Twitter, estaba meditando en que serie de este Blog colocar esta tan interesante entrada y me dije por que no crear una serie nueva para que las personas que no estén interesadas en la API de Twitter puedan disfrutar del código que aquí voy a exponer:

 
### Autor Cesar Chirinos
### Fecha 22 Agosto 2016
### publicado en https://stickybitshell.wordpress.com/2016/08/22/de-json-a-histogramas-con-matplotlibparte-1-2/


### http://pybonacci.org/tag/tutorial-matplotlib-pyplot/

### http://python-para-impacientes.blogspot.com/2014/08/graficos-en-ipython.html
from collections import Counter

from prettytable import PrettyTable

import matplotlib.pyplot as plt

import numpy as np 


hashtags = [u'Deportes', u'Rio2016', u'YoRio', u'YoRio', u'Soyfandelupita', u'Paralimpicos', u'YoRio', u'fb', u'olimpiadas', u'yorio', u'vacaciones', u'tirolesas', u'YoRio', u'Tokio2020', u'YoRio', u'YoRio', u'YoRio', u'YoRio', u'Oro', u'YoRio', u'yorio', u'YoRio', u'YoRio', u'YoRio', u'yoRio', u'olympics', u'YoRio', u'YoRioxESPN', u'yoRio', u'GraciasRioPor', u'Rio2016', u'YoRio', u'YoRioxESPN', u'yorio', u'JuegosOlimpicos', u'GraciasRioPor', u'YoRio', u'YoRioxESPN', u'Rio2016', u'GraciasRio', u'Tokio2020', u'YoRio', u'GraciasRioPor', u'YoRio', u'Rio2016', u'JuegosOlimpicosRio2016', u'YoR\xedo', u'YoRio', u'paraolimpiadas', u'YoRio', u'YoRio', u'AndresBustamante', u'Tokio2020', u'YoRio', u'TodosSomosSuiza', u'TodosSomosTercerSet', u'YoRio', u'YoRio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'yorio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'YoRio', u'Japon2020', u'YoRio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'YoRioxESPN', u'YoR\xedo', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'GraciasRioPor', u'YoRioxESPN', u'YoRio', u'GraciasRioPor', u'YoRio', u'YoRioxESPN', u'YoRio', u'rioxespn', u'YoRio', u'YoRio', u'YoRioxESPN', u'olimpicosrio2016', u'ESPN', u'YoRio', u'balondividido', u'YoRioxESPN', u'YoRio', u'rio2016', u'olympics', u'olympics2016', u'paralimpico', u'paralimpic', u'goo', u'yorioxespn', u'yorio', u'YoRio', u'YoRio', u'Rio2016', u'CeremoniaDeClausura', u'Tokio2020', u'RiotoTokyo', u'oro', u'Plata', u'Bronce', u'Olympics', u'YoRioxESPN', u'YoRio', u'YoRio', u'YoRio', u'Leyendas', u'IAmTheMan', u'YoRio', u'Rio2016', u'Olympics', u'R\xedo', u'RiodeJaneiro', u'Brasil', u'YoRio', u'Ol\xedmpicos', u'ESPN', u'YoRio', u'YoRioxESPN', u'YoRioxESPN', u'ESPN', u'GraciasRioPorESPN', u'YoRio', u'yorio', u'YoRioxESPN', u'condicional', u'yorio', u'YoRio', u'CeremoniaDeClausura', u'YoRio', u'GraciasRio', u'Tokio2020', u'YoRio', u'YoRio', u'yo', u'GraciasRio', u'Tokio2020', u'YoRio', u'YoRio', u'tokio2020', u'yorio', u'juegosolimpicos', u'Brasil', u'Brasil', u'YoRio', u'YoRio', u'yorio', u'YoRio', u'Fail', u'yorio', u'YoRioxESPN', u'yorio', u'YoRio', u'CeremoniaDeClausura', u'YoRio', u'YORIO', u'YoRio', u'YoR\xedo', u'YoRio', u'MX', u'yorio', u'Rio2016', u'YoRio', u'YoRioxESP', u'COL', u'Rio2016', u'YoRio', u'OlimpiadeRio2016', u'YoRio', u'YoRio', u'YoRio', u'YoRei', u'YoReire', u'Rio2016', u'CeremoniaDeClausura', u'YoRio', u'Rio2016', u'freethenipples', u'yoRio', u'YoRio', u'CeremoniaDeClausura', u'YoRio', u'Olimp\xedadas', u'YoRio', u'YoRio', u'Yo_corro', u'nikeplus', u'YoRio', u'YoRio', u'YoRio', u'R\xedo', u'RiodeJaneiro', u'Brasil', u'YoRio', u'Ol\xedmpicos', u'YoRio', u'YoRio', u'YoRio', u'Tokio2020', u'JuegosOlimpicos', u'yorio', u'YoRioxESPN', u'YoR\xedo', u'TuR\xedes', u'ElR\xede', u'EllaR\xede', u'EllosR\xeden', u'NosotrosRe\xedmos', u'UstedesR\xeden', u'Rio2016', u'Tokio2020', u'Tokio2020', u'CeremoniadeClausura', u'Rio2016xFOX', u'YoRio', u'Rio2016', u'JuegosOlimpicos', u'YoRioxESPN', u'YoLloro', u'YoRio', u'YoRio', u'YoRio']

screen_names = [u'ESPNmx', u'ESPNmx', u'ClaroSports', u'ClaroSports', u'ESPNmx', u'Faitelson_ESPN', u'Palomo_ESPN', u'espn', u'Rio2016', u'9GAG', u'joserra_espn', u'ESPNmx', u'werevertumorro', u'Faitelson_ESPN', u'ESPNmx', u'espn', u'ESPNmx', u'joserra_espn', u'chockoleiro', u'espn', u'EddyRios_', u'AnaGGuevara', u'Faitelson_ESPN', u'joapeca', u'TheMorrisMx', u'EPN', u'mexico', u'ESPNmx', u'ESPNmx', u'SoyUnStrapp', u'joserra_espn', u'MichaelPhelps', u'usainbolt', u'Deb_Estrella', u'AstroTerry', u'ESPNArgentina', u'espn', u'PresidenciaMX', u'CONADE', u'chockoleiro', u'joserra_espn', u'Faitelson_ESPN', u'joapeca', u'TheMorrisMx', u'EPN', u'mexico', u'ESPNmx', u'TheMorrisMx', u'EPN', u'mexico', u'YodaFath', u'EPN', u'mexico', u'CanalOnce11', u'joserra_espn', u'DavidFailtelson', u'ESPNmx', u'Lemocarv', u'PachoBenitezGol', u'ESPNmx', u'joserra_espn', u'CarolinaPadron', u'mauriciopedroza', u'Palomo_ESPN', u'cprocuna', u'paugr', u'puig_ricardo', u'Faitelson_ESPN', u'joserra_espn', u'Faitelson_ESPN', u'NTelevisa_com', u'CarlosLoret', u'espn', u'ElPrincipeDice', u'EPN', u'Wmichell', u'pelud0wn', u'EPN', u'giss1209', u'Deb_Estrella', u'AstroTerry', u'Javo__O', u'EPN', u'mexico', u'moriuper', u'giss1209']

words = [u'Si', u'estamos', u'hablando', u'de', u'#Deportes', u'tenemos', u'que', u'decir', u'#Rio2016', u'Los', u'Mejores', u'momentos', u'de', u'#YoRio', u'https://t.co/U9svEFTjfS', u'@ESPNmx', u'#YoRio', u'mi', u'momento:', u'la', u'plata', u'de', u'Lupita!', u'#Soyfandelupita', u'Terminaron', u'Ios', u'JJOO,', u'espero', u'que', u'@ESPNmx', u'y', u'@ClaroSports', u'transmitan', u'los', u'#Paralimpicos', u'de', u'la', u'misma', u'manera', u'#YoRio', u'#fb', u'https://t.co/OcJTLCUZIb', u'#olimpiadas', u'#yorio', u'#vacaciones', u'#tirolesas', u'https://t.co/g1TMTsUMzd', u'Gracias', u'@ClaroSports', u'por', u'mantenernos', u'tan', u'cerca', u'de', u'R\xedo,', u'lo', u'que', u'no', u'vi', u'por', u'TV', u'lo', u'vi', u'desde', u'su', u'gran', u'App.', u'#YoRio', u'nos', u'vemos', u'en', u'#Tokio2020', u'\U0001f3c5', u'Gracias', u'Rio!', u'#YoRio', u'@ESPNmx', u'#YoRio', u'emotivo', u'mensaje', u'del', u'final', u'de', u'R\xedo', u'2016', u'narrando', u'por', u'@Faitelson_ESPN.', u'Como', u'siempre', u'haciendo', u'un', u'excelente', u'trabajo,', u'gracias', u'ESPN!', u'viendo', u'la', u'clausura', u'de', u'los', u'juegos', u'Ol\xedmpicos', u'con', u'alitas!', u'(no', u'puedo', u'escuchar', u'porque', u'tienen', u'a', u'todo', u'volumen', u'la', u'musica', u'en', u'el', u'restaurante)', u'#YoRio', u'Misi\xf3n', u'cumplida', u'@Palomo_ESPN', u'#YoRio', u'@espn', u'@Rio2016', u'\U0001f44f', u'\U0001f1e7\U0001f1f7', u'#Oro', u'\U0001f44f', u'Juegos', u'Paral\xedmpicos', u'de', u'Rio', u'2016,', u'un', u'encanto', u'de', u'video', u'<3', u'#YoRio', u"We're", u'The', u'Superhumans', u'|', u'Rio', u'Paralympics', u'2016', u'https://t.co/fmqPZMlQbK', u'C\xf3mo', u'busco', u'al', u'tr\xedo?', u'quiero', u'esa', u'rola', u'#yorio', u'#YoRio', u'-', u'Best', u'celebration', u'ever', u'https://t.co/6x2Jd6soPk', u'v\xeda', u'@9GAG', u'@joserra_espn', u'@ESPNmx', u'incluido', u'el', u'@werevertumorro', u'o', u'a', u'ese', u'hijo', u'lo', u'sigues', u'desconociendo???', u'Ah,', u'solo', u'@Faitelson_ESPN', u'lo', u'chikiteas!', u'#YoRio', u'Excelente', u'cobertura', u'#YoRio', u'ESPN,', u'la', u'mejor', u'que', u'haya', u'visto', u'en', u'ol\xedmpicos', u'Pocas', u'cosas', u'como', u'los', u'deportes', u'generan', u'tantas', u'y', u'tantas', u'emociones', u'que', u'actualmente', u'necesitamos', u'para', u'no', u'olvidar', u'quienes', u'somos.', u'#yoRio', u'#olympics', u'hace', u'tanto', u'que', u'no', u've\xeda', u'una', u'cobertura', u'tan', u'buena', u'de', u'unos', u'Juegos', u'Ol\xedmpicos.', u'Felicidades', u'@ESPNmx', u'Maravilloso', u'programa', u'#YoRio', u'#YoRioxESPN', u'\U0001f44f\U0001f3fc\U0001f44f\U0001f3fc\U0001f44f\U0001f3fc', u'Vi', u'lo', u'mejor', u'en', u'#yoRio', u'21', u'd\xedas', u'Juegos', u'Ol\xedmpicos', u'cerca', u'del', u'mar', u'nadie', u'me', u'lo', u'va', u'borrar', u'#GraciasRioPor', u'esas', u'panor\xe1micas', u'extraordinarias', u'de', u'#Rio2016', u'trabajo', u'de', u'@espn.Belleza', u'total.Arrobo.Excelente', u'transmisi\xf3n.', u'#YoRio', u'#YoRioxESPN', u'#yorio', u'voy', u'a', u'extra\xf1ar', u'no', u'volver', u'a', u'ver', u'nunca', u'm\xe1s', u'el', u'monopolio', u'televisivo', u'gracias', u'@ESPNmx', u'magn\xedfica', u'transmisi\xf3n', u'mis', u'8vos', u'#JuegosOlimpicos', u'tnks', u'#GraciasRioPor', u'palabras', u'hermosas', u'de', u'@joserra_espn', u'"Unos', u'Juegos', u'profundamente', u'hermosos,de', u'cara', u'al', u'mar."', u'Gracias', u'#YoRio', u'#YoRioxESPN', u'#Rio2016', u'RT', u'@chockoleiro:', u'#GraciasRio', u'ahora', u'a', u'esperar', u'a', u'#Tokio2020', u'suena', u'bien,', u'no?', u'#YoRio', u'https://t.co/xxJQJlIze4', u'#GraciasRioPor', u'que', u'lloro', u'de', u'emoci\xf3n', u'con', u'#YoRio', u'de', u'despedida.', u'Excelente', u'@espn', u'\xa1Nunca', u'me', u'olvidar\xe9', u'de', u'#Rio2016', u'#JuegosOlimpicosRio2016!', u'Nada', u'malos', u'esos', u'cantores', u'en', u'#YoR\xedo,', u'no', u'los', u'conoc\xeda.', u'#YoRio', u'waoo', u'que', u'momentos', u'vivieron', u'estos', u'atletas,', u'me', u'siento', u'triste', u'porque', u'ay', u'que', u'esperar', u'4', u'a\xf1os'
, u'mas', u'para', u'ver', u'estos', u'atletlas', u'hacer', u'historia', u'Nunca', u'he', u'estado', u'de', u'acuerdo', u'en', u'q', u'apaguen', u'la', u'llama', u'olimpica', u'si', u'siguen', u'las', u'#paraolimpiadas', u'#YoRio', u'Ya', u'falto', u'el', u'g\xfciri', u'g\xfciri', u'en', u'los', u'#YoRio', u'y', u'si', u'hace', u'un', u'canal', u'de', u'YouTube', u'#AndresBustamante', u'para', u'#Tokio2020', u'#YoRio', u'lo', u'que', u'm\xe1s', u'me', u'gust\xf3', u'fue', u'#TodosSomosSuiza', u'y', u'#TodosSomosTercerSet', u'haaaaaaaaa....', u'que', u'maravilla....', u'RT', u'@EddyRios_:', u'Tuve', u'la', u'oportunidad', u'de', u'comenzar', u'con', u'#YoRio', u'desde', u'enero', u'y', u'tristemente', u'no', u'pude', u'concluir.', u'A\xfan', u'as\xed', u'fue', u'una', u'gran', u'experiencia', u'que\u2026', u'Tuve', u'la', u'oportunidad', u'de', u'comenzar', u'con', u'#YoRio', u'desde', u'enero', u'y', u'tristemente', u'no', u'pude', u'concluir.', u'A\xfan', u'as\xed', u'fue', u'una', u'gran', u'experiencia', u'que', u'me', u'dej\xf3', u'mucho.', u'#GraciasRioPor', u'hacerme', u'parte', u'de', u'la', u'historia', u'\xa1Los', u'viv\xed,los', u'viv\xed!', u'La', u'emocion', u'de', u'ver', u'grandes', u'leyendas', u'del', u'deporte', u'despedirse', u'#YoRioxESPN', u'#YoRio', u'@AnaGGuevara', u'@Faitelson_ESPN', u'excelente', u'transmisi\xf3n', u'en', u'#yorio', u'esperemos', u'puedas', u'ayudar', u'al', u'deporte', u'de', u'mx,', u'eres', u'la', u'ideal', u'para', u'dirigir', u'el', u'rumbo!', u'#GraciasRioPor', u'Ver', u'tanta', u'belleza', u'interna', u'y', u'externa', u'de', u'hombres', u'y', u'mujeres', u'\xa1Y', u'esos', u'tacos', u'de', u'ojo', u'con', u'tanto', u'guapo!', u'Por', u'qu\xe9', u'no', u'#YoRioxESPN', u'#YoRio', u'Pues', u'se', u'nos', u'termino', u'#YoRio', u'nos', u'vemos', u'en', u'#Japon2020', u'\U0001f44d', u'RT', u'@joapeca:', u'@TheMorrisMx', u'A', u'las', u'diez', u'mis', u'@EPN', u'Boots,a', u'las', u'diez,@mexico', u'no', u'debe', u'saber', u'que', u'yo', u'soy', u'uno', u'de', u'ustedes', u'#YoRio', u'https://t.co/26YdPZVk\u2026', u'#GraciasRioPor', u'\xa1Hacerme', u'VIVIR', u'Y', u'VIBRAAARRR!', u'\xa1Esas', u'finales', u'de', u'nerrrrvios!', u'Gracias', u'hermanos', u'de', u'Brasil', u'po', u'su', u'gran', u'esfuerzo', u'#YoRioxESPN', u'#YoRio', u'@ESPNmx', u'gracias', u'por', u'llevarnos', u'una', u'transmisi\xf3n', u'de', u'primer', u'nivel', u'de', u'los', u'juegos', u'ol\xedmpicos', u'esperemos', u'que', u'en', u'4', u'a\xf1os', u'vuelvan', u'#YoRioxESPN', u'#YoR\xedo', u'#GraciasRioPor', u'motivarme,', u'ense\xf1arme,', u'por', u'el', u'paseo', u'hermoso', u'por', u'R\xedo,', u'sentir', u'que', u'ah\xed', u'estaba', u'apoyando', u'a', u'los', u'j\xf3venes', u'atletas.', u'#YoRioxESPN', u'#YoRio', u'#GraciasRioPor', u'hacerme', u'emocionarme', u'hasta', u'las', u'l\xe1grimas', u'al', u'ver', u'a', u'nuestros', u'j\xf3venes', u'atletas', u'triunfando', u'\xa1Me', u'motiva', u'tanto!', u'#YoRioxESPN', u'#YoRio', u'#GraciasRioPor', u'hacerme', u'saber', u'que', u'nunca', u'es', u'tarde', u'para', u'superarme', u'a', u'm\xed', u'misma', u'y', u'motivarme', u'a', u'trabajar', u'y', u'luchar.#YoRio', u'#YoRioxESPN', u'Thanks', u'ESPN', u'FOR', u'#YoRio', u'2016...muchas', u'gracias', u'@ESPNmx', u'tip', u'para', u'el', u'futuro:', u'no', u'metan', u'comerciales', u'en', u'las', u'ceremonias,', u'cualquiera', u'que', u'sea...los', u'himnos', u'tambi\xe9n', u'son', u'importantes', u'#rioxespn', u'#YoRio', u'@SoyUnStrapp', u'Dicen', u'que', u'las', u'imagenes', u'dicen', u'mas', u'que', u'un', u'mill\xf3n', u'de', u'Twitters,', u'\xbfO', u'no?', u'Por', u'eso', u'#YoRio', u'https://t.co/xGBDzyhiAF', u'Gracias', u'#YoRioxESPN', u'Por', u'llevarme', u'a', u'Los', u'#olimpicosrio2016', u'a', u'travez', u'de', u'la', u'pantalla', u'de', u'mi', u'TV!', u'\u26bd\U0001f6b4\U0001f3c7\U0001f3c0\u26be\U0001f3ca\U0001f3be\U0001f46f', u'#ESPN', u'#YoRio', u'#balondividido', u'#YoRioxESPN', u'#YoRio', u'https://t.co/TpkZOA37IU', u'#rio2016', u'#olympics', u'#olympics2016', u'#paralimpico', u'#paralimpic', u'\
u263a\U0001f64c\U0001f64b\u2764\U0001f44d\u270c\U0001f44b', u'#goo', u'#yorioxespn', u'#yorio\u2026', u'https://t.co/Dei7iL0Ukk', u'RT', u'mauriciopedroza:', u'Por', u'entrar', u'con', u'joserra_espn', u'y', u'Faitelson_ESPN', u'a', u'hablar', u'de', u'lo', u'que', u'nos', u'dej\xf3', u'la', u'nataci\xf3n', u'en', u'#YoRio\u2026', u'https://t.co/RnDcBAS4hJ', u'#YoRio', u'#Rio2016', u'#CeremoniaDeClausura', u'#Tokio2020', u'#RiotoTokyo', u'#oro', u'#Plata', u'#Bronce', u'#Olympics', u'#YoRioxESPN', u'https://t.co/Ai6g6U80rQ', u'Esta', u'semana', u'muchos', u'tendremos', u'sindrome', u'de', u'abstinencia', u'olimpica', u'#YoRio', u'RT', u'mauriciopedroza:', u'Por', u'entrar', u'con', u'joserra_espn', u'y', u'Faitelson_ESPN', u'a', u'hablar', u'de', u'lo', u'que', u'nos', u'dej\xf3', u'la', u'nataci\xf3n', u'en', u'#YoRio\u2026', u'https://t.co/dHr01K1ted', u'@joserra_espn', u'#YoRio', u'gran', u'video', u'de', u'@MichaelPhelps', u'@usainbolt', u'subanlo', u'a', u'youtube', u'#Leyendas', u'#IAmTheMan', u'#YoRio', u'\U0001f64f\U0001f3fc\U0001f622', u'#Rio2016', u'#Olympics', u'RT', u'@Deb_Estrella:', u'#R\xedo', u'#RiodeJaneiro', u'#Brasil', u'desde', u'el', u'espacio.', u'Soberbia', u'foto', u'del', u'astronauta', u'@AstroTerry', u'#YoRio', u'#Ol\xedmpicos', u'https://t.co/YyAC\u2026', u'Siempre', u'los', u'programas', u'y', u'las', u'cadenas', u'donde', u'este', u'joserra', u'ser\xe1n', u'los', u'mejores', u'#ESPN', u'#YoRio', u'#YoRioxESPN', u'\U0001f44b\U0001f3fd\U0001f63f', u'#YoRioxESPN', u'Gracias', u'Totales!', u'Cobertura', u'de', u'clase', u'mundial,', u'ORO', u'para', u'#ESPN', u'#GraciasRioPorESPN', u'#YoRio', u'@ESPNArgentina', u'#yorio', u'#YoRioxESPN', u'una', u'verg\xfcenza', u'la', u'conductora', u'ri\xe9ndose', u'de', u'la', u'ca\xedda', u'del', u'corredor,', u'una', u'falta', u'de', u'respeto', u'incre\xedble', u'\U0001f621\U0001f621\U0001f621', u'Me', u'gustar\xeda', u'que', u'@ESPN', u'se', u'exprese,', u'como', u'se', u'expresa', u'y', u'habla', u'de', u'Phelps,', u'de', u'los', u'paral\xedmpicos', u'en', u'especial', u'de', u'Gustavo', u'S\xe1nchez', u'#condicional', u'#yorio', u'@PresidenciaMX', u'Han', u'promovido', u'tanto', u'al', u'SNA', u'que', u'aparte', u'del', u'departamento', u'de', u'la', u'Gaviota', u'el', u'fracaso', u'de', u'@CONADE', u',Si', u'no', u'impera', u'la', u'impunidad', u'#YoRio', u'Ya', u'las', u'vi', u'criticando', u'la', u'clausura,', u'como', u'si', u'hubieran', u'uds.', u'Tenido', u'una', u'mejor', u'idea,', u'que', u'esperaban!?', u'Es', u'Rio.', u'#CeremoniaDeClausura', u'#YoRio', u'RT', u'@chockoleiro:', u'#GraciasRio', u'ahora', u'a', u'esperar', u'a', u'#Tokio2020', u'suena', u'bien,', u'no?', u'#YoRio', u'https://t.co/xxJQJlIze4', u'@joserra_espn', u'eres', u'grande', u'y', u'que', u'bueno', u'q', u'callas', u'a', u'@Faitelson_ESPN', u'#YoRio', u'#yo', u'#GraciasRio', u'ahora', u'a', u'esperar', u'a', u'#Tokio2020', u'suena', u'bien,', u'no?', u'#YoRio', u'https://t.co/xxJQJlIze4', u'RT', u'@joapeca:', u'@TheMorrisMx', u'A', u'las', u'diez', u'mis', u'@EPN', u'Boots,a', u'las', u'diez,@mexico', u'no', u'debe', u'saber', u'que', u'yo', u'soy', u'uno', u'de', u'ustedes', u'#YoRio', u'https://t.co/26YdPZVk\u2026', u'"Ah\xed', u'podemos', u'ver', u'la', u'bandera', u'de', u'Chihuahua"', u'Gracias', u'a', u'todos', u'los', u'cronistas', u'de', u'@espnmx', u'#tokio2020', u'#yorio', u'Se', u'acabaron', u'los', u'#juegosolimpicos', u'#Brasil', u'd', u'retos,', u'nostalgia,', u'admiraci\xf3n,', u'esfuerzo,', u'oportunidades,', u'talentos,', u'festejos.', u'Gracias', u'#Brasil', u'#YoRio', u'@TheMorrisMx', u'A', u'las', u'diez', u'mis', u'@EPN', u'Boots,a', u'las', u'diez,@mexico', u'no', u'debe', u'saber', u'que', u'yo', u'soy', u'uno', u'de', u'ustedes', u'#YoRio', u'https://t.co/26YdPZVkbj', u'#yorio', u'gracias', u'x', u'esos', u'juegos', u'tan', u'maravillosos', u'e', u'inolvidables', u'\U0001f1e7\U0001f1f7\U0001f1e7\U0001f1f7\U0001f1e7\U0001f1f7', u'@YodaFath', u'Pobres', u'@EPN', u'Boots', u'el', u'felicita', u'a', u'los', u'atletas', u'y', u'ustedes', u'a', u'el,\
xa1que', u'veo', u'si', u'si', u'compiti\xf3', u'por', u'@mexico', u'!', u'#YoRio', u'https://t.co/jznPQI8PfD', u'Quien', u'es', u'el', u'comunicador', u'de', u'@CanalOnce11', u'que', u'esta', u'en', u'contra', u'de', u'la', u'clausura', u'de', u'los', u'JO?', u'Osea', u'es', u'una', u'fiesta', u'mundial', u'#Fail', u'canal', u'11', u'Bien', u'#yorio', u'#YoRioxESPN', u'#yorio', u'porque', u'siempre', u'estan', u'de', u'pleito', u'@joserra_espn', u'y', u'@DavidFailtelson', u'https://t.co/NxaCn7jB8T', u'#YoRio', u'Se', u'acabaron', u'los', u'juegos', u'#CeremoniaDeClausura', u'#YoRio', u'volvamos', u'a', u'la', u'lucha', u'diaria,', u'esperemos', u'4', u'a\xf1os.', u'https://t.co/JXhJF8LnKJ', u'@ESPNmx', u'LA', u'NETA,', u'LA', u'NETA...', u'EXCELENTE', u'COBERTURA', u'LA', u'QUE', u'GENER\xd3', u'ESPN;', u'ENHORABUENA.', u'#YORIO', u'RT', u'@Lemocarv:', u'@PachoBenitezGol', u'gran', u'trabajo', u'en', u'#YoRio', u'comentarios', u'claros', u'profesionales', u'excelente', u'cobertura', u'y', u'sobre', u'todo', u'la', u'emoci\xf3n', u'@ESPNmx', u'#YoR\xedo', u'@joserra_espn', u'@CarolinaPadron', u'@mauriciopedroza', u'@Palomo_ESPN', u'@cprocuna', u'@paugr', u'@puig_ricardo', u'@Faitelson_ESPN', u'GRACIAS!!!', u'#YoRio', u'@joserra_espn', u'@Faitelson_ESPN', u'excelentes', u'programas.', u'Los', u'esperamos', u'para', u're\xedr', u'en', u'Jap\xf3n.', u'@NTelevisa_com', u'@CarlosLoret', u'califiquen', u'con', u'datos,', u'desde', u'84', u'es', u'el', u'3er', u'mejor', u'resultado', u'de', u'#MX', u'y', u'el', u'5\xba', u'mejor', u'en', u'su', u'historia', u'#yorio', u'#Rio2016', u'Un', u'GRACIAS', u'Gigante', u'a', u'@ESPN', u'#YoRio', u'#YoRioxESP', u'porque', u'apoyaron', u'a', u'los', u'colombianos', u'#COL', u'con', u'el', u'coraz\xf3n', u'\u2764', u'en', u'todas', u'sus', u'transmisiones', u'#Rio2016', u'Y', u'ahora??', u'De', u'que', u'van', u'hablar???', u'#YoRio', u'Me', u'encant\xf3', u'la', u'apertura', u'pero', u'le', u'faltaba', u'carnaval...', u'Ahora', u'si!!!!', u'Hermoso', u'cierre!!!', u'#OlimpiadeRio2016', u'Felicidades', u'a', u'los', u'5', u'campeones,', u'por', u'sus', u'medallas', u'y', u'a', u'todos', u'los', u'que', u'nos', u'representaron,', u'por', u'su', u'gran', u'esfuerzo!', u'#YoRio', u'https://t.co/mPP7NWgZmS', u'@ElPrincipeDice', u'Jovenes', u'creativos', u'los', u'@EPN', u'Boots,en', u'el', u'mar', u'de', u'oportunidades', u'recibieron', u'la', u'suya', u'por', u'eso', u'#YoRio', u'https://t.co/9QCbKeWRix', u'#YoRio', u'#YoRei', u'y', u'#YoReire', u'con', u'#Rio2016', u'RT', u'@Wmichell:', u'Detallazo', u'homenajear', u'a', u'los', u'voluntarios!!.Los', u'casi', u'anonimos', u'que', u'hacen', u'funcionar', u'las', u'cosas', u'por', u'puro', u'coraz\xf3n!!', u'#CeremoniaDeClaus\u2026', u'\xbfEs', u'idea', u'm\xeda', u'o', u'el', u'cierre', u'de', u'#Rio2016', u'fue', u'una', u'dosis', u'de', u'#freethenipples?', u'#yoRio', u'Se', u'acabo', u'\U0001f622', u'#YoRio', u'Que', u'lujo', u'de', u'olimpiadas', u',', u'que', u'buena', u'#CeremoniaDeClausura', u'.', u'Felicidad!', u'#YoRio', u'A', u'esperar', u'otros', u'cuatro', u'a\xf1os', u'para', u'ver', u'las', u'#Olimp\xedadas...', u'#YoRio', u'Mientras', u'#YoRio', u'llega', u'a', u'su', u'fin', u'#Yo_corro....!!!', u'Acabo', u'de', u'correr', u'6.07', u'km', u'a', u'un', u'ritmo', u'de', u"5'13''", u'con', u'Nike+', u'https://t.co/Q2zB6vsQsd', u'#nikeplus', u'Los', u'veo', u'en', u'Tokio', u'#YoRio', u'@pelud0wn', u'Es', u'hermoso', u'ver', u'que', u'a', u'los', u'@EPN', u'Boots', u'les', u'gusta', u'lo', u'grande', u'lo', u'm\xe1s', u'grande,\xa1', u'lo', u'grandototote!', u'Por', u'eso', u'#YoRio', u'https://t.co/De5yikxL7E', u'RT', u'@giss1209:', u'Ser\xe1', u'que', u'el', u'de', u'ESPN', u'puede', u'dejar', u'de', u'hablar', u'de', u'M\xe9xico?', u'Es', u'Brazil', u'#YoRio', u'RT', u'@Deb_Estrella:', u'#R\xedo', u'#RiodeJaneiro', u'#Brasil', u'desde', u'el', u'espacio.', u'Soberbia', u'foto', u'del', u'astronauta', u'@AstroTerry', u'#YoRio', u'#Ol\xedmpicos', u'https://t.co/YyAC\u2026', u'El', u'pa\xeds', u'm\xe1s', u'alegre', u'y', u'
maravilloso', u'del', u'mundo', u',', u'despide', u'su', u'mega', u'evento', u'#YoRio', u'#YoRio', u'muy', u'buena', u'transmisi\xf3n,', u'esperemos', u'que', u'as\xed', u'sea', u'la', u'de', u'los', u'juegos', u'paralimpicos', u'@Javo__O', u'@EPN', u'\xa1Silencio', u'!', u'@mexico', u'los', u'ni\xf1os', u'est\xe1n', u'haciendo', u'su', u'tarea,mientras', u'les', u'tendr\xedamos', u'su', u'frutsi', u'#YoRio', u'https://t.co/SqT3PAH9wl', u'RT', u'@moriuper:', u'La', u'presentaci\xf3n', u'de', u'#Tokio2020', u'estuvo', u'demasiado', u'cool', u'#JuegosOlimpicos', u'#yorio', u'#YoRioxESPN', u'#YoR\xedo', u'#TuR\xedes', u'#ElR\xede', u'#EllaR\xede', u'#EllosR\xeden', u'#NosotrosRe\xedmos', u'#UstedesR\xeden', u'#Rio2016', u'#Tokio2020', u'https://t.co/LkE4azl1ZF', u'Si', u'la', u'presentaci\xf3n', u'de', u'#Tokio2020', u'fue', u'as\xed...', u'Ya', u'quiero', u'ver', u'la', u'inauguraci\xf3n.', u'#CeremoniadeClausura', u'#Rio2016xFOX', u'#YoRio', u'Pues', u'ya', u'se', u'acabo', u'#Rio2016', u'#JuegosOlimpicos', u'#YoRioxESPN', u'ahora', u'ser\xe1', u'#YoLloro', u'ya', u'no', u'es', u'#YoRio', u'#YoRio', u'el', u'cierre', u'de', u'los', u'juegosolimpicos', u'fue', u'mejor', u'que', u'el', u'opening...', u'RT', u'@giss1209:', u'Ser\xe1', u'que', u'el', u'de', u'ESPN', u'puede', u'dejar', u'de', u'hablar', u'de', u'M\xe9xico?', u'Es', u'Brazil', u'#YoRio']




coleccion_hashtags = Counter(hashtags).most_common()[:15]  ### de la lista hashtags importamos una lista de tuplas con las 15 palabras mas comunes

coleccion_screen_names = Counter(screen_names).most_common()[:15]  ### de la lista screen_names importamos una lista de tuplas con las 15 palabras mas comunes

coleccion_words = Counter(words).most_common()[:15]  ### de la lista words importamos una lista de tuplas con las 15 palabras mas comunes



count_coleccion_hashtags = len(coleccion_hashtags) ### Solo vamos a ver el grafico de los hashtags, por lo q contamos cuanttos elementos hay
diccionario = dict() # creamos el diccionario
i = 0 # inicializamos la variable
lista_nueva1 =[]   # creamos la lsita1
lista_nueva2 = []  # creamos la lsita2

for i in  range(0,count_coleccion_hashtags): # creamos el bucle for para pasar por cada uno de los elementos de hashtags
        
        llave = coleccion_hashtags[i][0]  ### Llamamos llave el primer elemento de la tupla para cada elemento de la lista, creo q esta es la parte dificil de programar saber que es que cosa en el codigo
        valor = coleccion_hashtags[i][1]  ### llamamos clave a el segundo elemento de la tupla para cada i
        
        ### Necesitamos 2 lsitas para graficar X y Y
        lista_nueva1.append(llave)     # Esta es la palabra
        lista_nueva2.append(valor)     # este es el numero de veces que aparece en la lista hashtags
        

posicion_y = np.arange(len(lista_nueva1))
plt.barh(posicion_y, lista_nueva2, align = "center")
plt.yticks(posicion_y, lista_nueva1)
plt.xlabel('Palabras')
plt.title("Numero de Repeticiones")
plt.show()


explode = [0.1, 0, 0, 0, 0, 0, 0, 0.1, 0.1, 0, 0, 0, 0, 0, 0.] # Para mi esto es lo mas importante de explicar por ejemplo ay 0 y 0,1
                                           ###  Los que son mayores que 0 se veran un poco mas separados y es una funcion para hacer notar algo
plt.pie(lista_nueva2, explode=explode, labels=lista_nueva1, autopct='%1.1f%%', shadow=True) # Aqui se construyte como queremos ver el Grafico
plt.title("Histograma de una clase Twitter", bbox={"facecolor":"0.8", "pad":5}) ### Este es el titulo
plt.legend()
plt.show()


En esta entrada decidí comentar lo mas interesante e importante del código…. En resumen, se crean 2 Gráficos de los Hashtags de la etiqueta #YoRio, aunque decidí colocar la lista que habíamos obtenidos de imprimir hashtags “print hashtags” del código de la entrada anterior, el primero es de barras y  el segundo es de Torta ademas se saca la fracción de cada elemento involucrado en el 100% o total de las palabras estudiadas que fueron 15 y no el total real….

Con esta entrada comenzamos esta serie en la que vamos solo a analizar las salidas de cada cuenta con el programa que vamos a ir construyendo en las otras series….

La salida de este programa es la siguiente:

grafico1

Al cerrar la ventana nos aparece este:

grafico2

De verdad es que me parece muy interesante ver los datos en gráficas par aprender mas 😀

Que Dios les Bendiga, hasta pronto, recuerda ahora puedes darle me gusta y ratear las entradas de este blog, ademas deja tus dudas en estos temas, podrían convertirse en algo interesante para otros…

Información de interés que a mi me pareció de mucha ayuda:

Pybonacci como siempre un sitio donde aprender y deleitarse con buenas practicas de Python: http://pybonacci.org/tag/tutorial-matplotlib-pyplot/

Python para impacientes, de aqui saque la forma de imprimir el grafico, no soy un experto en eso :S

http://python-para-impacientes.blogspot.com/2014/08/graficos-en-ipython.html

 

 

Jugando con la API de Twitter [Parte 4]

En esta entrada vamos a ver nuestras primeras tablas, no te emociones aun, vamos a ver como python le da formato a datos sencillos, aunque en la siguiente entrada si vamos a ver gráficos de lo que hemos ido haciendo hasta ahora con la otra serie que te recuerdo va paralela a esta Manejando los datos de la API Twitter en Python [Parte 1]  ademas aquí te tengo mi nuevo repositorio de GitHub que hasta ahora solo tiene 2 de las series del Blog pero las voy a ir subiendo poco a poco y para este año espero tener de 10 a 15 series en el repo, solo voy a subir repositorios míos no voy a hacer fork de ningún repo de otra persona, así que aquí esta mi nuevo repo: https://github.com/Seth-Root No me entusiasma mucho los 2 repos que he subido pero son los mas completos y el código esta interesante.

Bueno a lo que nos interesa, “PrettyTable es una biblioteca de Python sencilla para visualizar fácilmente los datos tabulares en un formato de tabla ASCII visualmente atractivo.

PrettyTable es una biblioteca de Python simple diseñada para que sea fácil y rápido para representar datos tabulares en las tablas ASCII visualmente atractivos. Se inspira en las tablas ASCII utilizados en la cáscara de psql de PostgreSQL. PrettyTable permite la selección de las columnas que se van a imprimir, la alineación independiente de columnas (izquierda o derecha o centrado) y la impresión de “sub-tablas” especificando un rango fila.”

Información de aquí

Como aun estamos con nuestros programas en linea de comandos, tenemos que buscar la manera de ver la salida lo mas interesante, fácil y educativa posible y es por esto que me he permitido colocar este formato aquí, ademas en el libro que venimos siguiendo de minando las web sociales tienen un ejemplo de esto y lo coloque aquí 😀

Vamos a visualizar los datos que podemos ver con el siguiente código:


import twitter, json

from collections import Counter

from prettytable import PrettyTable


# Datos de autenticacion
CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_SECRET = 'Datos de D'



auth = twitter.oauth.OAuth( OAUTH_TOKEN , OAUTH_SECRET, CONSUMER_KEY , CONSUMER_SECRET )

api = twitter.Twitter(auth=auth)

q =  '#yorio' # Coloca aqui la cuenta a estudiar


count = 100

search_results = api.search.tweets(q=q, count =count)

statuses = search_results['statuses']


  
retweet_counts = [status['retweet_count']
	 for status in statuses ]

status_texts = [status['text']
	 for status in statuses ]


screen_names = [user_mention['screen_name']
	 for status in statuses 
	     for user_mention in status ['entities']['user_mentions'] ]


hashtags = [hashtag['text']
	 for status in statuses 
	     for hashtag in status ['entities']['hashtags'] ]

words = [ w
	 for t in status_texts
	    for w in t.split()
  ]

for item in [words, screen_names, hashtags]:
    c = Counter(item)
    print c.most_common()[:20]
    print



for label, data in (('Word', words), ('Screen Name', screen_names), ('Hashtag', hashtags)):
    pt = PrettyTable(field_names=[label, 'Count'])
    c = Counter(data)
    [ pt.add_row(kv) for kv in c.most_common()[:20] ]
    pt.align[label], pt.align['Count'] = 'l', 'r' # Set column alignment
    print pt


    

La salida de este programa es sumamente importante, y consta de 2 partes interesantes para nosotros y debemos estudiarlas a fondo aunque aquí solo diré que las vamos a estudiar a fondo en la otra serie, lo que si me interesa tocar es los bloques de código del bucle for que generan esta salida


[(u'en', 103), (u'de', 76), (u'#YoRio', 73), (u'del', 62), (u'a', 61), (u'RT', 53), (u'Diego', 52), (u'Tendremos', 40), (u'a\xf1os', 40), (u'4to', 40), (u'lugar', 40), (u'NOCHE', 40), (u'22', 40), (u'fue', 40), (u'Con', 40), (u'lanzamiento', 40), (u'ESTA', 40), (u'Real.', 40), (u'#YoRioxESPN', 39), (u'martillo.', 34)]

[(u'Leonlec', 33), (u'ACC_Castillo', 8), (u'EPN', 6), (u'CONADE', 4), (u'joserra_espn', 4), (u'ESPNmx', 4), (u'PaolaEspinosaOf', 2), (u'Faitelson_ESPN', 2), (u'gobmx', 1), (u'mexico', 1), (u'yllenhot1', 1), (u'aristeguicnn', 1), (u'AnaGGuevara', 1), (u'INEMexico', 1), (u'PresidenciaMX', 1), (u'merizemborain', 1), (u'apmakeup', 1), (u'matsinfronteras', 1), (u'Pajaropolitico', 1), (u'Valencia_Guzman', 1)]

[(u'YoRio', 80), (u'YoRioxESPN', 40), (u'YoR\xedo', 15), (u'Rio2016', 3), (u'HondurasLlora', 2), (u'NoTeMuerasNunca', 2), (u'MePongoDePie', 2), (u'YoLloro', 2), (u'Idolo', 2), (u'Grandisima', 2), (u'lupitadeoro', 2), (u'YoRIO', 2), (u'EllaRie', 1), (u'TodosReimos', 1), (u'yorio', 1), (u'COL', 1), (u'Olimpiadas2016', 1), (u'Plata', 1), (u'LupitaMentality', 1), (u'yoRio', 1)]

+-------------+-------+
| Word        | Count |
+-------------+-------+
| en          |   103 |
| de          |    76 |
| #YoRio      |    73 |
| del         |    62 |
| a           |    61 |
| RT          |    53 |
| Diego       |    52 |
| Tendremos   |    40 |
| años        |    40 |
| 4to         |    40 |
| lugar       |    40 |
| NOCHE       |    40 |
| 22          |    40 |
| fue         |    40 |
| Con         |    40 |
| lanzamiento |    40 |
| ESTA        |    40 |
| Real.       |    40 |
| #YoRioxESPN |    39 |
| martillo.   |    34 |
+-------------+-------+
+-----------------+-------+
| Screen Name     | Count |
+-----------------+-------+
| Leonlec         |    33 |
| ACC_Castillo    |     8 |
| EPN             |     6 |
| CONADE          |     4 |
| joserra_espn    |     4 |
| ESPNmx          |     4 |
| PaolaEspinosaOf |     2 |
| Faitelson_ESPN  |     2 |
| gobmx           |     1 |
| mexico          |     1 |
| yllenhot1       |     1 |
| aristeguicnn    |     1 |
| AnaGGuevara     |     1 |
| INEMexico       |     1 |
| PresidenciaMX   |     1 |
| merizemborain   |     1 |
| apmakeup        |     1 |
| matsinfronteras |     1 |
| Pajaropolitico  |     1 |
| Valencia_Guzman |     1 |
+-----------------+-------+
+-----------------+-------+
| Hashtag         | Count |
+-----------------+-------+
| YoRio           |    80 |
| YoRioxESPN      |    40 |
| YoRío           |    15 |
| Rio2016         |     3 |
| HondurasLlora   |     2 |
| NoTeMuerasNunca |     2 |
| MePongoDePie    |     2 |
| YoLloro         |     2 |
| Idolo           |     2 |
| Grandisima      |     2 |
| lupitadeoro     |     2 |
| YoRIO           |     2 |
| EllaRie         |     1 |
| TodosReimos     |     1 |
| yorio           |     1 |
| COL             |     1 |
| Olimpiadas2016  |     1 |
| Plata           |     1 |
| LupitaMentality |     1 |
| yoRio           |     1 |
+-----------------+-------+

Los 2 bucles son estos:


### Bloque 1

for item in [words, screen_names, hashtags]:
    c = Counter(item)
    print c.most_common()[:20]
    print


### Bloque 2
for label, data in (('Word', words), ('Screen Name', screen_names), ('Hashtag', hashtags)):
    pt = PrettyTable(field_names=[label, 'Count'])
    c = Counter(data)
    [ pt.add_row(kv) for kv in c.most_common()[:20] ]
    pt.align[label], pt.align['Count'] = 'l', 'r' # Set column alignment
    print pt


    

Si analizamos bien el código anterior lo que estamos imprimiendo para el primer bloque es una lista con 1 diccionario adentro, esto debido a que la API nos proporciona una lista de muchos diccionarios y como estamos sobre esta, es decir no hemos creado diccionarios nuevos esto lo hacemos en la otra serie :D, la salida es lógica una lista de 1 diccionario con los items mas comunes que estamos evaluando.

Se me olvidaba también tenemos importada una librería llamada Counter que nos facilita el tener que contar los items mas comunes de una clase o método python como es nuestro caso tenemos 3 diccionario y el bloque 1 nos permite encontrar los mas comunes de cada diccionario, yo le coloque 20, aquí la linea en cuestión:


    print c.most_common()[:20]

El siguiente Bloque es mas interesante, nos permite visualizar los datos en una tabla para tener mejor percepción ademas los ordena 😀 de mayor a menor, podemos visualizar como para cada etiqueta tenemos 1 dato que vayamos agregando no sin antes contar con la librería Counter, Y a ti que se te ocurre hacer con estos datos 😀

Bueno a mi se me ocurrió que no me interesaban los datos con menos de 4 caracteres  y le coloque un condicional sencillo así:


for item in [words, screen_names, hashtags]:

    for palabra in item:
        if len(palabra) >= 4 :
            frecuencia[palabra] = frecuencia.get(palabra,0)+1 #esto nos cuenta todas las palabras
            
            
    print frecuencia
    print "  ############  "
    print "  ############  "
    print "  ############  "
    print "  ############  "



    

Que es lo que hice, simple crear un nuevo diccionario para imprimir en un diccionario las palabras que tengan mas de 4 caracteres y los agregue a un diccionario, con este mismo diccionario voy a imprimir lo que necesito, ojo pude usar el otro bloque que ya tenia pero me parece mas fácil de explicar así, puedes correr el siguiente programa y ver la salida(en la otra entrada):


for item in [words, screen_names, hashtags]:
    frecuencia = {}
    coleccion = {}
    lista_nueva=[]
    for palabra in item:
        if len(palabra) >= 4 :
	  frecuencia[palabra] = frecuencia.get(palabra,0)+1 #esto nos cuenta todas las palabras
	  lista_nueva.append(palabra)
    c = Counter(lista_nueva)
    print c.most_common()[:10]    
    print "  ############  "
    print "  ############  "    
    

    coleccion = c.most_common()[:10] 
    frecuencia_10 = len(coleccion)
    i = 0
    diccionario = dict()
    for i in range(0, frecuencia_10):
        key = coleccion[i][0]
        value = coleccion[i][1]
        diccionario[key] = value
     
    print diccionario


    t = PrettyTable(['key', 'value'])
    for key, val in diccionario.items():
        t.add_row([key, val])
    print t
            
            
    print "  ############  "
    print "  ############  "
    print "  ############  "
    print "  ############  "



    

Estaba tratando de hacer lo mas sencillo posible el código pasando por la librería operator hasta prettytables, pero me di cuenta que era mejor crear todo de nuevo o mejor dicho hacerlo lo mas sencillo pero largo posible, hoy no voy a comentar el código incluso falta colocarle las etiquetas al prettytable pero lo haré el lunes, ya a partir de ahora a descansar 😀

Fíjate que hay un solo ciclo FOR y para la siguiente entrada de la serie voy a dividirlos, incluso no se si la parte del prettytable quedara así, ya que a pesar de tener las 10 palabras mas usadas en cada Diccionario no están ordenados :S

Hasta la Próxima Feliz fin de Semana. Que Dios les Bendiga y le deje ver su Gloria en cada momento de Sus Vidas…

 

 

Jugando con la API de Twitter [Parte 3.2]

Con los datos recolectados en el programa de la entrada anterior podemos ir haciéndonos una idea de que tanto podemos avanzar y que información podemos obtener en Las Redes Sociales, pero en realidad no tenemos ni idea de que podemos hacer, ya que podemos hacer mucho mas con esta información, por ejemplo del Libro Mining-the-Social-Web-2nd-Edition en el capitulo que sigue podremos saber el léxico de una persona según sus twitter, no es un dato exacto pero hasta allá podemos llegar, en la especialización, hoy acabo de terminar el curso 4 que trata sobre el manejo de datos de la Red y Bases de datos, hemos usado un programa muy interesante para modelar datos en un mapa usando la geo-localización  de Google, mas adelante vamos a usar este mismo programa para visualizar diferentes datos en el mapa usando google y claro los datos que vamos a modelar son datos de las redes sociales, en primera instancia los datos que saquemos de la API de Twitter y posiblemente complementar  con otros datos de otras redes Sociales…

Ojo tenemos que tener en la misma carpeta los siguientes códigos, para que el código que vamos a estudiar funcione, primero creamos el archivo twurl.py, este programa es una conexión a la API de Twitter llamando a la pagina con parámetros interesantes:



import urllib
import oauth
import hidden

def augment(url, parameters) :
    secrets = hidden.oauth()
    consumer = oauth.OAuthConsumer(secrets['consumer_key'], secrets['consumer_secret'])
    token = oauth.OAuthToken(secrets['token_key'],secrets['token_secret'])

    oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, 
        token=token, http_method='GET', http_url=url, parameters=parameters)
    oauth_request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), consumer, token)
    return oauth_request.to_url()


def test_me() :
    print '* Calling Twitter...'
    url = augment('https://api.twitter.com/1.1/statuses/user_timeline.json',
        {'screen_name': 'drchuck', 'count': '2'} )
    print url
    connection = urllib.urlopen(url)
    data = connection.read()
    print data
    headers = connection.info().dict
    print headers
      

También necesitamos un archivo para manejar las claves llamado oauth.py:


"""
The MIT License

Copyright (c) 2007 Leah Culver

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

import cgi
import urllib
import time
import random
import urlparse
import hmac
import binascii


VERSION = '1.0' # Hi Blaine!
HTTP_METHOD = 'GET'
SIGNATURE_METHOD = 'PLAINTEXT'


class OAuthError(RuntimeError):
    """Generic exception class."""
    def __init__(self, message='OAuth error occured.'):
        self.mymessage = message

def build_authenticate_header(realm=''):
    """Optional WWW-Authenticate header (401 error)"""
    return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}

def escape(s):
    """Escape a URL including any /."""
    return urllib.quote(s, safe='~')

def _utf8_str(s):
    """Convert unicode to utf-8."""
    if isinstance(s, unicode):
        return s.encode("utf-8")
    else:
        return str(s)

def generate_timestamp():
    """Get seconds since epoch (UTC)."""
    return int(time.time())

def generate_nonce(length=8):
    """Generate pseudorandom number."""
    return ''.join([str(random.randint(0, 9)) for i in range(length)])


class OAuthConsumer(object):
    """Consumer of OAuth authentication.

    OAuthConsumer is a data type that represents the identity of the Consumer
    via its shared secret with the Service Provider.

    """
    key = None
    secret = None

    def __init__(self, key, secret):
        self.key = key
        self.secret = secret

   
class OAuthToken(object):
    """OAuthToken is a data type that represents an End User via either an access
    or request token.
    
    key -- the token
    secret -- the token secret

    """
    key = None
    secret = None

    def __init__(self, key, secret):
        self.key = key
        self.secret = secret

    def to_string(self):
        return urllib.urlencode({'oauth_token': self.key,
            'oauth_token_secret': self.secret})
 
    def from_string(s):
        """ Returns a token from something like:
        oauth_token_secret=xxx&oauth_token=xxx
        """
        params = cgi.parse_qs(s, keep_blank_values=False)
        key = params['oauth_token'][0]
        secret = params['oauth_token_secret'][0]
        return OAuthToken(key, secret)
    from_string = staticmethod(from_string)

    def __str__(self):
        return self.to_string()


class OAuthRequest(object):
    """OAuthRequest represents the request and can be serialized.

    OAuth parameters:
        - oauth_consumer_key 
        - oauth_token
        - oauth_signature_method
        - oauth_signature 
        - oauth_timestamp 
        - oauth_nonce
        - oauth_version
        ... any additional parameters, as defined by the Service Provider.
    """
    parameters = None # OAuth parameters.
    http_method = HTTP_METHOD
    http_url = None
    version = VERSION

    def __init__(self, http_method=HTTP_METHOD, http_url=None, parameters=None):
        self.http_method = http_method
        self.http_url = http_url
        self.parameters = parameters or {}

    def set_parameter(self, parameter, value):
        self.parameters[parameter] = value

    def get_parameter(self, parameter):
        try:
            return self.parameters[parameter]
        except:
            if parameter == "oauth_token" : return None
            raise OAuthError('Parameter not found: %s' % parameter)

    def _get_timestamp_nonce(self):
        return self.get_parameter('oauth_timestamp'), self.get_parameter(
            'oauth_nonce')

    def get_nonoauth_parameters(self):
        """Get any non-OAuth parameters."""
        parameters = {}
        for k, v in self.parameters.iteritems():
            # Ignore oauth parameters.
            if k.find('oauth_') < 0: parameters[k] = v return parameters def to_header(self, realm=''): """Serialize as a header for an HTTPAuth request.""" auth_header = 'OAuth realm="%s"' % realm # Add the oauth parameters. if self.parameters: for k, v in self.parameters.iteritems(): if k[:6] == 'oauth_': auth_header += ', %s="%s"' % (k, escape(str(v))) return {'Authorization': auth_header} def to_postdata(self): """Serialize as post data for a POST request.""" return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) \ for k, v in self.parameters.iteritems()]) def to_url(self): """Serialize as a URL for a GET request.""" return '%s?%s' % (self.get_normalized_http_url(), self.to_postdata()) def get_normalized_parameters(self): """Return a string that contains the parameters that must be signed.""" # Chuck - Make a copy of the parameters so we can modify them params = dict(self.parameters) try: # Exclude the signature if it exists. del params['oauth_signature'] except: pass # Escape key values before sorting. key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) \ for k,v in params.items()] # Sort lexicographically, first after key, then after value. key_values.sort() # Combine key value pairs into a string. return '&'.join(['%s=%s' % (k, v) for k, v in key_values]) def get_normalized_http_method(self): """Uppercases the http method.""" return self.http_method.upper() def get_normalized_http_url(self): """Parses the URL and rebuilds it to be scheme://host/path.""" parts = urlparse.urlparse(self.http_url) scheme, netloc, path = parts[:3] # Exclude default port numbers. if scheme == 'http' and netloc[-3:] == ':80': netloc = netloc[:-3] elif scheme == 'https' and netloc[-4:] == ':443': netloc = netloc[:-4] return '%s://%s%s' % (scheme, netloc, path) def sign_request(self, signature_method, consumer, token): """Set the signature parameter to the result of build_signature.""" # Set the signature method. self.set_parameter('oauth_signature_method', signature_method.get_name()) # Set the signature. self.set_parameter('oauth_signature', self.build_signature(signature_method, consumer, token)) def build_signature(self, signature_method, consumer, token): """Calls the build signature method within the signature method.""" return signature_method.build_signature(self, consumer, token) def from_request(http_method, http_url, headers=None, parameters=None, query_string=None): """Combines multiple parameter sources.""" if parameters is None: parameters = {} # Headers if headers and 'Authorization' in headers: auth_header = headers['Authorization'] # Check that the authorization header is OAuth. if auth_header.index('OAuth') > -1:
                auth_header = auth_header.lstrip('OAuth ')
                try:
                    # Get the parameters from the header.
                    header_params = OAuthRequest._split_header(auth_header)
                    parameters.update(header_params)
                except:
                    raise OAuthError('Unable to parse OAuth parameters from '
                        'Authorization header.')

        # GET or POST query string.
        if query_string:
            query_params = OAuthRequest._split_url_string(query_string)
            parameters.update(query_params)

        # URL parameters.
        param_str = urlparse.urlparse(http_url)[4] # query
        url_params = OAuthRequest._split_url_string(param_str)
        parameters.update(url_params)

        if parameters:
            return OAuthRequest(http_method, http_url, parameters)

        return None
    from_request = staticmethod(from_request)

    def from_consumer_and_token(oauth_consumer, token=None,
            http_method=HTTP_METHOD, http_url=None, parameters=None):
        if not parameters:
            parameters = {}

        defaults = {
            'oauth_consumer_key': oauth_consumer.key,
            'oauth_timestamp': generate_timestamp(),
            'oauth_nonce': generate_nonce(),
            'oauth_version': OAuthRequest.version,
        }

        defaults.update(parameters)
        parameters = defaults

        if token:
            parameters['oauth_token'] = token.key

        return OAuthRequest(http_method, http_url, parameters)
    from_consumer_and_token = staticmethod(from_consumer_and_token)

    def from_token_and_callback(token, callback=None, http_method=HTTP_METHOD,
            http_url=None, parameters=None):
        if not parameters:
            parameters = {}

        parameters['oauth_token'] = token.key

        if callback:
            parameters['oauth_callback'] = callback

        return OAuthRequest(http_method, http_url, parameters)
    from_token_and_callback = staticmethod(from_token_and_callback)

    def _split_header(header):
        """Turn Authorization: header into parameters."""
        params = {}
        parts = header.split(',')
        for param in parts:
            # Ignore realm parameter.
            if param.find('realm') > -1:
                continue
            # Remove whitespace.
            param = param.strip()
            # Split key-value.
            param_parts = param.split('=', 1)
            # Remove quotes and unescape the value.
            params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
        return params
    _split_header = staticmethod(_split_header)

    def _split_url_string(param_str):
        """Turn URL string into parameters."""
        parameters = cgi.parse_qs(param_str, keep_blank_values=False)
        for k, v in parameters.iteritems():
            parameters[k] = urllib.unquote(v[0])
        return parameters
    _split_url_string = staticmethod(_split_url_string)

class OAuthServer(object):
    """A worker to check the validity of a request against a data store."""
    timestamp_threshold = 300 # In seconds, five minutes.
    version = VERSION
    signature_methods = None
    data_store = None

    def __init__(self, data_store=None, signature_methods=None):
        self.data_store = data_store
        self.signature_methods = signature_methods or {}

    def set_data_store(self, data_store):
        self.data_store = data_store

    def get_data_store(self):
        return self.data_store

    def add_signature_method(self, signature_method):
        self.signature_methods[signature_method.get_name()] = signature_method
        return self.signature_methods

    def fetch_request_token(self, oauth_request):
        """Processes a request_token request and returns the
        request token on success.
        """
        try:
            # Get the request token for authorization.
            token = self._get_token(oauth_request, 'request')
        except OAuthError:
            # No token required for the initial token request.
            version = self._get_version(oauth_request)
            consumer = self._get_consumer(oauth_request)
            self._check_signature(oauth_request, consumer, None)
            # Fetch a new token.
            token = self.data_store.fetch_request_token(consumer)
        return token

    def fetch_access_token(self, oauth_request):
        """Processes an access_token request and returns the
        access token on success.
        """
        version = self._get_version(oauth_request)
        consumer = self._get_consumer(oauth_request)
        # Get the request token.
        token = self._get_token(oauth_request, 'request')
        self._check_signature(oauth_request, consumer, token)
        new_token = self.data_store.fetch_access_token(consumer, token)
        return new_token

    def verify_request(self, oauth_request):
        """Verifies an api call and checks all the parameters."""
        # -> consumer and token
        version = self._get_version(oauth_request)
        consumer = self._get_consumer(oauth_request)
        # Get the access token.
        token = self._get_token(oauth_request, 'access')
        self._check_signature(oauth_request, consumer, token)
        parameters = oauth_request.get_nonoauth_parameters()
        return consumer, token, parameters

    def authorize_token(self, token, user):
        """Authorize a request token."""
        return self.data_store.authorize_request_token(token, user)

    def get_callback(self, oauth_request):
        """Get the callback URL."""
        return oauth_request.get_parameter('oauth_callback')
 
    def build_authenticate_header(self, realm=''):
        """Optional support for the authenticate header."""
        return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}

    def _get_version(self, oauth_request):
        """Verify the correct version request for this server."""
        try:
            version = oauth_request.get_parameter('oauth_version')
        except:
            version = VERSION
        if version and version != self.version:
            raise OAuthError('OAuth version %s not supported.' % str(version))
        return version

    def _get_signature_method(self, oauth_request):
        """Figure out the signature with some defaults."""
        try:
            signature_method = oauth_request.get_parameter(
                'oauth_signature_method')
        except:
            signature_method = SIGNATURE_METHOD
        try:
            # Get the signature method object.
            signature_method = self.signature_methods[signature_method]
        except:
            signature_method_names = ', '.join(self.signature_methods.keys())
            raise OAuthError('Signature method %s not supported try one of the '
                'following: %s' % (signature_method, signature_method_names))

        return signature_method

    def _get_consumer(self, oauth_request):
        consumer_key = oauth_request.get_parameter('oauth_consumer_key')
        consumer = self.data_store.lookup_consumer(consumer_key)
        if not consumer:
            raise OAuthError('Invalid consumer.')
        return consumer

    def _get_token(self, oauth_request, token_type='access'):
        """Try to find the token for the provided request token key."""
        token_field = oauth_request.get_parameter('oauth_token')
        token = self.data_store.lookup_token(token_type, token_field)
        if not token:
            raise OAuthError('Invalid %s token: %s' % (token_type, token_field))
        return token

    def _check_signature(self, oauth_request, consumer, token):
        timestamp, nonce = oauth_request._get_timestamp_nonce()
        self._check_timestamp(timestamp)
        self._check_nonce(consumer, token, nonce)
        signature_method = self._get_signature_method(oauth_request)
        try:
            signature = oauth_request.get_parameter('oauth_signature')
        except:
            raise OAuthError('Missing signature.')
        # Validate the signature.
        valid_sig = signature_method.check_signature(oauth_request, consumer,
            token, signature)
        if not valid_sig:
            key, base = signature_method.build_signature_base_string(
                oauth_request, consumer, token)
            raise OAuthError('Invalid signature. Expected signature base '
                'string: %s' % base)
        built = signature_method.build_signature(oauth_request, consumer, token)

    def _check_timestamp(self, timestamp):
        """Verify that timestamp is recentish."""
        timestamp = int(timestamp)
        now = int(time.time())
        lapsed = now - timestamp
        if lapsed > self.timestamp_threshold:
            raise OAuthError('Expired timestamp: given %d and now %s has a '
                'greater difference than threshold %d' %
                (timestamp, now, self.timestamp_threshold))

    def _check_nonce(self, consumer, token, nonce):
        """Verify that the nonce is uniqueish."""
        nonce = self.data_store.lookup_nonce(consumer, token, nonce)
        if nonce:
            raise OAuthError('Nonce already used: %s' % str(nonce))


class OAuthClient(object):
    """OAuthClient is a worker to attempt to execute a request."""
    consumer = None
    token = None

    def __init__(self, oauth_consumer, oauth_token):
        self.consumer = oauth_consumer
        self.token = oauth_token

    def get_consumer(self):
        return self.consumer

    def get_token(self):
        return self.token

    def fetch_request_token(self, oauth_request):
        """-> OAuthToken."""
        raise NotImplementedError

    def fetch_access_token(self, oauth_request):
        """-> OAuthToken."""
        raise NotImplementedError

    def access_resource(self, oauth_request):
        """-> Some protected resource."""
        raise NotImplementedError


class OAuthDataStore(object):
    """A database abstraction used to lookup consumers and tokens."""

    def lookup_consumer(self, key):
        """-> OAuthConsumer."""
        raise NotImplementedError

    def lookup_token(self, oauth_consumer, token_type, token_token):
        """-> OAuthToken."""
        raise NotImplementedError

    def lookup_nonce(self, oauth_consumer, oauth_token, nonce):
        """-> OAuthToken."""
        raise NotImplementedError

    def fetch_request_token(self, oauth_consumer):
        """-> OAuthToken."""
        raise NotImplementedError

    def fetch_access_token(self, oauth_consumer, oauth_token):
        """-> OAuthToken."""
        raise NotImplementedError

    def authorize_request_token(self, oauth_token, user):
        """-> OAuthToken."""
        raise NotImplementedError


class OAuthSignatureMethod(object):
    """A strategy class that implements a signature method."""
    def get_name(self):
        """-> str."""
        raise NotImplementedError

    def build_signature_base_string(self, oauth_request, oauth_consumer, oauth_token):
        """-> str key, str raw."""
        raise NotImplementedError

    def build_signature(self, oauth_request, oauth_consumer, oauth_token):
        """-> str."""
        raise NotImplementedError

    def check_signature(self, oauth_request, consumer, token, signature):
        built = self.build_signature(oauth_request, consumer, token)
        return built == signature


class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod):

    def get_name(self):
        return 'HMAC-SHA1'
        
    def build_signature_base_string(self, oauth_request, consumer, token):
        sig = (
            escape(oauth_request.get_normalized_http_method()),
            escape(oauth_request.get_normalized_http_url()),
            escape(oauth_request.get_normalized_parameters()),
        )

        key = '%s&' % escape(consumer.secret)
        if token and token.secret:
            key += escape(token.secret)
        raw = '&'.join(sig)
        return key, raw

    def build_signature(self, oauth_request, consumer, token):
        """Builds the base signature string."""
        key, raw = self.build_signature_base_string(oauth_request, consumer,
            token)

        # HMAC object.
        try:
            import hashlib # 2.5
            hashed = hmac.new(key, raw, hashlib.sha1)
        except:
            import sha # Deprecated
            hashed = hmac.new(key, raw, sha)

        # Calculate the digest base 64.
        return binascii.b2a_base64(hashed.digest())[:-1]


class OAuthSignatureMethod_PLAINTEXT(OAuthSignatureMethod):

    def get_name(self):
        return 'PLAINTEXT'

    def build_signature_base_string(self, oauth_request, consumer, token):
        """Concatenates the consumer key and secret."""
        sig = '%s&' % escape(consumer.secret)
        if token:
            sig = sig + escape(token.secret)
        return sig, sig

    def build_signature(self, oauth_request, consumer, token):
        key, raw = self.build_signature_base_string(oauth_request, consumer,
            token)
        return key


      

Y hemos creado un archivo donde vamos a guardar todas nuestras llaves llamado hidden.py:

# Keep this file separate

def oauth() :
    return { "consumer_key" : "Coloca tus datos aqui",
        "consumer_secret" : "Coloca tus datos aqui",
        "token_key" : "Coloca tus datos aqui",
        "token_secret" : "Coloca tus datos aqui" }

En esta entrada voy a seguir trabajando con uno de los ejemplos del curso(ojo no son los ejercicios propuestos), en el siguiente código tenemos un programa muy pero muy limpio que con algunos detalles podría ser una excelente base para una aplicación completa, este es el programa:

import urllib, twurl, json, sqlite3


TWITER_URL = 'https://api.twitter.com/1.1/friends/list.json'


conn = sqlite3.connect('amigos.sqlite3')

cur = conn.cursor()

cur.execute('''CREATE TABLE IF NOT EXISTS Personas (id INTEGER PRIMARY KEY, nombre TEXT UNIQUE, recuperado INTEGER)''')
cur.execute('''CREATE TABLE IF NOT EXISTS Seguimientos (desde_id INTEGER, hacia_id INTEGER, UNIQUE(desde_id,hacia_id))''')

while True:
  
    cuenta = raw_input('Introduzca una cuenta de Twitter, o salir: ')
  
    if (cuenta == 'salir') : break

    if (len (cuenta) < 1):
    
        cur.execute('''SELECT id, nombre FROM Personas WHERE recuperado = 0 LIMIT 1''')
        try:
            (id, cuenta) = cur.fetchone()
        except:
            print "No se hab encontrado cuentas de Twitter sin recuperar"
      
            continue
    else:
        cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (cuenta, ))
    
        try:
      
            id = cur.fetchone()[0]
      
        except:
      
            cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0) ''', (cuenta, ))
            conn.commit()
      
            if cur.rowcount != 1 :
                print "Error insertando cuenta: ", cuenta
	
                continue
      
            id = cur.lastrowid
      
    url = twurl.augment(TWITER_URL, {'screen_name': cuenta, 'count': '20'})
  
    print "Recuperando cuenta: " , cuenta
  
    conexion = urllib.urlopen(url)
  
    datos = conexion.read()
  
    cabeceras = conexion.info().dict
  
    print "Restantes" , cabeceras['x-rate-limit-remaining']
  
    js = json.loads(datos)
  
    # print json.dumps(js.indent=4)
  
    cur.execute('UPDATE Personas SET recuperado=1 WHERE nombre = ?', (cuenta, ))
  
    contnuevas = 0
  
    contantiguas = 0
  
    for u in js['users']:
    
        amigo = u['screen_name']
    
        print amigo
    
        cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (amigo, ))
        try:
            
            amigo_id = cur.fetchone()[0]
     
            contantiguas = contantiguas + 1
     
        except:
     
            cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0)''', (amigo, ))
            conn.commit()
     
            if cur.rowcount != 1:
                print 'Error al insertar cuenta:', amigo
                continue
            amigo_id = cur.lastrowid
     
            contnuevas = contnuevas + 1
        cur.execute('''INSERT OR IGNORE INTO Seguimientos (desde_id, hacia_id) VALUES(?,?)''', (id, amigo_id))
    print 'Cuentas nuevas= ', contnuevas,' ya visitadas=', contantiguas
    
    conn.commit()
cur.close()
      
      

Como podemos observar y gracias  a python, al leer por encima el codigo vemos varios bloques interesantes y es de estos bloques que nos vamos a ocupar en esta entrada, para comenzar el bloque 1 de interés

import urllib, twurl, json, sqlite3


TWITER_URL = 'https://api.twitter.com/1.1/friends/list.json'


conn = sqlite3.connect('amigos.sqlite3')

cur = conn.cursor()

cur.execute('''CREATE TABLE IF NOT EXISTS Personas (id INTEGER PRIMARY KEY, nombre TEXT UNIQUE, recuperado INTEGER)''')
cur.execute('''CREATE TABLE IF NOT EXISTS Seguimientos (desde_id INTEGER, hacia_id INTEGER, UNIQUE(desde_id,hacia_id))''')
      

 Las primeras lineas no necesitan muchos comentarios, primero importamos las librerías necesarias , nos conectamos al API específicamente a Friends y creamos la base de datos  (‘amigos.sqlite3’), luego creamos la tabla personas y creamos la tabla seguimientos, hasta aquí todo muy sencillo….

Luego tenemos un bucle while desde la linea 15 hasta la 99, no te asustes, el código no es tan complejo y básicamente tenemos 2 bloques que vamos a comentar un poco, por ejemplo tenemos este:


 cuenta = raw_input('Introduzca una cuenta de Twitter, o salir: ')
 
 if (cuenta == 'salir') : break

 if (len (cuenta) < 1):
 
 cur.execute('''SELECT id, nombre FROM Personas WHERE recuperado = 0 LIMIT 1''')
 try:
 (id, cuenta) = cur.fetchone()
 except:
 print "No se han encontrado cuentas de Twitter sin recuperar"
 
 continue
 else:
 cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (cuenta, ))
 
 try:
 
 id = cur.fetchone()[0]
 
 except:
 
 cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0) ''', (cuenta, ))
 conn.commit()
 
 if cur.rowcount != 1 :
 print "Error insertando cuenta: ", cuenta
 
 continue
 
 id = cur.lastrowid
 
      

En este bloque tenemos 2 cosas importantes, en primer lugar debemos colocar el nombre de la cuenta que queremos minar, y luego tenemos 1 condicional si el nombre de la cuenta es salir hasta aquí llega el código y se sale, pero si agregamos una cuenta así no exista el código crea un nombre en la base de datos si no existe y la ignora si ya existe, la parte mas importante es el bloque else donde si no se escribe un nombre para cuenta el código toma al siguiente nombre y crea un nombre en la base de datos y se ejecuta como si nosotros lo hubiéramos agregado manualmente…

El siguiente Bloque de código no es menos interesante, y trata sobre la conexión y recolección de los datos de la API en primer lugar, es este bloque:


      
    url = twurl.augment(TWITER_URL, {'screen_name': cuenta, 'count': '20'})
  
    print "Recuperando cuenta: " , cuenta
  
    conexion = urllib.urlopen(url)
  
    datos = conexion.read()
  
    cabeceras = conexion.info().dict
  
    print "Restantes" , cabeceras['x-rate-limit-remaining']
  
    js = json.loads(datos)
  
    # print json.dumps(js.indent=4)
  
    cur.execute('UPDATE Personas SET recuperado=1 WHERE nombre = ?', (cuenta, ))
  
    contnuevas = 0
  
    contantiguas = 0
  
    for u in js['users']:
    
        amigo = u['screen_name']
    
        print amigo
    
        cur.execute('SELECT id FROM Personas WHERE nombre = ? LIMIT 1', (amigo, ))
        try:
            
            amigo_id = cur.fetchone()[0]
     
            contantiguas = contantiguas + 1
     
        except:
     
            cur.execute('''INSERT OR IGNORE INTO Personas (nombre, recuperado) VALUES (?,0)''', (amigo, ))
            conn.commit()
     
            if cur.rowcount != 1:
                print 'Error al insertar cuenta:', amigo
                continue
            amigo_id = cur.lastrowid
     
            contnuevas = contnuevas + 1
        cur.execute('''INSERT OR IGNORE INTO Seguimientos (desde_id, hacia_id) VALUES(?,?)''', (id, amigo_id))
    print 'Cuentas nuevas= ', contnuevas,' ya visitadas=', contantiguas
    
    conn.commit()
cur.close()
 
      

 Como dije anteriormente nos conectamos a la URL  y sacamos hasta 20 seguidores de la cuenta, podemos notar screen_name que es el nombre de la cuenta y count, url genera la pagina a la que nos vamos a conectar con screen_name, luego se hace la conexión se sacan las cabeceras como un diccionario, veamoslo así obtenemos los datos de la url se los pasamos a cabeceras como un diccionario solo para revisar cuantas peticiones a la api nos quedan, luego cargamos datos de JSON con load, actualizamos la cuenta en nuestra base de datos, luego iniciamos un bucle for para buscar los datos de nuestros amigos y vamos obteniendo sus nombres, luego tenemos el guardián para contar los seguidores e insertar o ignorar los nombres recuperados…. Luego agregamos la tabla donde tenemos quien sigue a quien para tener llaves foraneas para futuros ejercicios….

De verdad a mi me ha  gustado mucho hasta ahora la Especializacion en Python de Coursera, y me esta gustando Machine Learning con Python, pero espero Dios me de tiempo mas adelante para dedicarme de lleno… Esto de las API es excelente para aprender mas y mas de python por que son codigos muy sencillos y con aplicaciones practicas… hasta la próxima y Dios les Bendiga

Jugando con la API de Twitter [Parte 3.1]

Bueno les explico el por que del 3.1, simple en la entrada anterior escribí basándome en los ejemplos del Libro Mining_the_Social_WEB, Ya tenia planeado usar los ejemplos del libro Python_para_Informáticos que es el libro de versión español para los estudiantes de la Especialización en Python, Explicare mejor el por que me gustan mas los ejemplos de la especialización pero por que no quiero dejar de lado los ejemplos  de Mining_the_Social_WEB, primero por que los ejercicios de la especialización son mas prácticos y ademas son mas sencillos de entender, los hacen como un alumno los haría si comprende la clase, pero los de Mining_the_Social_WEB son mas profundos por que usan al máximo el como usar python, para mi son mas engorrosos por eso les presento los 2, claro con los de Python_para_Informáticos obtendremos mejores resultados y creo deberían ser la base para los códigos finales que vamos a usar….

Ojo que hay un problema no he entrado de lleno en el código del libro Python_para_Informáticos por que cuando ejecutamos si tenemos instalado las librerías de pip me da un error y entonces hay que eliminar el código de python-twitter o pytwitter e instalarlo con pip como super usuario y ahora si funciona el código, no he estudiado el código para hacer la mejora respectiva si se puede, pero no vamos a caer en estos problemas por 100kb de código y yo por ejemplo voy a des-instalar e instalar cada vez q lo necesite. Para que el código que vamos a utilizar funcione vamos a des-instalar e instalar así:

 
pip uninstall twitter

Nos sale algo como esto:

 
Uninstalling twitter:
 /usr/local/bin/twitter 
 /usr/local/bin/twitter-archiver 
 /usr/local/bin/twitter-follow 
 /usr/local/bin/twitter-log 
 /usr/local/bin/twitter-stream-example 
 /usr/local/bin/twitterbot 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/DESCRIPTION.rst 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/METADATA 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/RECORD 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/WHEEL 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/entry_points.txt 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/pydist.json 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/top_level.txt 
 /usr/local/lib/python2.7/dist-packages/twitter-1.17.1.dist-info/zip-safe 
 /usr/local/lib/python2.7/dist-packages/twitter/__init__.py 
 /usr/local/lib/python2.7/dist-packages/twitter/__init__.pyc 
 /usr/local/lib/python2.7/dist-packages/twitter/ansi.py 
 /usr/local/lib/python2.7/dist-packages/twitter/ansi.pyc 
 /usr/local/lib/python2.7/dist-packages/twitter/api.py 
 /usr/local/lib/python2.7/dist-packages/twitter/api.pyc 
 /usr/local/lib/python2.7/dist-packages/twitter/archiver.py 
 /usr/local/lib/python2.7/dist-packages/twitter/archiver.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/auth.py
 /usr/local/lib/python2.7/dist-packages/twitter/auth.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/cmdline.py
 /usr/local/lib/python2.7/dist-packages/twitter/cmdline.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/follow.py
 /usr/local/lib/python2.7/dist-packages/twitter/follow.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/ircbot.py
 /usr/local/lib/python2.7/dist-packages/twitter/ircbot.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/logger.py
 /usr/local/lib/python2.7/dist-packages/twitter/logger.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/oauth.py
 /usr/local/lib/python2.7/dist-packages/twitter/oauth.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/oauth2.py
 /usr/local/lib/python2.7/dist-packages/twitter/oauth2.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/oauth_dance.py
 /usr/local/lib/python2.7/dist-packages/twitter/oauth_dance.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/stream.py
 /usr/local/lib/python2.7/dist-packages/twitter/stream.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/stream_example.py
 /usr/local/lib/python2.7/dist-packages/twitter/stream_example.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/timezones.py
 /usr/local/lib/python2.7/dist-packages/twitter/timezones.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/twitter_globals.py
 /usr/local/lib/python2.7/dist-packages/twitter/twitter_globals.pyc
 /usr/local/lib/python2.7/dist-packages/twitter/util.py
 /usr/local/lib/python2.7/dist-packages/twitter/util.pyc
Proceed (y/n)? y

Le damos que Si o “y”, y ya esta listo, ahora instalamos python-twitter:

pip install python-twitter

 

Ahora vamos a probar el programa con el siguiente código para que veamos lo que podemos hacer con un código mas sencillo 😀 :

import twitter

# Datos de autenticacion
CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_SECRET = 'Datos de D'

# Conexion a la API
api = twitter.Api(consumer_key=CONSUMER_KEY,
           consumer_secret=CONSUMER_SECRET,
           access_token_key=OAUTH_TOKEN,
           access_token_secret=OAUTH_SECRET);

# Procedimiento para mostrar los datos de cada amigo seguido en Twitter. 
def GetFriendsInformation(user, api):
   # Obtenemos el listado de de amigos del usuario pasado
   TwitterFriends = api.GetFriends(screen_name=user);
   # Por cada amigo vamos a mostrar la informacion que desemos
   for Friends in TwitterFriends:
      # Nombre mostrados
      print 'Amigo ' + Friends.screen_name;
      # Localizacion
      print '\t Localizacion: ' + Friends.location;
      # Numero de seguidores
      print '\t Numero de seguidores: ' + str(Friends.followers_count);
      # Numero de amigos
      print '\t Numero de amigos: ' + str(Friends.friends_count);
      # Numero de tweets enviados
      print '\t Numero de tweets enviados: ' + str(Friends.statuses_count);

# Llamada al procedimiento para obtener los datos del usuario yorio
# Sustituir el usuario por el vuestro o cualquiera que querais analizar.
GetFriendsInformation('yorio', api);

La salida del programa es:

Amigo GoyaFoods
 Localizacion: 
 Numero de seguidores: 5406
 Numero de amigos: 1954
 Numero de tweets enviados: 6169
Amigo Number2Creative
 Localizacion: New York, NY
 Numero de seguidores: 168
 Numero de amigos: 200
 Numero de tweets enviados: 376
Amigo buzzedhostess
 Localizacion: Hoboken, NJ
 Numero de seguidores: 194
 Numero de amigos: 230
 Numero de tweets enviados: 156
Amigo christinleigh22
 Localizacion: 
 Numero de seguidores: 15
 Numero de amigos: 76
 Numero de tweets enviados: 8

Podemos ver alguna información interesante pero ojo que podemos ir a la API de twitter o a la salida de uno de los primeros códigos que escribimos y podemos obtener datos que antes no se dejaban leer y veríamos datos mas interesantes, por ejemplo el dato de localización lo podríamos usar, mas adelante les diré para que 😀

Este sencillo código te dará información muy interesante de los amigo o a quienes esta siguiendo yorio, podemos probar con vladimirala1 y otros, es muy interesante la información obtenida, mañana voy a agregar mas código y sacaremos mas información ademas vamos a ver algunas rutinas de nuestro programa realmente importante donde agregaremos los datos a una BD y el programa verificara si hemos agregado ya el usuario a estudiar  y si no es así llamar a twitter y agregarlo y si no ingresamos nada podremos estudiar a los amigos de los amigo o a seguidores de seguidores 😀

Saludos Dios les Bendiga, comentar es agradecer

 

Jugando con la API de Twitter [Parte 3]

Jugando con la API de Twitter [Parte 2]

Jugando con la API de Twitter [Parte 1]

Experiencia de La Especialización Python para toda la vida

Jugando con la API de Twitter [Parte 3]

La verdad es que esto del scraping en las API de Twitter y las redes sociales me tiene con muy altas expectativas de lo que podría hacer con tanta información :D, Este Libro que hemos venido estudiando junto con los ejemplo de la especialización en python me han ayudado a escribir sobre este interesante mundo de la información de Redes Sociales, y es que solo hemos raspado muy por arriba la información que contienen las bases de datos de Twitter.

Hoy vamos a crear unas rutinas un poco mas complejas, no se asusten, digo complejas por que vamos a comenzar a conocer aun mas los datos que nos provee la API de Twitter, es importante entender que Python nos ayuda mucho al intentar sacar la información del archivo JSON que nos da Twitter, por que lo digo, simplemente por que la estructura de JSON y XML es muy parecida por no decir idéntica a un Diccionario Python y esto si que nos va a beneficiar al no tener que enviar múltiples llamadas a la API ya que podemos obtener la información guardarla en memoria como un diccionario mas formateado y luego comenzar a encontrar nuestros diamantes de la Roca extraída, por ejemplo en La especialización de Python(5 Cursos) que gracias a Dios estoy terminando había un problema que se ejecutaba muy lento por que el gestor de BD accedía en cada llamada a los datos de la API y esto ralentizaba mucho la ejecución, y con mi experiencia en python intuitivamente me incline por llevar los datos al diccionario y luego ya con los datos en la memoria(aquí esta la magia de los diccionarios), ya con los datos en la memoria ejecute el gestor de Base de Datos o ejecute código SQL sobre el diccionario y paso de 7 minutos mas o menos a menos de 40 segundos, aun creo que podría mejorar ese código pero una vez que pase la tarea me olvide de esta :S(no recomendable jejeje)…

Que vamos a hacer hoy, Hoy vamos a revisar un poco los datos que nos provee la API y vamos a imprimir en pantalla los datos recolectados solo los que nos interesan(vamos a entrar un poco mas en detalle) y los vamos a agregar a la BD SQLITE3, ademas vamos a ver uno de los ejemplos del curso 4 de la especialización (ojo no voy a colocar los ejercicios propuestos) y vamos a ver algunas cosas importantes para no repetir datos en la BD y no entrar 2 veces en un mismo Twitter:

 

import twitter, json
# Lo primero que debemos hacer es ir a http://dev.twitter.com/apps/new y crear una app
#puedes ver https://dev.twitter.com/docs/auth/oauth para mas informacion
#las credenciales que necesitamos debemos copiarlas de XXXXXXXXXXXXXXXXXXXXXX y usarlas tal como se muestrasn en las imagenes de esta entrada http://wp.me/p3nJhK-ev

CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_TOKEN_SECRET = 'Datos de D'

auth = twitter.oauth.OAuth( OAUTH_TOKEN , OAUTH_TOKEN_SECRET, CONSUMER_KEY , CONSUMER_SECRET )

twitter_api = twitter.Twitter(auth=auth)

worl_trends = twitter_api.trends.place(_id=WORL_WOE_ID)

us_trends = twitter_api.trends.place(_id=US_WOE_ID)

print json.dumps(worl_trends, indent =4)
print 
print json.dumps(us_trends, indent =4)

Vamos a utilizar como base esta consulta de búsqueda, vamos a buscar algunos tweets para su posterior análisis, la salida de este programa dista mucho de lo que quisiéramos obtener como mineros de datos, en realidad tenemos mucha información pero no tenemos nada palpable, por ejemplo en el libro hablan de los re-twitts de las tendencias y otras cosas, pero a mi me gustaría saber cuales son las principales cuentas de programación en python y ofertas para freelancer, claro esto lo veremos mas a fondo en La API de Linkedin y podríamos conectar facebook+twitter+linkedin+freelancer y relacionar las bases de datos y obtener información refinada de determinados temas :D….

Por ahora nos vamos a conformar con sacar algunos datos y aprender nuevas técnicas de extracción de JSON y algunas técnicas aplicadas de programación en python…. Es importante tener en cuenta que lo que se quiere es tener control sobre datos en tiempo real de la API de Twitter algo como tipo streaming, eso lo veremos mas adelante cuando pasemos por la API de Freelancer que por ahora esta cerrada :S

Anteriormente vimos el código anterior, ahora vamos a ver un código con mas python, recuerda que tomamos los datos de la API y  luego queda programar en python :D, este es el código:

 
import twitter, json

CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_TOKEN_SECRET = 'Datos de D'

auth = twitter.oauth.OAuth( OAUTH_TOKEN , OAUTH_TOKEN_SECRET, CONSUMER_KEY , CONSUMER_SECRET )

twitter_api = twitter.Twitter(auth=auth)




q =  '#yorio' # una cuenta twitter importante para ti, ten en cuenta que mas adelante 
				      # implementare una arania real para twitter q nos permitira tener una BD actualizada
				      # con muchos twitter y cuentas enlazadas
				      # Ademas podemos ver que es q aqui  https://dev.twitter.com/docs/api/1.1/get/search/tweets


count = 100

search_results = twitter_api.search.tweets(q=q, count =count)

statuses = search_results['statuses']

# Ahora, vamos a Recorrer 5  lotes de resultados siguiendo el cursor
# Esto es muy importante en python ya que permite ir por delante del cursor
# Resultados de la busqueda contienen un nodo search_metadata especial que incorpora un next_results
# campo con una cadena de consulta que proporciona la base de una consulta posterior

for _ in range(5):
  print "Length of statuses", len(statuses)
  try:
    next_results = search_results['search_metadata']['next_results']
  except KeyError, e: # No mas resultados si no hay mas datos
    break
  
  # Creamos un Diccionario para next_results, con la siguiente forma:
  # ?max_id=313519052523986943&q=NCAA&include_entities=1
  
  kwargs = dict([kv.split('=') for kv in next_results[1:].split('&') ])
  
  # para una mejor comprension puedes vistar http://librosweb.es/libro/python/capitulo_6/metodos_de_union_y_division.html
  # Split es una funcion que se utiliza para divir una cadena
  # breve explicacion de :kv.split('=') for kv in next_results[1:].split('&')
  # simple toma como valor a el siguiente caracter luego del '=' y lo corta has & dandole el valor de kv
  # recuerda que next_results es un diccionario o lista de tuplas
  
  search_results = twitter_api.search.tweets(**kwargs)
  
  statuses += search_results['statuses']
  

print json.dumps(statuses[0], indent=1)

 Algo que me parece interesante es que al utilizar un Hashtag como el que veníamos usando, este código ejecuta un error de Fuera de Rango, y es que no tenemos unos guardianes custodiando que hay suficiente información y no voy a crearlos tampoco, recuerda que con estos código buscamos es aprender ya mas adelante crear mejor código python recopilando lo que vamos aprendiendo entrada a entrada…

En este ejemplo coloque la cuenta de #VladirmirAla1 por que sabia que hay bastante información, podemos usar el #YoRio aprovechando el momento de los juegos olímpicos 😀

Algo importante del código, los kwargs, recordemos que en python podemos llamar de diferentes maneras los atributos o valores que vamos a usar en una función, y en python para usar valores arbitrarios podemos usar **arg o **kwargs, específicamente usamos kwargs para los diccionarios, es algo como que aceptamos cualquier valor que se vaya encontrando…

Si nos detenemos a revisar la salida de nuestro programa nos daremos cuenta que hay mucha información en las redes, y de verdad no hemos encontrado mucho con este ejemplo, a continuación, vamos a sumergirnos un poco mas en los datos que nos ofrece la API y vamos a sacar algunos datos interesantes como por ejemplo re_tweets(este dato tiene especial interés y solo diré que solo el tweet original se puede re_tweets), screen_name es el nombre de quien escribe y otros datos mas de los que aparecen en el libro, voy a modificar un poco el ejemplo para obtener algunos datos mas:

 

import twitter, json

# Datos de autenticacion
CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_TOKEN_SECRET = 'Datos de D'





auth = twitter.oauth.OAuth( OAUTH_TOKEN , OAUTH_SECRET, CONSUMER_KEY , CONSUMER_SECRET )

api = twitter.Twitter(auth=auth)

q =  '#vladimirala1' # una cuenta twitter importante para ti, ten en cuenta que mas adelante 
				      # implementare una arania real para twitter q nos permitira tener una BD actualizada
				      # con muchos twitter y cuentas enlazadas
				      # Ademas podemos ver que es q aqui  https://dev.twitter.com/docs/api/1.1/get/search/tweets


count = 100

search_results = api.search.tweets(q=q, count =count)

statuses = search_results['statuses']


  
retweet_counts = [status['retweet_count']
	 for status in statuses ]

status_texts = [status['text']
	 for status in statuses ]


screen_names = [user_mention['screen_name']
	 for status in statuses 
	     for user_mention in status ['entities']['user_mentions'] ]


hashtags = [hashtag['text']
	 for status in statuses 
	     for hashtag in status ['entities']['hashtags'] ]



fields = "id screen_name name created_at url followers_count friends_count statuses_count \
    favourites_count listed_count \
    contributors_enabled description protected location lang expanded_url".split()
    
r = {}
for f in fields:
    r[f] = ""
    #ASSIGN VALUE OF 'ID' FIELD IN JSON TO 'ID' FIELD IN OUR DICTIONARY
    r['id'] = f['id']
    #SAME WITH 'SCREEN_NAME' HERE, AND FOR REST OF THE VARIABLES
    r['screen_name'] = f['screen_name']



print json.dumps(retweet_counts[0:5], indent=4)

print json.dumps(status_texts[0:5], indent=4)

print json.dumps(screen_names[0:5], indent=4)

print json.dumps(hashtags[0:5], indent=4)

 Aunque todavía no hemos obtenido los gramos de oro que esperamos, cada vez tenemos mejores expectativas, en la próxima entrada voy a implementar 1 programa del curso y vamos a sacar los datos del Archivo Json y del diccionario de una manera mas intuitiva y mas fácil de entender… es interesante todo lo que podemos hacer con python, ya en la próxima entrada tendemos mejores vistas de muchos datos que vamos a obtener formateados directo para una BD, ademas espero implementar unas cuantas cosas para La BD esperemos a ver 😀

Saludos y Dios les Bendiga

Jugando con la API de Twitter [Parte 2]

Jugando con la API de Twitter [Parte 1]

Experiencia de La Especialización Python para toda la vida

Jugando con la API de Twitter [Parte 2]

Hola no es habitual que escriba sobre el mismo tema tan seguido pero lo haré por lo menos en esta serie “Jugando con las API de las redes sociales”, y próximamente “Jugando con la API  de SPN” para que aquellas personas que les gustan algunos números que no salen en los periódicos tengan acceso a estos… claro voy a terminar primero con la mayor parte de las redes sociales antes de comenzar otra serie.

En esta entrada vamos a intentar refinar un poco la información que obtuvimos en la entrada anterior, vamos a usar algunas rutinas de json y vamos a usar también python para ir depurando nuestra información, ademas vamos a tener un breve acercamiento a sqlite3 para obtener una base de datos que realmente no hace nada pero nos ayudara a ir entendiendo la información y guardarla para reutilizarla, mas adelante vamos a crear bases de datos mas elegantes y funcionales donde no vamos a tener q repetir los datos una vez si no 1 sola vez y de diferentes modos 😀

En el siguiente ejemplo vamos a implementar una rutina de JSON para formatear los datos que hemos recibido anteriormente y asi tener una mirada mas sencilla a estos :D, puedes colocarle ej2_twitterAPI_json.py:

 

import twitter, json
# Lo primero que debemos hacer es ir a http://dev.twitter.com/apps/new y crear una app
#puedes ver https://dev.twitter.com/docs/auth/oauth para mas informacion
#las credenciales que necesitamos debemos copiarlas de XXXXXXXXXXXXXXXXXXXXXX y usarlas tal como se muestrasn en las imagenes de esta entrada http://wp.me/p3nJhK-ev

CONSUMER_KEY = 'Datos de A'

CONSUMER_SECRET = 'Datos de B'

OAUTH_TOKEN = 'Datos de C'

OAUTH_TOKEN_SECRET = 'Datos de D'


auth = twitter.oauth.OAuth( OAUTH_TOKEN , OAUTH_TOKEN_SECRET, CONSUMER_KEY , CONSUMER_SECRET )

twitter_api = twitter.Twitter(auth=auth)

worl_trends = twitter_api.trends.place(_id=WORL_WOE_ID)

us_trends = twitter_api.trends.place(_id=US_WOE_ID)

print json.dumps(worl_trends, indent =4)
print 
print json.dumps(us_trends, indent =4)

Lo nuevo son estas lineas, estas lineas usan rutinas de JSON para formatear el Diccionario que nos devolvía el programa en la entrada anterior, el 4 no es mas que el identado con el que queremos ver la información 😀

 

print json.dumps(worl_trends, indent =4)
print 
print json.dumps(us_trends, indent =4)

Si corremos el código anterior obtenemos la salida siguiente:

 

[
    {
        "created_at": "2016-08-05T19:13:35Z", 
        "trends": [
            {
                "url": "http://twitter.com/search?q=%22BEM+FEITO+JUSTIN%22", 
                "query": "%22BEM+FEITO+JUSTIN%22", 
                "tweet_volume": 55828, 
                "name": "BEM FEITO JUSTIN", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23CerimoniaDeAbertura", 
                "query": "%23CerimoniaDeAbertura", 
                "tweet_volume": 38173, 
                "name": "#CerimoniaDeAbertura", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%D8%A7%D9%84%D8%A7%D8%AA%D8%AD%D8%A7%D8%AF_%D8%A7%D9%84%D9%86%D8%B5%D8%B1", 
                "query": "%23%D8%A7%D9%84%D8%A7%D8%AA%D8%AD%D8%A7%D8%AF_%D8%A7%D9%84%D9%86%D8%B5%D8%B1", 
                "tweet_volume": 67776, 
                "name": "#\u0627\u0644\u0627\u062a\u062d\u0627\u062f_\u0627\u0644\u0646\u0635\u0631", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23OpeningCeremony", 
                "query": "%23OpeningCeremony", 
                "tweet_volume": 49306, 
                "name": "#OpeningCeremony", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%D8%A7%D9%84%D8%B1%D8%A7%D8%AA%D8%A8_%D9%85%D8%A7_%D9%8A%D9%83%D9%81%D9%8A_%D8%A7%D9%84%D9%85%D9%8A%D9%83_%D8%A7%D8%A8", 
                "query": "%23%D8%A7%D9%84%D8%B1%D8%A7%D8%AA%D8%A8_%D9%85%D8%A7_%D9%8A%D9%83%D9%81%D9%8A_%D8%A7%D9%84%D9%85%D9%8A%D9%83_%D8%A7%D8%A8", 
                "tweet_volume": 11458, 
                "name": "#\u0627\u0644\u0631\u0627\u062a\u0628_\u0645\u0627_\u064a\u0643\u0641\u064a_\u0627\u0644\u0645\u064a\u0643_\u0627\u0628", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23PaulONeal", 
                "query": "%23PaulONeal", 
                "tweet_volume": 29285, 
                "name": "#PaulONeal", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%EB%AA%A8%EC%97%90%ED%99%94", 
                "query": "%EB%AA%A8%EC%97%90%ED%99%94", 
                "tweet_volume": null, 
                "name": "\ubaa8\uc5d0\ud654", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=Pel%C3%A9", 
                "query": "Pel%C3%A9", 
                "tweet_volume": 49187, 
                "name": "Pel\u00e9", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22Are+Camila+and+Lauren%22", 
                "query": "%22Are+Camila+and+Lauren%22", 
                "tweet_volume": 13455, 
                "name": "Are Camila and Lauren", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22Ba%C5%9Fkomutan+Y%C3%BCceATAT%C3%9CRK%22", 
                "query": "%22Ba%C5%9Fkomutan+Y%C3%BCceATAT%C3%9CRK%22", 
                "tweet_volume": null, 
                "name": "Ba\u015fkomutan Y\u00fcceATAT\u00dcRK", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22%C3%9Clk%C3%BCc%C3%BCOlmak+%C5%9Eereftir%22", 
                "query": "%22%C3%9Clk%C3%BCc%C3%BCOlmak+%C5%9Eereftir%22", 
                "tweet_volume": 10797, 
                "name": "\u00dclk\u00fcc\u00fcOlmak \u015eereftir", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%EC%9E%90%EA%B8%B0%ED%88%AC%EC%98%81", 
                "query": "%EC%9E%90%EA%B8%B0%ED%88%AC%EC%98%81", 
                "tweet_volume": null, 
                "name": "\uc790\uae30\ud22c\uc601", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23DeberiaSerDeporteOlimpico", 
                "query": "%23DeberiaSerDeporteOlimpico", 
                "tweet_volume": 11589, 
                "name": "#DeberiaSerDeporteOlimpico", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23HalilKantarc%C4%B1Yetimhanesi", 
                "query": "%23HalilKantarc%C4%B1Yetimhanesi", 
                "tweet_volume": null, 
                "name": "#HalilKantarc\u0131Yetimhanesi", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MentalHealthCareSoPoor", 
                "query": "%23MentalHealthCareSoPoor", 
                "tweet_volume": 13565, 
                "name": "#MentalHealthCareSoPoor", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23BuenViernes", 
                "query": "%23BuenViernes", 
                "tweet_volume": 42202, 
                "name": "#BuenViernes", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23NormaniIsImportant", 
                "query": "%23NormaniIsImportant", 
                "tweet_volume": 15562, 
                "name": "#NormaniIsImportant", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%C5%9EehidineSahip%C3%87%C4%B1k", 
                "query": "%23%C5%9EehidineSahip%C3%87%C4%B1k", 
                "tweet_volume": 41874, 
                "name": "#\u015eehidineSahip\u00c7\u0131k", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23ClickMyFingers", 
                "query": "%23ClickMyFingers", 
                "tweet_volume": 19458, 
                "name": "#ClickMyFingers", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%D0%A2%D0%B2%D0%B8%D1%82%D1%82%D0%B5%D1%80%D1%81%D0%BA%D0%B8%D0%B9%D0%98%D0%B7%D0%A2%D0%B2%D0%BE%D0%B5%D0%B3%D0%BE%D0%93%D0%BE%D1%80%D0%BE%D0%B4%D0%B0", 
                "query": "%23%D0%A2%D0%B2%D0%B8%D1%82%D1%82%D0%B5%D1%80%D1%81%D0%BA%D0%B8%D0%B9%D0%98%D0%B7%D0%A2%D0%B2%D0%BE%D0%B5%D0%B3%D0%BE%D0%93%D0%BE%D1%80%D0%BE%D0%B4%D0%B0", 
                "tweet_volume": null, 
                "name": "#\u0422\u0432\u0438\u0442\u0442\u0435\u0440\u0441\u043a\u0438\u0439\u0418\u0437\u0422\u0432\u043e\u0435\u0433\u043e\u0413\u043e\u0440\u043e\u0434\u0430", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23VitorPereiraVarsaBizYokuz", 
                "query": "%23VitorPereiraVarsaBizYokuz", 
                "tweet_volume": 29927, 
                "name": "#VitorPereiraVarsaBizYokuz", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%D8%B5%D8%AD%D9%8A%D9%81%D9%87_%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%B6_%D8%AA%D8%AF%D8%B9%D9%85_%D8%A7%D9%84%D8%A7%D8%B3%D8%AF", 
                "query": "%23%D8%B5%D8%AD%D9%8A%D9%81%D9%87_%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%B6_%D8%AA%D8%AF%D8%B9%D9%85_%D8%A7%D9%84%D8%A7%D8%B3%D8%AF", 
                "tweet_volume": 52905, 
                "name": "#\u0635\u062d\u064a\u0641\u0647_\u0627\u0644\u0631\u064a\u0627\u0636_\u062a\u062f\u0639\u0645_\u0627\u0644\u0627\u0633\u062f", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FridayFeeling", 
                "query": "%23FridayFeeling", 
                "tweet_volume": 85572, 
                "name": "#FridayFeeling", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23CuentaWYLS", 
                "query": "%23CuentaWYLS", 
                "tweet_volume": 27538, 
                "name": "#CuentaWYLS", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FlashbackFriday", 
                "query": "%23FlashbackFriday", 
                "tweet_volume": 23282, 
                "name": "#FlashbackFriday", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MarioBautistaEnHoy", 
                "query": "%23MarioBautistaEnHoy", 
                "tweet_volume": 24315, 
                "name": "#MarioBautistaEnHoy", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%D9%83%D9%85_%D8%B9%D9%86%D8%AF%D9%83_%D8%B1%D9%82%D9%85_%D8%A8%D9%86%D8%AA_%D9%85%D9%86_%D8%AA%D9%88%D9%8A%D8%AA%D8%B1", 
                "query": "%23%D9%83%D9%85_%D8%B9%D9%86%D8%AF%D9%83_%D8%B1%D9%82%D9%85_%D8%A8%D9%86%D8%AA_%D9%85%D9%86_%D8%AA%D9%88%D9%8A%D8%AA%D8%B1", 
                "tweet_volume": null, 
                "name": "#\u0643\u0645_\u0639\u0646\u062f\u0643_\u0631\u0642\u0645_\u0628\u0646\u062a_\u0645\u0646_\u062a\u0648\u064a\u062a\u0631", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23A41MesesDeTuSiembraComandante", 
                "query": "%23A41MesesDeTuSiembraComandante", 
                "tweet_volume": 39635, 
                "name": "#A41MesesDeTuSiembraComandante", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MakeMeVideo", 
                "query": "%23MakeMeVideo", 
                "tweet_volume": null, 
                "name": "#MakeMeVideo", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FCKH96", 
                "query": "%23FCKH96", 
                "tweet_volume": null, 
                "name": "#FCKH96", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23TiroConArco", 
                "query": "%23TiroConArco", 
                "tweet_volume": null, 
                "name": "#TiroConArco", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23WhenIStressOutI", 
                "query": "%23WhenIStressOutI", 
                "tweet_volume": null, 
                "name": "#WhenIStressOutI", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MinhaInfanciaFoiBoaPq", 
                "query": "%23MinhaInfanciaFoiBoaPq", 
                "tweet_volume": 22352, 
                "name": "#MinhaInfanciaFoiBoaPq", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23Felsefeye31Kadro", 
                "query": "%23Felsefeye31Kadro", 
                "tweet_volume": null, 
                "name": "#Felsefeye31Kadro", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23NABJNAHJ16", 
                "query": "%23NABJNAHJ16", 
                "tweet_volume": 18229, 
                "name": "#NABJNAHJ16", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23LaFieraGranFinal", 
                "query": "%23LaFieraGranFinal", 
                "tweet_volume": null, 
                "name": "#LaFieraGranFinal", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23VisibleWomen", 
                "query": "%23VisibleWomen", 
                "tweet_volume": null, 
                "name": "#VisibleWomen", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23BlogHer16", 
                "query": "%23BlogHer16", 
                "tweet_volume": null, 
                "name": "#BlogHer16", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23110MilletvekiliAran%C4%B1yor", 
                "query": "%23110MilletvekiliAran%C4%B1yor", 
                "tweet_volume": 12648, 
                "name": "#110MilletvekiliAran\u0131yor", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%D8%B3%D8%A7%D8%B9%D9%87_%D8%A7%D8%B3%D8%AA%D8%AC%D8%A7%D8%A8%D9%87", 
                "query": "%23%D8%B3%D8%A7%D8%B9%D9%87_%D8%A7%D8%B3%D8%AA%D8%AC%D8%A7%D8%A8%D9%87", 
                "tweet_volume": 86440, 
                "name": "#\u0633\u0627\u0639\u0647_\u0627\u0633\u062a\u062c\u0627\u0628\u0647", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23RendUnFilmX", 
                "query": "%23RendUnFilmX", 
                "tweet_volume": null, 
                "name": "#RendUnFilmX", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23QueremosRock", 
                "query": "%23QueremosRock", 
                "tweet_volume": null, 
                "name": "#QueremosRock", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23LinhaDACSophiaAbrah%C3%A3o", 
                "query": "%23LinhaDACSophiaAbrah%C3%A3o", 
                "tweet_volume": null, 
                "name": "#LinhaDACSophiaAbrah\u00e3o", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23SiTodoSaleBien", 
                "query": "%23SiTodoSaleBien", 
                "tweet_volume": null, 
                "name": "#SiTodoSaleBien", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23QuerUmConselho", 
                "query": "%23QuerUmConselho", 
                "tweet_volume": null, 
                "name": "#QuerUmConselho", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23DiaDeLaCerveza", 
                "query": "%23DiaDeLaCerveza", 
                "tweet_volume": 32781, 
                "name": "#DiaDeLaCerveza", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23SanaBirS%C4%B1rVerece%C4%9Fim", 
                "query": "%23SanaBirS%C4%B1rVerece%C4%9Fim", 
                "tweet_volume": null, 
                "name": "#SanaBirS\u0131rVerece\u011fim", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23InternationalBeerDay", 
                "query": "%23InternationalBeerDay", 
                "tweet_volume": 19066, 
                "name": "#InternationalBeerDay", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23SuicideSquadRejects", 
                "query": "%23SuicideSquadRejects", 
                "tweet_volume": null, 
                "name": "#SuicideSquadRejects", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23%D9%8A%D8%A7%D8%B3%D8%B1_%D8%A7%D9%84%D9%82%D8%AD%D8%B7%D8%A7%D9%86%D9%8A_11_%D8%B3%D9%86%D9%87_%D9%81%D9%8A_%D8%A7%D9%84%D9%87%D9%84%D8%A7%D9%84", 
                "query": "%23%D9%8A%D8%A7%D8%B3%D8%B1_%D8%A7%D9%84%D9%82%D8%AD%D8%B7%D8%A7%D9%86%D9%8A_11_%D8%B3%D9%86%D9%87_%D9%81%D9%8A_%D8%A7%D9%84%D9%87%D9%84%D8%A7%D9%84", 
                "tweet_volume": null, 
                "name": "#\u064a\u0627\u0633\u0631_\u0627\u0644\u0642\u062d\u0637\u0627\u0646\u064a_11_\u0633\u0646\u0647_\u0641\u064a_\u0627\u0644\u0647\u0644\u0627\u0644", 
                "promoted_content": null
            }
        ], 
        "as_of": "2016-08-05T19:18:30Z", 
        "locations": [
            {
                "woeid": 1, 
                "name": "Worldwide"
            }
        ]
    }
]

[
    {
        "created_at": "2016-08-05T19:13:35Z", 
        "trends": [
            {
                "url": "http://twitter.com/search?q=%23PaulONeal", 
                "query": "%23PaulONeal", 
                "tweet_volume": 29285, 
                "name": "#PaulONeal", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23OpeningCeremony", 
                "query": "%23OpeningCeremony", 
                "tweet_volume": 49306, 
                "name": "#OpeningCeremony", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FridayFeeling", 
                "query": "%23FridayFeeling", 
                "tweet_volume": 85572, 
                "name": "#FridayFeeling", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23NABJNAHJ16", 
                "query": "%23NABJNAHJ16", 
                "tweet_volume": 18229, 
                "name": "#NABJNAHJ16", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FlashbackFriday", 
                "query": "%23FlashbackFriday", 
                "tweet_volume": 23282, 
                "name": "#FlashbackFriday", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22Mark+Teixeira%22", 
                "query": "%22Mark+Teixeira%22", 
                "tweet_volume": 18881, 
                "name": "Mark Teixeira", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22I+Ran+the+C.I.A.+Now%22", 
                "query": "%22I+Ran+the+C.I.A.+Now%22", 
                "tweet_volume": 18357, 
                "name": "I Ran the C.I.A. Now", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22Purple+Lamborghini%22", 
                "query": "%22Purple+Lamborghini%22", 
                "tweet_volume": 14316, 
                "name": "Purple Lamborghini", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22Nate+Parker%22", 
                "query": "%22Nate+Parker%22", 
                "tweet_volume": null, 
                "name": "Nate Parker", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22ON+SALE+NOW%22", 
                "query": "%22ON+SALE+NOW%22", 
                "tweet_volume": 10186, 
                "name": "ON SALE NOW", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%22Charlie+Strong%22", 
                "query": "%22Charlie+Strong%22", 
                "tweet_volume": null, 
                "name": "Charlie Strong", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23WhenIStressOutI", 
                "query": "%23WhenIStressOutI", 
                "tweet_volume": null, 
                "name": "#WhenIStressOutI", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23BlogHer16", 
                "query": "%23BlogHer16", 
                "tweet_volume": null, 
                "name": "#BlogHer16", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23VisibleWomen", 
                "query": "%23VisibleWomen", 
                "tweet_volume": null, 
                "name": "#VisibleWomen", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23SuicideSquadRejects", 
                "query": "%23SuicideSquadRejects", 
                "tweet_volume": null, 
                "name": "#SuicideSquadRejects", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23InternationalBeerDay", 
                "query": "%23InternationalBeerDay", 
                "tweet_volume": 19066, 
                "name": "#InternationalBeerDay", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FlippinGinjaIsOverParty", 
                "query": "%23FlippinGinjaIsOverParty", 
                "tweet_volume": null, 
                "name": "#FlippinGinjaIsOverParty", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MentalHealthCareSoPoor", 
                "query": "%23MentalHealthCareSoPoor", 
                "tweet_volume": 13565, 
                "name": "#MentalHealthCareSoPoor", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23LastTimeFrankDroppedAnAlbum", 
                "query": "%23LastTimeFrankDroppedAnAlbum", 
                "tweet_volume": 11511, 
                "name": "#LastTimeFrankDroppedAnAlbum", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FMLA23", 
                "query": "%23FMLA23", 
                "tweet_volume": null, 
                "name": "#FMLA23", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23newtanavideo", 
                "query": "%23newtanavideo", 
                "tweet_volume": null, 
                "name": "#newtanavideo", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23ReadWhereYouAre", 
                "query": "%23ReadWhereYouAre", 
                "tweet_volume": null, 
                "name": "#ReadWhereYouAre", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23ShopEdmond", 
                "query": "%23ShopEdmond", 
                "tweet_volume": null, 
                "name": "#ShopEdmond", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23DolansMakeMeConfident", 
                "query": "%23DolansMakeMeConfident", 
                "tweet_volume": null, 
                "name": "#DolansMakeMeConfident", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23NameABandsNextTour", 
                "query": "%23NameABandsNextTour", 
                "tweet_volume": null, 
                "name": "#NameABandsNextTour", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MakeMeVideo", 
                "query": "%23MakeMeVideo", 
                "tweet_volume": null, 
                "name": "#MakeMeVideo", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23seriousacademic", 
                "query": "%23seriousacademic", 
                "tweet_volume": null, 
                "name": "#seriousacademic", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23DAPGO", 
                "query": "%23DAPGO", 
                "tweet_volume": 45302, 
                "name": "#DAPGO", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23VRLA", 
                "query": "%23VRLA", 
                "tweet_volume": null, 
                "name": "#VRLA", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23hannibalmontanabalexperience", 
                "query": "%23hannibalmontanabalexperience", 
                "tweet_volume": null, 
                "name": "#hannibalmontanabalexperience", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23VRAChat", 
                "query": "%23VRAChat", 
                "tweet_volume": null, 
                "name": "#VRAChat", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23jobsreport", 
                "query": "%23jobsreport", 
                "tweet_volume": 12140, 
                "name": "#jobsreport", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23HyperMasculAZNs", 
                "query": "%23HyperMasculAZNs", 
                "tweet_volume": null, 
                "name": "#HyperMasculAZNs", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MLGOrlando", 
                "query": "%23MLGOrlando", 
                "tweet_volume": null, 
                "name": "#MLGOrlando", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23NewMusicFriday", 
                "query": "%23NewMusicFriday", 
                "tweet_volume": null, 
                "name": "#NewMusicFriday", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23MansionTonight", 
                "query": "%23MansionTonight", 
                "tweet_volume": null, 
                "name": "#MansionTonight", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23RememberOakCreek", 
                "query": "%23RememberOakCreek", 
                "tweet_volume": null, 
                "name": "#RememberOakCreek", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23DontTellTheKidsBut", 
                "query": "%23DontTellTheKidsBut", 
                "tweet_volume": null, 
                "name": "#DontTellTheKidsBut", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23FoodFri", 
                "query": "%23FoodFri", 
                "tweet_volume": null, 
                "name": "#FoodFri", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23SashaBanksGotMarried", 
                "query": "%23SashaBanksGotMarried", 
                "tweet_volume": null, 
                "name": "#SashaBanksGotMarried", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%231YearSinceOTRAMetLife", 
                "query": "%231YearSinceOTRAMetLife", 
                "tweet_volume": null, 
                "name": "#1YearSinceOTRAMetLife", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23OlympicMoment", 
                "query": "%23OlympicMoment", 
                "tweet_volume": null, 
                "name": "#OlympicMoment", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23KimojiMerch", 
                "query": "%23KimojiMerch", 
                "tweet_volume": null, 
                "name": "#KimojiMerch", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23CTRRS", 
                "query": "%23CTRRS", 
                "tweet_volume": null, 
                "name": "#CTRRS", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23pubpeopleormovies", 
                "query": "%23pubpeopleormovies", 
                "tweet_volume": null, 
                "name": "#pubpeopleormovies", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23NormaniIsImportant", 
                "query": "%23NormaniIsImportant", 
                "tweet_volume": 15562, 
                "name": "#NormaniIsImportant", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23myprintly", 
                "query": "%23myprintly", 
                "tweet_volume": null, 
                "name": "#myprintly", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23CheezIt355", 
                "query": "%23CheezIt355", 
                "tweet_volume": null, 
                "name": "#CheezIt355", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23HappyBirthdayElvisDuran", 
                "query": "%23HappyBirthdayElvisDuran", 
                "tweet_volume": null, 
                "name": "#HappyBirthdayElvisDuran", 
                "promoted_content": null
            }, 
            {
                "url": "http://twitter.com/search?q=%23patientchat", 
                "query": "%23patientchat", 
                "tweet_volume": null, 
                "name": "#patientchat", 
                "promoted_content": null
            }
        ], 
        "as_of": "2016-08-05T19:18:31Z", 
        "locations": [
            {
                "woeid": 23424977, 
                "name": "United States"
            }
        ]
    }
]

Ademas podemos fundir las listas o diccionarios como si de un base de datos relacional se tratara, esto por ejemplo con el fin de revelar los elementos comunes entre las Trends o Tendencias, debemos saber que puede o no haber solapamiento entre los datos, esto depende de que datos estamos interceptando, podemos usar el código siguiente:

 

worl_trends_set = set ([trend["name"] 
 for trend in worl_trends[0]['trends']])

us_trends_set = set ([trend["name"] 
 for trend in us_trends[0]['trends']])

common_trends = worl_trends_set.intersection(us_trends_set)



print common_trends

Con este código vamos a obtener lo siguiente:

 

["#MakeMeVideo", "#NABJNAHJ16", "#SuicideSquadRejects", "#VisibleWomen", "#MentalHealthCareSoPoor", "#FlashbackFriday", "#NormaniIsImportant", "#OpeningCeremony", "#FridayFeeling", "#BlogHer16", "#InternationalBeerDay", "#PaulONeal", "#WhenIStressOutI"]

Es una salida un poco fea :S, ahora vamos a implementar un for para ir visualizando cada elemento de la lista y ademas vamos a colocarles un id a la manera python(ya luego lo haremos con sqlite3) y lo vamos a agregar desde el diccionario(aunque la estructura parece un tupla o lista) a la base de datos, este es el código y hasta aquí lo voy a dejar por hoy mañana comentamos un poco el código y la salida:

 


import twitter, json, sqlite3
# Lo primero que debemos hacer es ir a http://dev.twitter.com/apps/new y crear una app
#puedes ver https://dev.twitter.com/docs/auth/oauth para mas informacion
#las credenciales que necesitamos debemos copiarlas de XXXXXXXXXXXXXXXXXXXXXX y usarlas tal como se muestrasn en las imagenes de esta entrada ZZZZZZZZZZZZZZZZZZZZZZZzz

CONSUMER_KEY = 'Recuerda A'

CONSUMER_SECRET = 'Datos B'

OAUTH_TOKEN = 'Datos C'

OAUTH_TOKEN_SECRET = 'DatosD'



auth = twitter.oauth.OAuth(  OAUTH_TOKEN , OAUTH_TOKEN_SECRET, CONSUMER_KEY , CONSUMER_SECRET )

twitter_api = twitter.Twitter(auth=auth)

conn = sqlite3.connect('CuentasIntersecciones.sqlite') #Agregado de los conocimientos de la especializacion

cur = conn.cursor() # Agregado


cur.execute('''
DROP TABLE IF EXISTS CuentasComunicadas''')

cur.execute('''
CREATE TABLE CuentasComunicadas (cuenta TEXT, cuenta_id INTEGER)''')

word = cur.fetchone()

cuenta_id = 0

WORL_WOE_ID = 1

US_WOE_ID = 23424977

worl_trends = twitter_api.trends.place(_id=WORL_WOE_ID)

us_trends = twitter_api.trends.place(_id=US_WOE_ID)


worl_trends_set = set ([trend["name"] 
			for trend in worl_trends[0]['trends']])

us_trends_set = set ([trend["name"] 
			for trend in us_trends[0]['trends']])

common_trends = worl_trends_set.intersection(us_trends_set)

for word in common_trends:
  print word
  cuenta= str(word)
  cur = conn.cursor()
  cur.execute('''INSERT INTO CuentasComunicadas (cuenta,cuenta_id) VALUES ( ?, ? ) ''', (cuenta, cuenta_id))
  cuenta_id +=1

SQLSTR = "SELECT  cuenta,cuenta_id FROM CuentasComunicadas"

print
print
for word in cur.execute(SQLSTR):
  print str(word[0]), word[1]


conn.commit()
cur.close()

La salida del programa es la siguiente:

 

> python ej1_conBD_twiter1.py 
#SuicideSquadRejects
#VisibleWomen
#MakeMe
#FlashbackFriday
#LastTimeFrankDroppedAnAlbum
#NormaniIsImportant
#OpeningCeremony
#MentalHealthCareSoPoor
#BlogHer16
#PaulONeal
#AustinMahoneOnLiveStream
#WhenIStressOutI


#SuicideSquadRejects 0
#VisibleWomen 1
#MakeMe 2
#FlashbackFriday 3
#LastTimeFrankDroppedAnAlbum 4
#NormaniIsImportant 5
#OpeningCeremony 6
#MentalHealthCareSoPoor 7
#BlogHer16 8
#PaulONeal 9
#AustinMahoneOnLiveStream 10

 

Hasta mañana, recuerda comentar es agradecer y es importante para mi ser de ayuda con mi tiempo libre 😀

Sigue desde el principio esta serie y el por que me he animado a escribir sobre este tema:

Jugando con la API de Twitter [Parte 1]

Experiencia de La Especialización Python para toda la vida