29 oct. 2013

Webscraping con Python Mechanize y BeautifulSoup4

Ahora se utilizará a Python Mechanize con BeautifulSoup4 para extraer la información de la salida y ocultamiento del sol en Venezuela con un breve cambio para mostrar el dinamismo que se le puede dar a la extracción de datos de una página web.

En este caso se extraerá información del mismo sitio timeanddate, la diferencia es que en vez de sólo pasarle el código de Venezuela (58), se le pasará el mes y el año.


El código muestra la información del amanecer y atardecer de todo el mes de Octubre y Noviembre.

A continuación se muestra el código:
#!/usr/bin/env python
#Se importa mechanize y cookielib
import mechanize
import cookielib
#Se importa beautifulSoup
from BeautifulSoup import BeautifulSoup
def DefinirUrl(mes,agno):
    #Se pasa el url del sitio timeanddate con la informacion
    #de la salida y ocultamiento del sol en Venezuela.
    return "http://www.timeanddate.com/worldclock/astronomy.htmln=58&month=%s&year=%s&obj=sun&afl=-11&day=1" %(mes,agno)
def CapturarInformacion(mes,agno):
    #Se crea una instancia de Browser
    br = mechanize.Browser()
    #Se crea una instancia para la Cookie
    cj = cookielib.LWPCookieJar()
    #Se asocia la instancia del cookie con el navegador.
    br.set_cookiejar(cj)
    #Se deshabilita el manejo de robots.txt
    br.set_handle_robots(False)
    #Se define el tiempo de refrescamiento
    br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
    #Se pasa el url del sitio timeanddate con la informacion
    url = DefinirUrl(mes,agno)
    #de la salida y ocultamiento del sol en Venezuela.
    #Se define las cabeceras del navegador, en este caso se le esta diciendo
    # que el navegador es un firefox desde Linux Debian
    br.addheaders = [('User-agent',
         'Mozilla/5.0 (X11; U; Linux i686; es-VE; rv:1.9.0.1)Gecko/2008071615 Debian/6.0 Firefox/9')]
    #Se abre el url
    r = br.open(url)
    #Se lee el htmml de la pagina
    html = br.response().read()
    #Se crea una instancia de BeautifulSoup pasando el html
    #a verificar
    soup = BeautifulSoup(html)
    #Se busca la palabra table, y de ahi class y se
    #busca el contenido
    #de cada columna de la tabla.
    for row in soup('table', {'class': 'spad'})[0].tbody('tr'):
        tds = row('td')
        #Se muestra la fecha y hora de la salida del sol
        print tds[0].string, tds[1].string,tds[2].string
if __name__== "__main__":
    print "Se muestra la informacion del mes de Octubre"
    print "--------------------------------------------"
    CapturarInformacion(10,2013)
    print "Se muestra la informacion del mes de Noviembre"
    print "--------------------------------------------" 
    CapturarInformacion(11,2013)
A continuación se muestra el resultado del script:
Se muestra la informacion del mes de Octubre

--------------------------------------------

1 Oct 2013 05:46 17:48

2 Oct 2013 05:46 17:47

3 Oct 2013 05:46 17:47

4 Oct 2013 05:46 17:46

5 Oct 2013 05:46 17:45

6 Oct 2013 05:46 17:45

7 Oct 2013 05:46 17:44

8 Oct 2013 05:46 17:44

9 Oct 2013 05:46 17:43

10 Oct 2013 05:46 17:43

11 Oct 2013 05:46 17:42

12 Oct 2013 05:46 17:42

13 Oct 2013 05:46 17:41

14 Oct 2013 05:46 17:41

15 Oct 2013 05:46 17:40

16 Oct 2013 05:46 17:40

17 Oct 2013 05:46 17:39

18 Oct 2013 05:47 17:39

19 Oct 2013 05:47 17:38

20 Oct 2013 05:47 17:38

21 Oct 2013 05:47 17:37

22 Oct 2013 05:47 17:37

23 Oct 2013 05:47 17:36

24 Oct 2013 05:47 17:36

25 Oct 2013 05:47 17:36

26 Oct 2013 05:48 17:35

27 Oct 2013 05:48 17:35

28 Oct 2013 05:48 17:35

29 Oct 2013 05:48 17:34

30 Oct 2013 05:48 17:34

31 Oct 2013 05:48 17:34

Se muestra la informacion del mes de Noviembre

--------------------------------------------

1 Nov 2013 05:49 17:33

2 Nov 2013 05:49 17:33

3 Nov 2013 05:49 17:33

4 Nov 2013 05:49 17:33

5 Nov 2013 05:50 17:33

6 Nov 2013 05:50 17:32

7 Nov 2013 05:50 17:32

8 Nov 2013 05:51 17:32

9 Nov 2013 05:51 17:32

10 Nov 2013 05:51 17:32

11 Nov 2013 05:51 17:32

12 Nov 2013 05:52 17:32

13 Nov 2013 05:52 17:32

14 Nov 2013 05:53 17:31

15 Nov 2013 05:53 17:31

16 Nov 2013 05:53 17:31

17 Nov 2013 05:54 17:31

18 Nov 2013 05:54 17:31

19 Nov 2013 05:54 17:32

20 Nov 2013 05:55 17:32

21 Nov 2013 05:55 17:32

22 Nov 2013 05:56 17:32

23 Nov 2013 05:56 17:32

24 Nov 2013 05:57 17:32

25 Nov 2013 05:57 17:32

26 Nov 2013 05:58 17:32

27 Nov 2013 05:58 17:32

28 Nov 2013 05:59 17:33

29 Nov 2013 05:59 17:33

30 Nov 2013 06:00 17:33

Como se muestra ya se puede agregar dinamismo a las busquedas que se quiera realizar en una página web, extrayendo su información al pasarle datos al url. Además se muestra como usar Python Mechanize para la captura de la página web y BeautifulSoup4 para capturar la información necesaria.

28 oct. 2013

Extracción de datos con Scraperwiki y Python

Continuando con los artículos sobre webscraping con Python, le toca el turno a Scraperwiki.

La documentación de Scraperwiki la pueden encontrar acá.

Aparte de una librería para Python, tiene un sitio interactivo donde puede usar ScraperWiki para Ruby, Php y Python, en el siguiente enlace  pueden ver la interfaz web de ScraperWiki para Python.

Este artículo se basa en el tutorial oficial de ScraperWiki.

En la siguiente figura se muestra la página web de ScraperWiki para Python:


La siguiente imagen muestra la información de la salida y ocultamiento del Sol en Venezuela del sitio timeanddate:

Se muestra a continuación una imagen del código html de la página de la imagen anterior, sombreando la parte de dicho código que nos interesa:

Para instalar ScraperWiki se ejecuta el comando pip:
#pip install scraperwiki

El código para extraer la información se muestra a continuación:
#!/usr/bin/env python
#importar scraperwiki
import scraperwiki
#importar lxml.html
import lxml.html
#Url de la pagina timeanddate de la
#info de Venezuela.
url = "http://www.timeanddate.com/worldclock/astronomy.html?n=58"
#se crea la instancia de la clase scrape pasando el
#url del sitio a extraer la informacion.
html = scraperwiki.scrape(url)
#Se busca en el codigo html de la pagina
root = lxml.html.fromstring(html)
#Se crea una lista que almacenara los diccionarios conteniendo
#la informacion que se necesita
lista = []
#Se busca el tag html tbody y tr.
#Esto genera una lista con el contenido del tbody.Esto
#se recorre dicha lista
for tr in root.cssselect("tbody tr "):
    #Se selecciona la informacion que aparece en
    #el tag html td
    tds = tr.cssselect("td")
    #Se guarda la informacion en un diccionario
    datos = {
        'fecha': tds[0].text_content(),
        'amanecer': tds[1].text_content(),
        'atardecer': tds[2].text_content()
    }
    #Se agrega los datos a la lista
    lista.append(datos)
#Se muestra la lista en pantalla
for i in lista:
    print i
El resultado de la ejecución del script a continuación:
{'fecha': '26 Oct 2013', 'atardecer': '17:35', 'amanecer': '05:48'}

{'fecha': '27 Oct 2013', 'atardecer': '17:35', 'amanecer': '05:48'}

{'fecha': '28 Oct 2013', 'atardecer': '17:35', 'amanecer': '05:48'}

{'fecha': '29 Oct 2013', 'atardecer': '17:34', 'amanecer': '05:48'}

{'fecha': '30 Oct 2013', 'atardecer': '17:34', 'amanecer': '05:48'}

{'fecha': '31 Oct 2013', 'atardecer': '17:34', 'amanecer': '05:48'}

{'fecha': '1 Nov 2013', 'atardecer': '17:33', 'amanecer': '05:49'}


Puede revisar más tutoriales sobre ScraperWiki en el siguiente enlace.

27 oct. 2013

Extracción de datos de página web con pyquery y Python

Continuando con los artículos de webscraping ahora toca el turno a pyquery.

Ya la explicación de ubicación de la información que se desea obtener fue explicada en este artículo.

Pyqueary es una librería que permite hacer consultas de jquery y en documentos xml. 

La idea es obtener la información de la salida y ocultamiento del sol ya explicado en artículos anteriores. 

A continuación se muestra el código:
#!/usr/bin/env python
#importar pyquery
from pyquery import *
#Se Crea la instancia de la Clase PyQuery pasando el url de
#timeanddate.
html = PyQuery(url='http://www.timeanddate.com/worldclock/astronomy.html?n=58')
#Se busca el tag html de la tabla.
#Recibe todos los elementos de la tabla.
trs = html('table.spad tbody tr')
#Se muestra los elementos de la tabla.
print trs
#Se recorre los elementos de la tabla
for tr in trs:
    tds = tr.getchildren()
    print tds[1].text, tds[2].text
El resultado de la ejecución del script se muestra a continuación:
05:47 17:36

05:47 17:36

05:48 17:35

05:48 17:35

05:48 17:35

05:48 17:34

05:48 17:34


26 oct. 2013

Extracción de datos de páginas web con Scrapemark y Python

Continuando con los artículos sobre webscraping, ahora es el turno de scrapermark.

Se sigue usando como página de ejemplo timeanddate.com. Scrapermark usa expresiones regulares internamente lo que le da velocidad en la busqueda, utiliza un lenguaje parecido al HTML.

Para bajar scrapermark se puede bajar el egg o el fuente desde el siguiente enlace.

Para el caso del egg se ejecuta:
#easy_install scrapemark-0.9-py2.7.egg

Para el caso del fuente se descomprime el archivo .tar.gz :
#tar -xvf scrapemark-0.9.tar.gz
Luego se cambia al directorio y se ejecuta la instalación por medio del setup.py:
#cd scrapemark-0.9/
#python setup.py install


En el siguiente enlace se muestra un ejemplo de como se usa, para más ejemplos  puede visitar este enlace.

En este artículo se explica como buscar la información que se necesita extraer de la página antes mencionada.

La idea es extraer las hora de salida y ocultamiento del sol para Venezuela.
A continuación se muestra el código:

#!/usr/bin/env python
#Se importa sys para pasar como argumento al programa
#el url del sitio timeanddate
import sys
#Se importa pprint para mostrar la informacion en la
#consola
from pprint import pprint
#se importa scrape
from scrapemark import scrape
#se ejecuta scrape pasando el tag html de la tabla
#donde se encuentra la fila de la informacion de la salida
#y ocultamiento del sol.
#se le pasa como argumento en la linea de comandos
#el url de timeanddate.
resultado = scrape("""
    <table class="spad">
     <tbody>
      {*
       <tr>
          <td>{{[].day}}</td>
          <td>{{[].sunrise}}</td>
          <td>{{[].sunset}}</td>
      {# ... #}
     </tr>
     *}
 </tbody>
</table>
""",url=sys.argv[1] )
#Se muestra el resultado en pantalla
pprint (resultado)
El resultado de la ejecución del script es el siguiente:
ernesto@grievous:~$ python ej5.py http://www.timeanddate.com/worldclock/astronomy.html?n=58

fetching http://www.timeanddate.com/worldclock/astronomy.html?n=58 ...

DONE fetching.

[{'day': u'24 Oct 2013', 'sunrise': u'05:47', 'sunset': u'17:36'},

 {'day': u'25 Oct 2013', 'sunrise': u'05:47', 'sunset': u'17:36'},

 {'day': u'26 Oct 2013', 'sunrise': u'05:48', 'sunset': u'17:35'},

 {'day': u'27 Oct 2013', 'sunrise': u'05:48', 'sunset': u'17:35'},

 {'day': u'28 Oct 2013', 'sunrise': u'05:48', 'sunset': u'17:35'},

 {'day': u'29 Oct 2013', 'sunrise': u'05:48', 'sunset': u'17:34'},

 {'day': u'30 Oct 2013', 'sunrise': u'05:48', 'sunset': u'17:34'}]



25 oct. 2013

Extracción de datos en páginas web con Webscraping y Python

Continuando con la extracción de datos en la página timeanddate, la información de amanecer y atardecer en Venezuela.
En este caso se usará la librería webscraping. Para su instalación se usa el comando pip:
#pip install webscraping

En el artículo anterior se muestra como se ubica la información que se requiere.

A continuación se muestra el código:

#!/usr/bin/env python
#De webscraping se importa download y xpath
from webscraping import download, xpath
#Se define la instancia Download
D = download.Download()
#Se obtiene la informacion de la salida y ocultamiento del
#sol en Venezuela desde la pagina timeanddate.
html = D.get('http://www.timeanddate.com/worldclock/astronomy.html?n=58')
#Se busca la informacion en la tabla donde se muestra.
for row in xpath.search(html, '//table[@class="spad"]/tbody/tr'):
    #Se busca en la fila el tag /td
    cols = xpath.search(row, '/td')
    #Se muestra la informacion en pantalla
    print 'Amanecer: %s, Atardecer: %s' % (cols[1], cols[2])
A continuación se muestra el resultado de la ejecución del script:
Amanecer: 05:47, Atardecer: 17:36

Amanecer: 05:47, Atardecer: 17:36

Amanecer: 05:47, Atardecer: 17:36

Amanecer: 05:48, Atardecer: 17:35

Amanecer: 05:48, Atardecer: 17:35

Amanecer: 05:48, Atardecer: 17:35

Amanecer: 05:48, Atardecer: 17:34



24 oct. 2013

Webscraping o extracción de datos de páginas web con BeautifulSoup4 y Python

El webscraping es una técnica utilizada para extraer datos de una página web por medio de herramientas (más información en wikipedia).

Para Python existen varias herramientas:



En otros artículos se explicará el uso de cada herramienta mencionada. Ahora toca mostrar otro par de ejemplos de BeautifulSoup4.
El primer ejemplo captura la fecha y hora de la salida del sol para Venezuela del sitio timeanddate.
A continuación se muestra una imagen de la página timeanddate de la salida del sol en Venezuela.

A continuación se muestra la página timeanddate donde se va a inspeccionar el elemento de la fila mostrada en la imagen anterior:


Luego se muestra la imagen el código html de la fila mostrada en la imagen anterior:

El código se muestra a continuación:
#!/usr/bin/env python





#Importar urllib2 y BeautifulSoup


import urllib2


from BeautifulSoup import BeautifulSoup





#Se crea la instancia y se abre el url de timeanddate 


#buscando la informacion de la hora de salir el sol en Venezuela


soup = BeautifulSoup(urllib2.urlopen('http://www.timeanddate.com/worldclock/astronomy.html?n=58').read())





#Se busca la palabra table, y de ahi class y se busca el contenido


#de cada columna de la tabla.


for row in soup('table', {'class': 'spad'})[0].tbody('tr'):

    tds = row('td')


    #Se muestra la fecha y hora de la salida del sol


    print tds[0].string, tds[1].string


  





El resultado de la ejecución es la siguiente:
23 Oct 2013 05:47

24 Oct 2013 05:47

25 Oct 2013 05:47

26 Oct 2013 05:48

27 Oct 2013 05:48

28 Oct 2013 05:48

29 Oct 2013 05:48


El otro ejemplo es un código más ordenado de como extraer los enlaces de una página web.
En este caso se pedirá desde la línea de comandos el url del sitio que se desea extraer los urls, en vez de usar urllib2 se usará con beautifulsoup4 la librería request.
A continuación el código:
#!/usr/bin/env python
#Se importa BeautifulSoup
from bs4 import BeautifulSoup
#Se importa requests
import requests
#Se crea la clase Extraer 
class Extraer:
    def __init__(self,url):
        #Se asocia el url a self.__url
        self.__url = url
    #Se crea el método Enlaces, donde se crea una lista vacía
    #donde se lee el url con requests.get y se busca el tag a
    #luego se agrega a la lista cada link donde aparece el texo href
   #Se retorna la lista
    def Enlaces(self):
        self.__enlaces = []
        for link in BeautifulSoup(requests.get("http://" +url).text).find_all('a'):
            self.__enlaces.append((link.get('href')))
        return self.__enlaces
#Se ejecuta este script
if __name__ == "__main__":
#Se pide el url desde la línea de comandos
url = raw_input("Escriba el url del sitio que desea extraer informacion: ")
#Se crea la instancia de la clase donde se le pasa el url
ws = Extraer(url)
#Se muestra el texto Enlaces
print "Enlaces: "
#Se muestra cada enlace extraído
for enlace in ws.Enlaces():
    print enlace
El resultado se muestra a continuación:
ernesto@grievous:~/bin/python/webscraping$ python ej1.py 

Escriba el url del sitio que desea extraer informacion: 127.0.0.1:8000

Enlaces: 

/

/radios/pagina/1/

/acerca/

/login/


23 oct. 2013

Un introducción a Beautiful Soup 4 en Python.

Beautiful Soup es una librería de Python que facilita la extracción de datos de archivos html y xml.

Este artículo se basa en el artículo de Python For Beginners.

La documentación oficial se puede leer en el siguiente enlace.

Para instalar beautifulsoup es necesario tener instalado la librería python-bs4 el cual es un parser html.
#apt-get install python-bs4

Luego se instala beautiful soup 4:
#pip install beautifulsoup4

Para utilizar beautifulsoup se le puede pasar un archivo html o un URL, pero para capturar el archivo html se tiene que usar urllib2, beautifulsoup no lo hace sólo.

El API tiene varias formas de realizar filtros para la busqueda:
1. Busqueda por string, se usa la funciónn find_all:
soup.find_all("Prueba)

De esta forma se busca todas las palabras Prueba en el archivo.
2. Expresión regular:
El siguiente código muestra todos los tags html que comiencen con la letra b.
import re

for tag in soup.find_all(re.compile("^b")):

    print(tag.name)

El siguiente código muestra todos los tags html que contenga la letra b:
import re

for tag in soup.find_all(re.compile("b")):

    print(tag.name)

3. Una lista.
Al pasar una lista beautifulsoup encontrará cualquier elemento de la lista.
El siguiente código muestra como se encuentra todas las a y todas las b que aparezca:
print soup.find_all(["a","b"])

Para demostrar el uso de beautifulsoup se utilizará una aplicación en django que maneja un registro de radios por internet para la aplicación radiotray de Linux.

A continuación una captura de pantalla:

El código de ejemplo es el siguiente:
#!/usr/bin/env python
from bs4 import BeautifulSoup
import urllib2
#Se crea la instancia de BS pasando la URL con urllib2.
soup = BeautifulSoup(urllib2.urlopen("http://127.0.0.1:8000").read())
print "--------------------"
#Se muestra todo el contenido de la pagina
print soup.prettify()
print "---------------------"
#Se muestra el titulo de la pagina
print "Titulo" ,soup.title.string
print "----------------------"
#Se muestra el tag p de html que contiene la pagina
print soup.p
print "----------------------"
#Se muestra el tag a de html que contiene la pagina
print soup.a

A continuación se muestra una imagen con el resultado del programa:

Para extraer URLs de la página se busca el tag html a, luego lo que contenga la palabra href:
#!/usr/bin/env python
from bs4 import BeautifulSoup
import urllib2
#Se crea la instancia de BS pasando la URL con urllib2.
soup = BeautifulSoup(urllib2.urlopen("http://127.0.0.1:8000").read())
print "--------------------"
#Para extraer url de la pagina.
for link in soup.find_all('a'):
    print(link.get('href'))

El resultado se muestra a continuación:
--------------------
/
/radios/pagina/1/
/acerca/
/login/


Para extraer todo el texto de la página:

#!/usr/bin/env python
from bs4 import BeautifulSoup
import urllib2
#Se crea la instancia de BS pasando la URL con urllib2.
soup = BeautifulSoup(urllib2.urlopen("http://127.0.0.1:8000").read())
print "--------------------"
#Para extraer todo el texto de la pagina.
print(soup.get_text())
El resultado se muestra a continuación:
....
 Bienvenido 
/span
Radio
              	L
/.well 
Nuevas radios
/.well 
/span
/row
© Registro Radiotray 2013  
/.fluid-container
 Le javascript
    ================================================== 
 Placed at the end of the document so the pages load faster

Esta es la base para realizar webscraping que se explicará en el siguiente artículo.

14 oct. 2013

Obtener información de metadatos EXIF de una imagen con Python

Se probará con un simple script como obtener metadatos EXIF de dos imágenes, son dos fotos, la primera directamente del dispositivo móvil con que se tomó la foto, la segunda imagen se bajó desde Google+.

La idea es notar la diferencia de información que se obtiene de los metadatos de dos fotos idénticas para obtenidas de dos formas diferentes.

Lo primero que se tiene que hacer es instalar el módulo python llamado pyexiv2. Su documentación la pueden encontrar aquí.
Se puede instalar en Debian wheezy de la siguiente forma:
#apt-get install python-pyexiv2 python-pyexiv2-doc



La imagen original fue tomada desde un celular Motorola Razr XT910 y la segunda imagen se bajo desde Google+.
Imagen original con md5:
md5sum ecrespo-orig.jpg
a74977dbbd40d228658435b03db9a4c3  ecrespo-orig.jpg

El tamaño de la imagen es de 248k:
du  ecrespo-orig.jpg
248 ecrespo-orig.jpg

ecrespo-orig.jpg


Imagen bajada de Google+ con md5:
md5sum ecrespo.jpg
d1d41f5865bbb8360e6a748e38ae5ee1  ecrespo.jpg
El tamaño de la imagen es de 32k:
du ecrespo.jpg
32 ecrespo.jpg
ecrespo.jpg

El código que muestra los metadatos de exif de cada imagen es el siguiente:
#!/usr/bin/env python

#Se importa el modulo para analisis de metadatos de exif

import pyexiv2





#Se crea una funcion que devuelve en pantalla la informacion exif

def Meta(archivo):

    #Se crea la instancia metadata al pasarle el archivo que se quiere analizar

    metadata = pyexiv2.ImageMetadata(archivo)

    #Se lee el metadato

    metadata.read()

    #Se muestra en pantalla un mensaje

    print "Se muestra la informacion exif del archivo %s" %archivo

    print  "---------------------------------------------"

    #Se despliega la informacion de metadatos exif que contiene la imagen

    for metadato in metadata.exif_keys:

        texto = metadato + ": " + metadata[metadato].raw_value

        print texto





if __name__ == "__main__":

    Meta("ecrespo-orig.jpg")

    print "********************************************"

    Meta("ecrespo.jpg")

La salida del script es la siguiente:
Se muestra la informacion exif del archivo ecrespo-orig.jpg

---------------------------------------------

Exif.Image.YCbCrPositioning: 1

Exif.Image.XResolution: 72/1

Exif.Image.YResolution: 72/1

Exif.Image.ResolutionUnit: 2

Exif.Image.DateTime: 2013:09:08 13:10:00

Exif.Image.Make: Motorola

Exif.Image.Model: XT910

Exif.Image.ExifTag: 449

Exif.Photo.ExifVersion: 48 50 50 48

Exif.Photo.FlashpixVersion: 48 48 48 48

Exif.Photo.ColorSpace: 1

Exif.Photo.ComponentsConfiguration: 1 2 3 0

Exif.Photo.CompressedBitsPerPixel: 0/1

Exif.Photo.ExposureTime: 0/1000000

Exif.Photo.FNumber: 24/10

Exif.Photo.ExposureProgram: 0

Exif.Photo.ISOSpeedRatings: 0

Exif.Photo.ShutterSpeedValue: 0/1

Exif.Photo.ApertureValue: 3/1

Exif.Photo.BrightnessValue: 0/1

Exif.Photo.ExposureBiasValue: 0/10

Exif.Photo.MaxApertureValue: 3/1

Exif.Photo.SubjectDistance: 0/1

Exif.Photo.MeteringMode: 1

Exif.Photo.LightSource: 3

Exif.Photo.Flash: 24

Exif.Photo.FocalLength: 460/100

Exif.Photo.FlashEnergy: 0/1

Exif.Photo.ExposureIndex: 0/0

Exif.Photo.SceneType: 1

Exif.Photo.CustomRendered: 1

Exif.Photo.ExposureMode: 0

Exif.Photo.WhiteBalance: 0

Exif.Photo.DigitalZoomRatio: 65536/65535

Exif.Photo.SceneCaptureType: 0

Exif.Photo.GainControl: 0

Exif.Photo.Contrast: 0

Exif.Photo.Saturation: 0

Exif.Photo.Sharpness: 0

Exif.Photo.SubjectDistanceRange: 0

Exif.Image.GPSTag: 1243

Exif.Thumbnail.ImageWidth: 200

Exif.Thumbnail.ImageLength: 120

Exif.Thumbnail.Compression: 6

Exif.Thumbnail.XResolution: 72/1

Exif.Thumbnail.YResolution: 72/1

Exif.Thumbnail.ResolutionUnit: 2

Exif.Thumbnail.JPEGInterchangeFormat: 2027

Exif.Thumbnail.JPEGInterchangeFormatLength: 8033

********************************************

Se muestra la informacion exif del archivo ecrespo.jpg

---------------------------------------------

Exif.Image.Software: Google

Exif.Image.ExifTag: 46

Exif.Photo.ExifVersion: 48 50 50 48

Exif.Photo.0x9009: 10 39 8 1 16 1 24 0 32 0 40 0 48 0 56 0 64 0 72 1 80 0 88 0 96 1 104 1 112 0 120 1 128 1 1 136 1 1 144 1 1

Como se puede observar la imagen original bajada del dispositivo con Android tiene más información de metadatos exif que la imagen bajada de Google+, la primera foto tiene información del dispositivo, modelo entre otras cosas mientras que la segunda foto maneja información del software que proceso la imagen que es de Google.

26 sept. 2013

Mostrar tweets en tiempo real con twython y el API Stream de Twitter

En el artículo anterior se mostró como ver trendings topics por región, ahora se usará el API Stream de twitter para ver el flujo de tweets que recibe el usuario o lo que se publica en general en twitter.

La idea es usar twython con la clase TwythonStreamer para acceder a la API stream de twitter.

Del API de twitter se mostrará GET user el cual muestra los mensajes en flujo de un sólo usuario.

También se mostrará como usar POST status filter, el cual muestra todos los tweets públicos que contengan una palabra (track).

El primer ejemplo es con el GET user, el código a continuación:


#!/usr/bin/env python

# -*- coding: utf-8 -*-



#Se define el token de la aplicacion

CONSUMER_KEY = 'xxxxx'

CONSUMER_SECRET = 'xxxxx'

#Se define el acceso al usuario

ACCESS_KEY = 'xxxxx'

ACCESS_SECRET = 'xxxxx'



#Se importa TwythonStreamer

from twython import TwythonStreamer





#Se crea la clase MiStream que hereda de TwythonStreamer 

class MiStream(TwythonStreamer):

    #Se crea el metodo on_success que recibe data

    def on_success(self, data):

        #Si la palabra 'text' se encuentra en data se muestra en pantalla

        #su contenido

        if 'text' in data:

            print data['text'].encode('utf-8')

            #Si se desea desconectar luego del primer resultado?

            #self.disconnect()



    #Se crea el metodo on_error que recibe el codigo de estatus y data y se muestra en pantalla

    def on_error(self, status_code, data):

        print status_code, data

# Requires Authentication as of Twitter API v1.1
#Se crea la instancia de la clase MiStream con los parametros de autenticacion del API v1.1 de twittter.
stream = MiStreame(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
#Se recibe los tweets del usuario.
stream.user()



El resultado se muestra a continuación:


NASA puts papers from Curiosity rover behind paywall; @mbeisen points out this is illegal &amp; shares them http://t.co/UB1jQfRpLR #openaccess

ICYMI: Boost Mobile now offering Boost Warp 4G http://t.co/qvZKtZXqOn

Empoderando a la ciudadanía para mejorar la educación en México http://t.co/GnTqhDWqzv

BREAKING: Dodgers say man killed in altercation with Giants fans in SF was son of team security guard: http://t.co/CkB75Nkt0V

RT @Anonymous_Prodi: Posible bomba nuclear de baja intensidad en Siria http://t.co/uSjjVI1T3A @Famelica_legion @AquiyAhora_2013 @wikinotici…

guía de gobierno electrónico local: http://t.co/X6i7f8NHFe  servicios electrónicos orientados al ciudadano #eGov

¡Felicidades también a @jenniferpsayago por ser la ganadora de estos increíbles productos #Samsung y @Oakley_VE! http://t.co/ZfZnNtZtCf

#linux #fedora  #art  Re: Request to join the Design Team http://t.co/CuAuncfFPU

Del Gobierno Abierto como Política y la Apertura de Datos como Programa Público http://t.co/4fmZAHA8x6  #OpenData #OGov

#linux #fedora  #art  Re: Request to join the Design Team http://t.co/RiHSMifvBQ

3D printer duplicates paintings down to the last brush stroke http://t.co/suC4T3P2Lr #3DPrinting #art

Maduro: Mi ausencia en la ONU se debió a provocaciones que habían en mi contra http://t.co/Ed1ufBiPCW

Venezuela: Turismo “raspatarjetas” mató al turismo http://t.co/Rd18XiZYZu @kaosenlarednet mm

Como las iniciativas de Datos Abiertos pueden mejorar la vida en las Ciudades? http://t.co/j8FJOUd5mk  #OpenData

RT @csoghoian: Want to read the details of some NSA #LOVEINT surveillance abuses? Now you can, thanks to Senator @ChuckGrassley http://t.co…

¿Me está diciendo usted q su teoría mágica es: no tener teoría? Creo que eso no es muy anarquista, ni lógico tampoco @fascaso @loadupyourgun

Venezuela: Turismo “raspatarjetas” mató al turismo http://t.co/Rd18XiZYZu @kaosenlarednetmmmmm

RT @C354R_B3RMUD3Z: Te interesa saber de #Soporte Tecnico en #Gnu/Linux? #inscribete, es totalmente #gratuito informate por 04243165766

RT @csoghoian: Are you an NSA analyst? Suspect that your husband is cheating on you? Tap his phone, don't get prosecuted. Page 3 of http://…

Saturday Night Live lanza canal oficial de YouTube disponible para todo el mundo http://t.co/LDFcwFxsx0

Microsoft donated $100k to IPython http://t.co/sU2UP07dJ8

Crece el huracán: exitosos Niños Cantores de diversas tendencias políticas nos dieron hoy públicamente su apoyo http://t.co/SGDvxPrczA

How is everyone? I feel like I've been away for years when it's only been a few days.

Ahora se quiere se muestra todos los tweets públicos que contengan la palabra python, esto se logra al  sustituir la última línea del código anterior por stream.statuses.filter pasando el argumento track con la palabra a buscar.:

stream.statuses.filter(track='python')


El resultado se muestra a continuación:

lunes que viene #PUG  con pizza, cerveza, #python en @Dlabs_co . Yo no me la perdería...
Monty Python - The man who is alternately rude and polite: :#NowPlaying.#ClassicComedies..#ComedyGreats ,,,#Comedy.  http://t.co/IO3juw6nfD
Like a Kungfu master, a Pythonista knows how to kill with a single finger, and never to actually do it. http://t.co/xx0Sb8SsWV
RT @jpcolino: Python + Hadoop: Real Python in Pig trunk http://t.co/i4NZXrofvq
Affiliate Freelancer, Freelancing September 26, 2013 at 04:51PM Python web front end development by vishalchavda... http://t.co/V45nPv3LVI
Compressed 4h of Python, Win32 dbg API and Intel PIN in 2h. Still people seemed to like it. I guess a lot of people are into BSDM at @brucon
Go vs. Python: 10% longer, 10 times faster. http://t.co/v640YolHW4 and concurrent, statically compiled, and the libraries are all modern.
Quantitative Economics | #python #ebook http://t.co/eVjlO9VBoE
@MikeKellyofEM Hopefully a Monty Python style parrot...
por um tutorial de como aprender python em um dia
@tommyd_95 this could descend into a scene from a Monty Python movie ))

De esta forma se puede mejorar la captura de tweets en tiempo real  del timeline de un usuario o de todos los tweets públicos. 


22 sept. 2013

Descrubiendo Trending Topics de Twitter con twython y python

El artículo anterior muestra como probar la librería twython, hace poco se mostró en un artículo como ver los Trending Topics usando la librería python-twitter, ahora se mostrará como desplegar los topics usando la librería twython.

El script mostrará la conexión a twitter, luego despliega los identificadores de las ciudades que tienen Trending Topics en Venezuela y por último se despliega los Trending Topics de Venezuela en este momento.

Para saber como obtener el valor del token de la aplicación o de acceso se recomienda revisar el artículo anterior.
El código se muestra a continuación:

#!/usr/bin/env python

# -*- coding: utf-8 -*-



#Se define el token de la aplicacion

CONSUMER_KEY = 'xxxxx'

CONSUMER_SECRET = 'xxxxx'

#Se define el acceso al usuario

ACCESS_KEY = 'xxxxx'

ACCESS_SECRET = 'xxxxx'



#Se importa twython y de time a  sleep

from twython import Twython

from time import sleep



#Se define los argumentos del cliente, la ip y puerto del proxy, el tiempo de intento de la conexion y el nombre de la

#aplicacion cliente

client_args = {'headers': {'User-Agent': 'cmdtweetpy'},'proxies': {'http': '127.0.0.1:xxx'},'timeout': 300}



#Conectar a twitter y enviar un tweet,

#Si no se logra la conexion se devuelve un mensaje.

try:

    api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET,client_args = client_args)

    print(u"Autenticación con exito")

except twython.exceptions.TwythonAuthError:

    print(u"Error de autenticación")

print ""

trending = api.get_available_trends()

print u"Identificación de woeid de Venezuela"

print "-------------------------------------"

c = 0   

pos = 0

woeid = 0
#Se despliega los woeid de las ciudades de Venezuela y de Venezuela en si
for i in trending:
    if i[u'countryCode'] == u'VE':
        print i[u'name'],i[u'woeid']
        #Se toma el woeid de Venezuela
        woeid = i[u'woeid']
        pos = c
    c += 1
print ""
#Se despliega los topics de Venezuela.
print "Lista de Trending Topics en Venezuela"
print "-------------------------------------"
for i in api.get_place_trends(id=woeid):
    for k in i[u'trends']:
        print k[u'name']


A continuación se muestra el resultado de la ejecución del script:
Identificación de woeid de Venezuela
-------------------------------------
Caracas 395269
Maracaibo 395270
Maracay 395271
Valencia 395272
Barcelona 395273
Ciudad Guayana 395275
Turmero 395277
Barquisimeto 468382
Maturín 468384
Venezuela 23424982
Lista de Trending Topics en Venezuela
-------------------------------------
#10CosasQueOdio
#AlfombraRojaE
#EmmysPorWarner
#ChavezElGranArquitecto
#ObamaNervioso
Angela Merkel
Titanic
Kenia
GNB
Sofia Vergara

Como se ve se puede obtener el topics de cada ciudad o País al obtener el woeid.

Probando la librería twython para twitter

Retomando los artículos sobre librerías de python para acceder a twitter, en el último artículo explique como descubrir trending topic con la librería python-twitter., ahora le toca el turno a twython.
La página del proyecto se encuentra en github.

Twython soporta lo siguiente:

  • Busqueda para:
    • Información de usuario.
    • Lista de twitter.
    • Líneas de tiempo (timeline).
    • Mensajes directos (DM).
    • Cualquier cosa que se encuentre en la documentación del API de twitter.
  • Actualización de imagen:
    • Actualización de un estatus de un usuario con una imagen.
    • Cambiar el avatar de un usuario.
    • Cambiar imagen de fondo.
    • Cambiar banner.
  • Soporte de sólo lectura para OAuth2
  • Soporte para el API de stream de twitter.
  • Soporte para Python 3.
Para más información sobre la documentación la pueden visitar en el siguiente enlace.
Para manejar la autenticación de la aplicación y del código pueden revisar el artículo de Efrain Valles, jugando con las APis de twitter y python.

Para instalar twython se usa pip o easy_install como root desde la línea de comandos:
root@grievous:~# pip install twython

Lo primero que se va a hacer es envíar un tweet con una imagen y luego sólo texto, la implementación usa un proxy para enviar los tweets, luego se muestra en pantalla el timeline del usuario y por último el resultado de la busqueda de la palabra python.

El código de la aplicación se muestra a continuación:

#!/usr/bin/env python

# -*- coding: utf-8 -*-



#Se define el token de la aplicacion

CONSUMER_KEY = 'xxxxx'

CONSUMER_SECRET = 'xxxxx'

#Se define el acceso al usuario

ACCESS_KEY = 'xxxxx'

ACCESS_SECRET = 'xxxxx'



#Se importa twython y de time a  sleep

from twython import Twython

from time import sleep



#Se define los argumentos del cliente, la ip y puerto del proxy, el tiempo de intento de la conexion y el nombre de la

#aplicacion cliente

client_args = {'headers': {'User-Agent': 'cmdtweetpy'},'proxies': {'http': '127.0.0.1:xxxx'},'timeout': 300}



#Conectar a twitter y enviar un tweet,

#Si no se logra la conexion se devuelve un mensaje.

try:

    api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET,client_args = client_args)

    photo = open('linux.jpg','rb')

    api.update_status_with_media(media=photo, status='May the source be with you=> ')

    api.update_status(status="Enviando tweets con twython por medio de un proxy")

    print("Tweet enviado con exito")

except twython.exceptions.TwythonAuthError:

    print(u"Error de autenticación, no se pudo envíar el tweet")



#Listar el timeline del usuario

listado = api.get_home_timeline()
print("Timeline del usuario _seraph1")
print("-----------------------------")
for i in listado:
    print i[u'text']
    sleep(1)
print("-----------------------------")
#Se realiza una busqueda de la palabra python con tipo de resultado popular
resultados = api.search(q='python',result_type='popular')
#resultados = api.search(q='python')
#
datos= resultados.keys()
print("Elementos del diccionario: %s" %datos)
print("Resultado de la busqueda: python")
print("--------------------------------")
for i in range(len(resultados[datos[1]])):
        print resultados[datos[1]][i][u'text']
        print "***********************************"
print("--------------------------------")



A continuación se muestra la salida de la aplicación:

Tweet enviado con exito
Timeline del usuario _seraph1
-----------------------------
Bo Xilai Gets Life Sentence http://t.co/oWBTgTBJKv
(Starting with "A") Armstrong, Aslan, Atran: Who will be the first to say this has nothing to do with religion?
http://t.co/8IacERuHN7
All About Team Building &amp; #Leadership Exercises at Work! http://t.co/SEI89zGp8P #managers
#linux #netdev  Re: [Xen-devel] [PATCH net-next] xen-netfront: convert to GRO API and advertise this feature http://t.co/3nWDlbv7pT
#linux #netdev  [PATCH net 3/5] bnx2x: 57840 non-external loopback test fail on 1G http://t.co/tI6azgkcBZ
"Read the collective bargaining agreement, we can do that" RT @BradStone: ESPN reports #Browns now fielding offers for their fans' souls.
“@SoftwareHollis: @CloudExpo - can't wait for November.  Looking forward to presenting! http://t.co/b3dc2a08KU #Cloud #SocialMedia #SaaS”
.@jeancase - this is really about the democratization of ideas - the smartest people in the room probably don't work for you #2030NOW
Achieving Accountability With Talk of Infidelity - via @toddbnielsen http://t.co/hZktGZZ3EK #leadership
RT @les_leopold: Solution to the Student Debt Crisis: No More Debt
http://t.co/hsvdZj9uJQ
Recuerda cerrar sesión cuando entres a #Clavenet desde cualquier equipo. #TipdeSeguridad
-----------------------------
Elementos del diccionario: [u'search_metadata', u'statuses']
Resultado de la busqueda: python
--------------------------------
"Well, everday's a workout when you gotta carry around a 20 pound python in your jeans." -Will Forte 'MacGruber' 2010
***********************************
Aprende Python desde cero [Guía completa] http://t.co/ZZE2NXEOVG #YoComparto
***********************************
「d3はシングルスレッドなのでHadoopからデータ直接流し込んで大規模処理するわけにはいかないから、サーバ側でPythonとか走らせ、集計やサンプリング済みデータをJSに渡して可視化してる」的なこと言ったら「フリーソフトでは大規模なデータマイニングは難しい」っていう纏め方された
***********************************
Please RT! The most significant fact about today's Raspberry Jam for kids at PyconUK is the gender split: 50/50. #python #progress
***********************************
先方、データマイニングについての記事のインタビューなのにPythonとか全く知らない(名前すらしらない)ようで、RやPython、果てはd3.jsとか全部ひっくるめて「フリーソフトを利用して分析している」っていうすごいざっくりしたまとめられ方してて、前後の話に矛盾が出てる
***********************************
Obviously Monty Python was never shown on JA TV as the Reggae Charts out there have Silly Walks Record label listed as err..'Silky Walks".
***********************************
Air Jordan IV “Black Python” Customs. WIN or BIN? #CurtienFashion http://t.co/SHu9MKOOB5
***********************************
Defenders of Obamacare dismissing "glitches" increasingly sound like the Black Knight from Monty Python http://t.co/SGV8ys8hMF
***********************************
Without this Beatle, Monty Python's "Life of Brian" would never have been made http://t.co/85ys7bLo6S #5facts
***********************************
Indonesia adalah Tempat ditemukannya ular terpanjang di dunia yaitu, Python Reticulates sepanjang 10 meter di Sulawesi. #7d
***********************************
Recruiter: "I came across your resume in a Google search. You seem to have an awesome expertise on python" To Guido. https://t.co/lAbeQVgo1I
***********************************
Mozilla Webdev is looking for a Web Engineer - Python, Django, jQuery, OSS - http://t.co/9hg8GFOeSl
***********************************
Writing a High Performance Python book: I'm terribly excited to announce that I'm co-authoring an O'Reilly... http://t.co/ZctbSoZGqa
***********************************
If you can write PHP, you can write C/C++/Java/Python/Ruby/whatever.  These language aren't all that different.
***********************************
'El sentido de la vida' cumple 30 años: 12 cosas que probablemente no sabías de la peli de los Monty Python http://t.co/hBVKUCIMFJ
***********************************
--------------------------------



A continuación se muestra dos imagenes de los tweets enviados: