Os presento mis primeros 4 scripts en Python. Me parece un lenguaje muy interesante con unas librerías muy potentes, creo que en parte es debido a que es fácil portar librerías de C a Python y en este lenguaje se ha programado de todo. Desde luego que no son para un manual de programación en Python, os los presento solo para que veáis la potencia del lenguaje.
Lo que hace éste script está comentado en el mismo código:
#! /usr/bin/env python # -*- coding: utf-8 -*- # El script espera dos argumentos: # 1 - Una fecha en formato '%d-%m-%Y %H:%M', por ejemplo '21-01-2011 11:40' # Mostrará sólo los ficheros que se hayan modificado después de esta fecha. # 2 - Un path en formato *nix, por ejemplo '/home/vic/python'. No acepta '~' para referirse a 'home'. # Buscará recursivamente, subdirectorios incluidos, sin profundizar en enlaces simbólicos, todos los ficheros a partir de ese path. # # os.path.getmtime -> Da el número de segundos desde epoch (medianoche UTC desde el 1 de enero de 1970). # time.strptime devuelve una estructura time (struct_time). # time.mktime(struct_time) devuelve el nº de segundos desde epoch. time.localtime(segundos_desde_epoch) hace la función inversa. # El nº de segundos desde epoch se expresa en coma flotante. # #Para la fecha de creación de un fichero o dir: stat -c %w nombre #Para saber la fecha de la última molificación: stat -c %y nombre #Cuando se crea un fichero dentro de un directorio se modifica solo la fecha de modificacion del dir y no la de creación. #Cuando se modifica un fichero dentro de un directorio no se altera la fecha de modificación ni de creación del dir. import os, time, sys from sys import argv stModDesde = time.strptime(argv[1], '%d-%m-%Y %H:%M') fModDesde = time.mktime(stModDesde) top = argv[2] for root, dirs, files in os.walk(top, topdown=False): for name in files: elemPath = os.path.join(root, name) fModificado = os.path.getmtime(elemPath) if (fModificado > fModDesde): print 'Fichero ' + elemPath + ' Modificado:' + time.ctime(fModificado) # for name in dirs: # elemPath = os.path.join(root, name) # Si queremos trabajar también con los directorios descomentar este for / in
¡Daros cuenta de que tan solo son 11 líneas! Aquí una función en Object Pascal que hice hará unos 7 años que aun teniendo que hacer algo más sencillo (buscar un fichero en el directorio actual y subdirectorios) era más compleja: recursiva y con más líneas de código.
unit Llibreria; interface uses SysUtils, Classes, Forms; procedure busca(path: string; carpet: string; coincidencias: TStrings); implementation procedure busca(path: string; carpet: string; coincidencias: TStrings); var sr: TSearchRec; res: byte; lg: integer; begin lg:=strLen(PChar(path)); //lg:=length(path); path:=path+carpet; res:=FindFirst(path, faAnyFile, sr); if (res=0) then coincidencias.Add(copy(path,1,lg) + sr.Name); FindClose(sr); path:=copy(path,1,lg) + '*.*'; res:=FindFirst(path, faAnyFile, sr); while (res=0) do begin if (((sr.Attr and faDirectory)<>0) and (sr.Name[1]<>'.')) then begin path:=copy(path,1,lg); path:=path + sr.Name + '\'; application.ProcessMessages; busca(path,carpet,coincidencias); end; res:=FindNext(sr); end; FindClose(sr); path:=copy(path,1,lg); end; end.
Aquí un script para criptografía simétrica, usa el algoritmo Blowfish. El modo de cifrado es CTR, pero no le hagáis mucho caso a la función del contador. Una vez más creo que los comentarios ya explican bastante. (Python es el primer lenguaje en que me veo obligado a usar más líneas de comentarios que de código)
#! /usr/bin/env python # -*- coding: latin-1 -*- # El script espera 3 argumentos: # 1º: Encriptar / Desencriptar: e / d # 2º y 3º: paths a ficheros. # Con 'e' el 2º parámetro es el fichero a encriptar y el 3º el del encriptado (el resultado). # Con 'd' el 2º parámetro es el fichero encriptado y el 3º el desencriptado (el resultado). # ATENCIÓN: ¡en ambos casos el fichero resultante se sobreescribirá si ya existe! # # A continuación pedirá la clave. from Crypto.Cipher import Blowfish from os import path from sys import argv, exit import getpass if not path.isfile(argv[2]): exit(argv[2] + " no existe o no es un fichero.") # Añadir 'b' (binary) lo hace portable a Windows que sí distingue entre ficheros de texto y binarios, # permitiendo encriptar tanto ficheros de texto como binarios. f1 = open(argv[2], 'rb') passw = getpass.getpass("Contraseña:") class contador(object): def __init__(self, inicio): self.cont = inicio def next(self): self.cont = self.cont + 1 sCont = str(self.cont) while len(sCont) < 8: sCont = sCont + '0' return sCont c = contador(0) oBlow = Blowfish.new(passw, Blowfish.MODE_CTR, counter=c.next) # El primer param. es la clave. El segundo es el modo. # Parece que el modo ECB es el más inseguro y CTR el más seguro. Ver http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 # El tercer parámetro no es opcional en el caso de CTR: requiere el contador. Debe ser una cadena de 8 carácteres. # Se instancia el objeto antes del if pues el contador debe ser el mismo para la encriptación y la desencriptación. # Usar algo como "sAleatoria = os.urandom(8)" tiene el inconveniente de tener que almacenar en el fichero ese contador para luego poder desencriptar. if argv[1] == 'e': texto = f1.read() # Texto a encriptar. # La cadena a encriptar debe tener una longitud que sea múltiple de 8. Independientemente de la extensión de la clave. while (len(texto) % 8 != 0): texto = texto + chr(3) # El ASCII 3 es End of TeXt (ETX). textoEncriptado = oBlow.encrypt(texto) #print "Texto encriptado: " + textoEncriptado #textoDesencriptado = oBlow.decrypt(textoEncriptado) #print "Texto desencriptado: " + textoDesencriptado f2 = open(argv[3], 'wb') # Sobreescribe el fichero si ya existe. f2.write(textoEncriptado) f1.close() f2.close() elif argv[1] == 'd': textoEncriptado = f1.read() texto = oBlow.decrypt(textoEncriptado) f2 = open(argv[3], 'wb') f2.write(texto) f1.close() f2.close() else: print "Opción desconocida. 'e' para encriptar y 'd' para desencriptar"
¿Y Python para la web? He aquí un pequeño script que lee todas las referencias de productos de un fichero csv para después buscar en la web de la empresa las imágenes que les corresponden y guardarlas en el disco duro.
Creo que con las librerías «mechanize» y «BeautifulSoup» podemos construir fantásticas aplicaciones de testeo web, de una manera más rápida, eficiente y consumiendo muchos menos recursos que con herramientas como Selenium. Aquí el código:
#! /usr/bin/env python # coding=utf-8 import mechanize import cookielib from BeautifulSoup import BeautifulSoup import urllib br = mechanize.Browser() cj = cookielib.LWPCookieJar() br.set_cookiejar(cj) #Inicio configuración browser br.set_handle_equiv(True) br.set_handle_gzip(False) br.set_handle_redirect(True) br.set_handle_referer(True) br.set_handle_robots(False) #Para debug: #br.set_debug_http(True) #br.set_debug_redirects(True) #br.set_debug_responses(True) # User-Agent (no es Linux! pero lo engañamos O:-) br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] br.set_proxies({'http' : '192.168.4.4:3128'}) # Fin configuración browser # Abre fichero de referencias: f = open('/cygdrive/c/users/vic/documents/Empresa/Empresa.csv', 'r') fContent = f.readlines() for ref in fContent: ref = ref.strip() print "'" + ref + "'" #Busca por cada referencia su imagen: response1 = br.open("http://www.empresa.com/en/search/node/" + urllib.quote(ref)) #print br.title() Título de la página #print response1.info() # Cabeceras #print response1.read() # HTML # Si no obtenemos HTML da un error: if not br.viewing_html(): continue sHtml = response1.read() if sHtml.find('http://www.empresa.com/en/products/') == -1: continue #Sigue el link del resultado de la búsqueda: response1 = br.follow_link(url_regex = "http://www.empresa.com/en/products/") if not response1: continue; sHtml = response1.read() #Pone el HTML en la sopa para procesarlo: soup = BeautifulSoup(sHtml) #Busca la imagen y obtiene su valor src bsTagImg = soup.find(id='productimage') src = bsTagImg['src'] #Descarga la imagen en /tmp fTemp = br.retrieve(src)[0] #La copiamos al directorio que queramos: fh = open(fTemp, 'rb') fContentImg = fh.read() f2 = open('/home/vic/python/ref_' + ref + '.jpg', 'wb') f2.write(fContentImg) fh.close() f2.close() f.close()
Realmente un lenguaje potente, ¿verdad?