Documentos de Académico
Documentos de Profesional
Documentos de Cultura
El Minilibro de Trucos de Python - Todos Los Ejemplos de Código para Mejorar Tus Scripts PDF
El Minilibro de Trucos de Python - Todos Los Ejemplos de Código para Mejorar Tus Scripts PDF
Ya
ko
19
76
id
en
ti.
io
Crear gráficos con python y matplotlib
Instalación de librerías
Gráficos básicos de lineas
Gráficos de area
Gráficos en 3D
Gráficos tipo «Pie» o «Pastel»
Es un lenguaje interpretado pero, ¿Se puede compilar Python?
Usar Cython
Usar pyinstaller
Docker desde python
Instalando el paquete de api de docker
Por donde empezamos
Declaramos el docker usado
Crear contenedor y arrancarlos
Listar contenedores
Arrancar y parar contenedores
Listar imagenes
Trucos para scripts
Leer y escribir ficheros GZip
Crear fichero tar.gz
Ocultar el password al pedirlo por consola
Ejecutar comandos con pexpect
Codificar y decodificar un binario en base64 por chunks
Comprobar web
Sacar voz a partir de un texto
Reimportar modulo
Eliminar carácteres no alfanumericos
Eliminar elementos vacíos de una lista
Como usar en windows volume shadow copy con python
Como usar una libreria hecha en C con python
Levantar un servidor web
Otra forma de ejecutar print
Calcular direcciones IP
Trucos para formatear texto
Trucos de fechas y horas
Fecha y hora unix (timestamp) a fecha
Tiempo completo
Fecha y hora completo
Fecha y hora UTC
Saber el timestamp actual
Saber semana del año
Saber el día, el mes y el año
saber el tiempo en dias transcurrido entre dos fechas
Tail en python
Usar un fichero de configuración
Como manejar JSON
Web scraping básico
Crear gráficos con python y matplotlib
Matplotlib es una librería que nos ofrece muchas posibilidades de creación de gráficos desde python
a partir de arrays de datos. La web oficial de esta librería es: https://matplotlib.org/
Instalación de librerías
Para instalar matplotlib solo tenemos que ejecutar pip install matplotlib como se puede ver en esta
pantalla:
Para poder trabajar con los ejemplos que mostraremos a continuación también debemos instalar scipy
con el comando pip install scipy:
Y también debemos instalar python-tk en el caso de debian/ubuntu y similares se hace con apt install
python-tk:
Gráficos básicos de lineas
En este primer ejemplo vamos a hacer gráficos simples definiendo únicamente el eje «Y» con los
datos que queremos dibujar:
ger@ger:~$ python
>>> plot([1,2,3,2,1,3,2,1,2,3,4,5,4,30,10,1])
[]
Text(0.5,0,'mi grafico')
>>> title('titulo de mi grafico')
Text(0.5,1,'titulo de mi grafico')
>>> draw()
>>> savefig("mi-grafico1",dpi=300)
>>> close()
>>>
Con este código anterior se crea un gráfico en base a los datos definidos en la segunda linea (la que
empieza por plot). Para enseñaros el funcionamiento hemos creado un fichero python en
/tmp/grafico.py con este código y lo hemos ejecutado:
Cambiando parte del código se puede hacer que se muestre una ventana GUI con el gráfico que
hemos generado, esto se hace con la sentencia draw() :
io
ti.
en
id
76
Si añadimos antes de draw() la sentencia grid(True) se mostrará la cuadricula de fondo. Para mostrar
la leyenda se debe añadir legend( (‘Etiqueta1’,), loc = ‘upper left’) donde «Etiqueta 1» es el texto a
mostrar:
19
ko
Ya
by
Si queremos complicar un poco mas el gráfico de lineas simples podemos añadir linea de tiempo y
una segunda linea de datos:
En el caso anterior hemos podido definir el color y el texto de la etiqueta de cada linea. Esto lo
hacemos modificando los parámetros «color» y «label». En este caso como hemos utilizado
legend(loc = ‘upper left’) la leyenda adquiere los valores del parámetro label de la sentencia plot().
En este caso se podía haber utilizado también legend( (‘Vlores 1′,’Valores2’), loc = ‘upper left’) pero
la sentencia utilizada es más cómoda ya que nos evitamos pasar parámetros y estos se adquieren de
forma automática.
Gráficos de area
Es tan simple como añadir la sentencia fill_between(time,valores2,color=»red») (donde también
definimos el color del relleno del área ) por cada linea de un gráfico simple:
Y este es el resultado del gráfico de área:
Gráficos en 3D
Con el siguiente código generamos un gráfico en 3D con los datos facilitados en X e Y, el eje X se
facilita en el primer parámetro de np.arange:
fig = figure()
ax = Axes3D(fig)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1)
show()
El resultado es:
y = [1,2,3,2,1,3,2,1,2,3,4,5,4,30,10,1]
pie(y)
xlabel('mi grafico')
title('titulo de mi grafico')
draw()
#savefig("mi-grafico1",dpi=300)
#close()
grid(True)
show()
Si sustituimos pie(y) por plot(y) generamos un gráfico de lineas. Las lineas comentadas si se
descomentan, guardarán el gráfico directamente aparte de mostrarlo con show() . El resultado de este
código es:
Puedes encontrar mas información sobre como hacer otro tipo de gráficos como por ejemplo los de
barras en la documentación de la web oficial https://matplotlib.org/
Usar Cython
1- La primera forma de crear un ejecutable a partir de nuestro script python es con la utilidad Cython,
la cual convierte el código a lenguaje C para posteriormente compilarlo con un compilador C como
puede ser GCC:
Script «test.py»
def testPython():
print(toprint)
if __name__=="__main__":
testPython()
Para hacer lo siguiente es necesario instalar cython, se puede instalar con easy_install o con pip:
root@host:~#
root@host:~#
Como se puede ver se crea el ejecutable y se comporta exactamente igual que el script:
root@host:~# ./test
Python mola
Python mola
Como se puede ver, se ha generado un fichero ejecutable elf de linux (exe en windows), depende de
las librerías de python (y como en cualquier binario hay que tener cuidado de lo que se deja en los
strings ya que con el comando strings se puede obtener texto en claro):
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-
64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e54070acae5bb3d0c751b495919680933e43955f, not stripped
linux-vdso.so.1 (0x00007ffea39cc000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdf70fc9000)
testPython
Python mola
testPython
test.testPython
__pyx_k_testPython
__pyx_k_Python_mola
__pyx_kp_s_Python_mola
__pyx_n_s_testPython
__pyx_mdef_4test_1testPython
__pyx_pw_4test_1testPython
__pyx_pf_4test_testPython
Usar pyinstaller
También podemos crear un ejecutable con pyinstaller, aunque de esta forma realmente
empaquetamos el script python y sus librerías dentro de un binario, de esta forma no se requiere ni
python ni sus librerías instaladas en el sistema que se ejecute el binario generado:
root@host:~#
['/tmp', '/tmp']
1231 INFO: Python library not in binary depedencies. Doing additional searching...
root@host:~# dist/test
Python mola
Como se puede ver, también se ha generado un fichero binario ELF (en windows un EXE) ,tiene
menos dependencias de librerias y no aparece nada de lo escrito en los strings cuando ejecutamos el
comando «strings»:
dist/test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-
64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=373ec5dee826653796e927ac3d65c9a8ec7db9da, stripped
linux-vdso.so.1 (0x00007ffc22787000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc7adc4f000)
Py_SetPythonHome
Otra cosa a tener en cuenta es que el tamaño del fichero ejecutable será mayor con esta utilidad ya
que se ha generado un fichero standalone y para eso se han incluido las librerias necesarias en el
código:
Desde la API de docker para python se pueden realizar una gran variedad de operaciones. Se pueden
crear contenedores, manejar los existentes, gestionar imágenes, etc.
Vamos por partes:
En Centos 7:
En Debian:
Collecting docker
Downloading
https://files.pythonhosted.org/packages/e1/58/938fbc7acd98302ca4872f5eab8ab811498e342ab5aec0c1609f22e0aeda/docker-
3.6.0-py2.py3-none-any.whl (131kB)
Ahora que ya tenemos instalado el modulo de python para trabajar con docker podemos empezar:
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
import docker
client = docker.from_env()
import docker
client = docker.from_env()
Listar contenedores
Cuando solicitemos el listado nos devolverá un array con los IDs de los contenedores generados. Al
hacerlo con containers.list() es igual que si hiciesemos docker ps, solo nos muestra los levantados,
para ver todos, es necesario ejecutarlo con el parámetro all=True, es decir
client.containers.list(all=True)
import docker
client = docker.from_env()
lista = []
import docker
client = docker.from_env()
lista = []
lista = client.containers.list(all=True)
io
print("su id es {0} y su nombre {1} ".format(contenedor.id,contenedor.name))
ti.
print(contenedor.status)
en
contenedor.stop()
lista = client.containers.list(all=True)
contenedor.start()
19
lista = client.containers.list(all=True)
ko
print(contenedor.status)
contenedor.status()
En el anterior código hacemos varios bucles para actualizar el estado, el resultado sería:
by
>>> lista = []
... print(contenedor.status)
... contenedor.stop()
...
running
... print(contenedor.status)
... contenedor.start()
...
exited
... print(contenedor.status)
... contenedor.status()
...
running
Para eliminar un contenedor, primero debe estar parado y podemos hacerlo como hacemos con
«.stop()» pero ponemos en su lugar «.remove()«.
Listar imagenes
Para ver las imágenes se parece bastante a como lo hacemos con los contenedores, se llama al
método «.list()» de images:
import docker
client = docker.from_env()
lista = []
lista = client.images.list()
print(image.id)
print(image.tags)
#Nos devolverá un array de objetos image con los datos de las imagenes locales
Por ejemplo:
>>>
>>> lista = []
... print(image.id)
... print(image.tags)
...
sha256:1e1148e4cc2c148c6890a18e3b2d2dde41a6745ceb4e5fe94a923d811bf82ddb
[u'docker.io/centos:7']
sha256:dc496f71dbb587a32a007a0ffb420d1b35c55ec31cda99c0f5336954623f8368
[u'docker.io/alpine:3.5']
sha256:174b26fe09c724368aa2c3cc8f2b979b915a33f7b50c94cd215380d56147cd60
[u'docker.io/alpine:3.4']
sha256:c78b5648029c3636a0c6d056eeba8c3a2e970976342ee156155db19ca81c6f5e
[u'docker.io/alpine:3.3']
sha256:4558d96d24b5acf7d9bdaa060124ae787fa38093eb00538b88378833de5a223d
[u'docker.io/alpine:3.2']
sha256:f36c4228b2c6863208de3a13f2e467476d00ab492416c0aadcfc0e247db1ee03
[u'docker.io/alpine:3.1']
sha256:de4761d9f0371cbace6a4c2ebef14b14ce30185a7fcedb5e04b170130e7e642d
[u'docker.io/alpine:edge']
sha256:196d12cf6ab19273823e700516e98eb1910b03b17840f9d5509f03858484d321
[u'docker.io/alpine:3.8', u'docker.io/alpine:latest']
sha256:34ea7509dcad10aa92310f2b41e3afbabed0811ee3a902d6d49cb90f075fe444
[u'docker.io/alpine:3.7']
sha256:94627dfbdf19f1344aae6ef72db6ff30c5148b60e1091de098807ec4b42febbc
[u'docker.io/alpine:3.6']
sha256:b1666055931f332541bda7c425e624764de96c85177a61a0b49238a42b80b7f9
[u'docker.io/bfirsh/reticulate-splines:latest']
sha256:93f518ec2c41722d6c21e55f96cef4dc4c9ba521cab51a757b1d7272b393902f
[u'docker.io/alpine:2.7']
sha256:e738dfbe7a10356ea998e8acc7493c0bfae5ed919ad7eb99550ab60d7f47e214
[u'docker.io/alpine:2.6']
Y esto es solo una pequeña parte de lo que se puede llegar a hacer, puede consultarse toda la
información sobre la librería en https://docker-py.readthedocs.io/en/stable/client.html ya que es la
web oficial.
f = gzip.open(indexpath, 'rb')
import gzip
contenido = "Texto"
f = gzip.open(indexpath, 'rb')
data = f.read()
f.close()
Para leerlo es exactamente igual de fácil, al igual que en las escritura es la misma forma de de
trabajar que cuando creamos ficheros con python:
import gzip
f = gzip.open(indexpath, 'rb')
data = f.read()
f.close()
import os
import getpass
print(usuario, password)
Se mostraría lo siguiente:
Ejecutar comandos con pexpect
Este módulo es la versión para python de expect. Básicamente es capaz de Ejecutar un comando y
según la salida del comando introducir un texto en la consola. Esto es válido al utilizar comandos que
requieren de un tiempo de espera para introducir parámetros como por ejemplo passwd o ssh. De esta
forma se puede completar la ejecución del comando de forma correcta introduciendo los parámetros
necesarios, en el ejemplo mostraremos como ejecutar SSH introduciendo la contraseña dell host de
destino con pexpect:
import pexpect
import time
child = pexpect.spawn(cmd)
child.expect('password:', timeout=10)
child.sendline(PASSWORD)
time.sleep(5)
time.sleep(5)
child.sendline("\n")
fout = file('/tmp/texto-192.168.1.165','w')
child.logfile = fout
time.sleep(5)
child.expect(pexpect.EOF)
import codecs
import binascii
byte = "1"
in_file = open("/tmp/ping","rb")
out_file = open("/tmp/ping.b64","wb")
byte = in_file.read(128)
encode = codecs.encode(binascii.b2a_base64(byte),"base64")
out_file.write("__INICIO__" + encode[0:(len(encode)-2)] )
in_file.close()
out_file.close()
Como se puede ver en el código anterior, se abre el fichero de origen y el de destino. Lee un bloque
del fichero de origen, codifica cada el bloque y lo guarda en el fichero de destino.
En el siguiente bloque de código, hace justo lo contrario. Es decir abre el fichero codificado, lo
decodifica y escribe en el fichero de destino. Todo esto bloque a bloque.
import codecs
import binascii
byte = "1"
in_file = open("/tmp/ping.b64","rb")
out_file = open("/tmp/ping.devuelta","wb")
count = 0
byte = in_file.read(244)
print byte
if len(byte) != 244:
byte = byte[0:len(byte)-1]
if byte[0:10] == "__INICIO__":
byte = byte.replace("__INICIO__","")
print "Entra1"
out_file.write(binascii.a2b_base64(codecs.decode(byte+"=","base64")))
else:
bytes = byte.split("__INICIO__")
for b in bytes:
print b
out_file.write(binascii.a2b_base64(codecs.decode(b+"==","base64")))
in_file.close()
out_file.close()
Comprobar web
Este bloque de código ayuda a ver si una web tiene problemas. En este caso se comprueba solo
durante 10 minutos pero retocando el código se puede comprobar de forma infinita:
import requests,time,sys
def getWeb(url):
r = requests.get(url)
return int(r.status_code)
def main():
counter = 0
status = getWeb(url)
status = getWeb(url)
time.sleep(60)
counter += 1
if status==500:
elif status==200:
else:
print ("The website is not returning error code 500 but is not OK")
if __name__=="__main__":
main()
#!/usr/bin/env python
import win32com.client
speaker = win32com.client.Dispatch("SAPI.SpVoice")
while True:
s = raw_input()
speaker.Speak(s)
Reimportar modulo
En ocasiones se tiene que recargar un módulo en tiempo de ejecución, esto se consigue con:
reload(modulo)
Con esta linea podemos hacer que si hemos creado un servicio, este recargue modulos en tiempo de
ejecución, para recargar posibles cambios en módulos o plugins sin reiniciar el servicio.
import re
s = re.sub('[^0-9a-zA-Z]+', '*', s)
io
str_list=texto.split(" ")
ti.
#este es el mas rapido
en
#O podemos utilizar este:
#O este otro:
19
import win32com.client
import os
def vssList():
wcd=win32com.client.Dispatch("WbemScripting.SWbemLocator")
wmi=wcd.ConnectServer(".","root\cimv2")
def vssCreate():
wmi=win32com.client.GetObject("winmgmts:\\\\.\\root\cimv2:Win32_ShadowCopy")
createmethod = wmi.Methods_("Create")
createparams = createmethod.InParameters
createparams.Properties_[1].value="c:\\"
results = wmi.ExecMethod_("Create",createparams)
return results.Properties_[1].value
if __name__ == "__main__":
print(vssCreate())
list = vssList()
copyfile("{0}\\Windows\\System32\\drivers\\etc\hosts".format(list[0]), "c:\\nuevo")
Con este código se puede implementar un sistema de copias de seguridad a partir de los VSS de
windows utilizando el metodo « vssCreate() ».
También puede servir como forma de hacerse persistente en un sistema tras explotarlo, ya que
muchos antivirus no incluyen por defecto en sus escaneos del sistema los VSS.
Esto puede usarse de la siguiente forma tras explotar el sistema:
1-Se compromete el sistema y se copia el binario a la ubicación definitiva
2-Se lanza la creación de VSS (volume shadow copy de Windows)
De esta forma ya tenemos una copia «segura» del binario malicioso en el sistema.
Esto también es usado por los ransomware, lo que hacen es lanzar una copia con VSS y cifrar los
ficheros a partir de esta borrando los originales del disco. De modo que en ocasiones es posible
recuperar los ficheros a partir de estos VSS si hemos sido infectados por unos de estos malwares y
estos malwares no borran los VSS después de cifrar los ficheros.
Es importante que si un sistema ha sido infectado y se va a «limpiar» y a seguir usando (yo no so
partidario de esto, soy partidario de reinstalar) le purguen los VSS para evitar que resurja el
problema.
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#else
# define DLL_EXPORT
#endif
int res = 0;
res = a + b;
printf("ResC: %d\n",res) ;
return res;
Para compilarlo usamos el siguiente comando (sustituir librería por el nombre que se quiera):
user@host:~$ gcc -Wall -Wextra -O -ansi -pedantic -fPIC -shared LIBRERIA.c -o
/tmp/LIBRERIA.so
Para usarla en este lenguaje solamente hay que llamarla importando la clase cdll del modulo ctypes,
depués de usar el método LoadLibrary de la clase cdll, podremos llamar a los métodos de la librería
importada:
user@host:~$ python
ResC: 1456018974
1456018974
Donde 2048 es el puerto. Es tan alto porque algunos sistemas operativos no dejan que un usuario deje
aplicaciones a la escucha en puertos inferiores al 1000.
Un ejemplo de uso es el siguiente:
Después de ejecutar esas lineas de comandos podremos acceder vía web a http://localhost:2048
como se puede ver en la siguiente imagen:
Como hacer que nuestro código sea multitarea
En ocasiones necesitamos que nuestro código ejecute varias tareas simultaneas. Se puede hacer de
multiples formas pero una de ellas es la siguiente:
def test(thname):
print ((thname,i))
time.sleep(1)
while True:
print("test123")
time.sleep(5)
Otra forma de ejecutar el código multithread es:
def test(thname):
print ((thname,i))
time.sleep(1)
def test1(arg):
while True:
print "test1"
time.sleep(1)
t2=threading.Thread( target=test1,args=(None,))
t1.start()
t2.start()
while True:
print("test123")
time.sleep(5)
sys.stdout.write(TEXTO)
sys.stdout.flush()
sys.stderr.write(TEXTO)
sys.stderr.flush()
Calcular direcciones IP
Si estamos trabajando con direcciones IP y queremos saber si una IP pertenece a un rango podemos
ejecutar lo siguiente:
if '10.0.0.10' in Network('10.0.0.0/8'):
print "OK"
for x in Network('10.2.32.40/27'):
print str(x)
En la primera parte miramos si la IP 10.0.0.10 pertenece al rango 10.0.0.0/8. Si es así imprime OK.
En la segunda imprime por pantalla todas las direcciones del rango 10.2.32.40/27
>>> print a
fruta=fruta, verdura=verdura
>>> print a
print temp
Tiempo completo
Para saber el tiempo actual podemos usar el siguiente código:
import time
time.ctime()
import datetime
print(datetime.datetime.now())
import datetime
datetime.datetime.utcnow()
time.time()
get date
import datetime
today = str(datetime.date.today()).split("-")
today = datetime.date.today()
datetime.date(today.year,today.month, today.day).isocalendar()
today = datetime.date.today()
day = today.day
month = today.month
year = today.year
print (day,month,year)
saber el tiempo en dias transcurrido entre dos fechas
import datetime
dtime.days
Tail en python
Leer ultimas lineas de un fichero cada vez que se actualice el fichero
io
for line in Pygtail("some.log"):
ti.
sys.stdout.write(line)
en
Usar un fichero de configuración
Puedes usar el módulo ConfigParser, pero antes tendrías que cambiar un poco tu archivo de
configuración ya que ConfigParser trabaja con secciones.
Archivo de ejemplo example.conf:
id
76
[HORAS]
19
hora_ini = 14:00
hora_fin = 22:00
ko
import ConfigParser
Ya
config = ConfigParser.ConfigParser()
by
config.read('example.conf')
print hora_ini
print hora_fin
import json
jsonlist = json.loads(data)
import json
json_data=open(file_directory).read()
data = json.loads(json_data)
pprint(data)
url = 'http://URL
resp = requests.get(url=url)
print(resp.text)
url = 'http://maps.googleapis.com/maps/api/directions/json'
params = dict(
origin='Chicago,IL',
destination='Los+Angeles,CA',
waypoints='Joplin,MO|Oklahoma+City,OK',
sensor='false'
data = json.loads(resp.text)
Crear enlace simbolico
Para crear un enlace simbolico desde python utilizamos:
import os
if callable(os_symlink):
pass
else:
import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.restype = ctypes.c_ubyte
raise ctypes.WinError()
os.symlink = symlink_ms
>>> [{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'_id': 1, u'name': u'name1', u'value': 11},{u'date':
datetime.datetime(2013, 11, 10, 10, 45), u'_id': 2, u'name': u'name2', u'value': 22}]
>>> from bson.json_util import dumps
>>> dumps(l)
Mandar email
Enviar un correo desde un servidor SMTP local:
import smtplib #Envio de correo
try:
me = "email@dominio.com"
msg['Subject'] = subject
msg['From'] = me
msg['To'] = to
s = smtplib.SMTP('localhost')
s.quit()
except Exception as e:
Argparse basico
Argparse es una libreria para gestionar los puntos de entrada y parametros:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("agent")
parser.add_argument("message")
args = parser.parse_args()
import requests
response = requests.get(my_url)
soup = BeautifulSoup(response.text)
soup.find(id="intro-text")
import dryscrape
import sys
session = dryscrape.Session()
session.visit( "https://encuentratrabajoya.com/oferta.html?id=5b7d229a5ee2653dc7271f74")
if 'linux' in sys.platform:
dryscrape.start_xvfb()
session.render('/tmp/google.png')
#fin de screenshot
response = session.body()
soup = BeautifulSoup(response,features="lxml")
print (soup.get_text())
#print soup.find(id="table_results_offer0")