2016-12-31

Cambiar la IP de TOR para python

Resulta muy útil en actividades de scraping poder cambiar la ip de tus bots de vez en cuando 1. Instalar tor
apt-get update apt-get install tor /etc/init.d/tor restart
Ahora debes generar una contraseña para tor
tor --hash-password micontrasenya
Te saldrá un hash de la contraseña. Debes copiar el hash y luego pegarlo en el archivo /etc/tor/torrc Debes descomentar estas dos líneas
ControlPort 9051 HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
Una vez hecho esto debes reiniciar tor:
/etc/init.d/tor restart
Ahora instalaremnos Privoxy:
apt-get install privoxy
Ahora hay que añadir esta línea al final del archivo de configuración de Privoxy /etc/privoxy/config:
forward-socks5 / localhost:9050 .
No hay que olvidarse del punto. .Es importante Reiniciamos Privoxy:
/etc/init.d/privoxy restart
Y aquí está el script para ver si funciona:

import time
import socket
import socks
import urllib2

from stem import Signal
from stem.control import Controller


controller = Controller.from_port(port=9051)
controller.authenticate(password='micontrasenya')
def connectTor():
    socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 , "127.0.0.1", 9050, True)
    socket.socket = socks.socksocket

def renew_tor():
    controller.signal(Signal.NEWNYM)
    time.sleep(controller.get_newnym_wait()) 

def showmyip():
    new_ip= urllib2.urlopen("http://icanhazip.com/").read()
    print(new_ip)


for i in range(3):
    renew_tor()
    connectTor()
    showmyip()
En los test realizados TOR tardaba entre 10 y 15 segundos en cambiar la IP.

2016-09-30

Spintax, un formato para reescribir artículos

¿Qué es Spintax?

El término spintax es una contracción de spinning + syntax.

Spintax es el formato o sintaxis que se utiliza por varios creadores de software vinculados a la creación de contenidos automatizados y sitios web que crean o utilizan artículos para generar otros distintos distintos a partir de los originales.

Lo que esto significa es que se pueden crear varias versiones de texto teniendo como origen una sola cadena de texto.

Esto se hace mediante la devolución al azar de uno de los elementos de texto de entre las tuberías en una cadena Spintax. Esto es lo que un simple cadena Spintax parece:

{Casa|Hogar|Piso|Chalet}

Por ejemplo, si el código spintax {Casa|Hogar|Piso|Chalet} se genera a través de nuestra Clase PHP Spintax, devolvería al azar uno de estas palabras Casa,Hogar, Piso o Chalet.

Como se puede ver que esto puede ser muy útil para crear varias versiones de texto de una sola cadena de texto.

Si en el texto tenemos muchas cadenas spintax el resultado final es bastante diferente al original. Para ello se necesita tener una fuente grande de sinónimos.

Esta es la mejor clase que he encontrado para spinnear texto: PHP Spintax Class <?PHP /**
* Spintax - A helper class to process Spintax strings.
* @name Spintax
* @author Jason Davis - http://www.codedevelopr.com/
*/
class Spintax
{
public function process($text)
{
return preg_replace_callback(
'/\{(((?>[^\{\}]+)|(?R))*)\}/x',
array($this, 'replace'),
$text
);
}

public function replace($text)
{
$text = $this->process($text[1]);
$parts = explode('|', $text);
return $parts[array_rand($parts)];
}
}
?>

Ejemplo de uso de la clase de spintax en php:

<?PHP
$spintax = new Spintax();
$string = '{Hello|Howdy|Hola} to you, {Mr.|Mrs.|Ms.} {Smith|Williams|Davis}!';
echo $spintax->process($string);
?>

El proceso es sencillo como veís incluso se puede transformar una base de dsatos con todos loos contenidos de una web y crear otra spinneada. La imaginación aquí cuenta mucho. Si además introduces nuevos elementos como videos, gráficos, etc la posibilidad de elementos comunes disminuye. Siempre viene bien realizar una revisión manual para volver a escribir los textos que hayan sido creados de forma muy marciana. Siempre hay textos que salen mal escritos con este tipo de fórmulas de reescritura de textos.

Fuente original https://gist.github.com/irazasyed/11256369

2016-07-15

Instalar Yii2 sobre Windows



Siguiendo las intrucciones oficiales y de tutoriales en varias ocasiones he llegado a puntos con errores poco claros.
 Mi instalación en windows 8 la he realizado en el entorno de Xampp donde según la documentación oficial indica:
 composer global require "fxp/composer-asset-plugin:^1.2.0"
composer create-project --prefer-dist yiisoft/yii2-app-basic basic
He tenido que hacer las siguientes modificaciones:

php c:\xampp\php\composer.phar global require "fxp/composer-asset-plugin:^1.2.0"

php c:\xampp\php\composer.phar create-project --prefer-dist yiisoft/yii2-app-advanced 

Si no, me salía que no ejecutaba composer adecuadamente y me salía por consola la lista de comandos posibles de composer.

Supongo que debo tener composer mal configurado. Lo hice hace tiempo para otro proyecto y no recuerdo como fue.

2016-04-18

Tablas con div, evitar el doble borde en celdas

Cuando tienes que mostrar datos tabulados lo normal es elegir maquetarlas con tablas pero éstas no se comportan bien en dispositivos móviles de pantalla pequeña. hay diversas soluciones pero ninguna me convence cuando se trata de pantallas de 320 píxeles.
Me puse manos a la obra a hacer la tabla con divs y al principio me salía un borde dos veces pero eso con css lo pude solucionar.




<div class="table"> <div class="rowtable"> <div class="cell">Date</div> <div class="cell">Sun, 21 Feb 2016 08:25:29 GMT</div> <div class="cell">data</div> </div> <div class="rowtable"> <div class="cell">Date</div> <div class="cell">Sun, 21 Feb 2016 08:25:29 GMT</div> <div class="cell">data</div> </div> <div class="rowtable"> <div class="cell">Date</div> <div class="cell">Sun, 21 Feb 2016 08:25:29 GMT</div> <div class="cell">data</div> </div> </div> Este sería el css, incluido el responsive que evita el doble borde en algunas celdas de la tabla: /* Tables */ .table { display: table; } .rowtable { display: table-row; } .rowtable:nth-child(odd){ background: #f9f9f9; } .cell:nth-child(odd){ width:25%; } .cell{ border: 1px solid #ddd; border-left: none; border-bottom:none; padding: 8px; vertical-align: top; display: table-cell; } .cell:first-child { border-left: 1px solid #ddd; } .rowtable:last-child .cell{ border-bottom: 1px solid #ddd; } /* End Tables */ /* Media Queries */ @media screen and (max-width: 480px) { .cell{ width:100%; display:inline-block; border-left: 1px solid #ddd; } .cell:nth-child(odd){ width:100%; } } } /* End Media Queries */ Lo he comprobado con dos y tres columnas y no he visto ningún problema.

2016-03-15

Chequear coincidencias en las lineas de dos archivos de texto

Tenía el siguiente problema:

Dos archivos de texto cada uno con entre 7 y 9 millones de registros de datos y no sabía si parte de los registros de A estaban en B. Quería saber los registros que estaban en A y no estaban en B para sumarlos a B.

Comprobarlo en mysql me resultaba imposible por lo que tardaba.

Probé desde la consola de linux:

grep -Fvf archivo1.txt archivo2.txt>/home/usuario/noestan.txt 

y se quedaba sin memoria.

Probé este archivo de linux haciendo que el archivo1 tuviera sólo 1000 líneas y así pronosticar cuanto tardaría con los 7 millones de líneas:


file1=open("C:\\Users\\carlos\\Documents\\de\\archivo1.txt","r")
file2=open("C:\\Users\\carlos\\Documents\\de\\archivo2.txt","r")
file3=open("C:\\Users\\carlos\\Documents\\de\\noestan.txt","w")
lines1=file1.readlines()
lines2=file2.readlines()
encontrado=0
for line1 in lines1:
for line2 in lines2:
if line1==line2:
encontrado2=1
if encontrado2==0:
print(line1)
file3.write(line1)
encontrado2=0
# Cerrar archivos abiertos
file1.close()
file2.close()
file3.close()
El resultado fue que tardaría más de 400 días...

Así que probé con sets:

import time
start = time.time()
file1=open("C:\\Users\\carlos\\Documents\\de\\archivo1.txt","r")
file2=open("C:\\Users\\carlos\\Documents\\de\\archivo2.txt","r")
file3=open("C:\\Users\\carlos\\Documents\\de\\noestan.txt","w")
data2   = set(file2.read().splitlines())
data1   = set(file1.read().splitlines())
for list in data1:
if list not in data2:
file3.write(list)
file3.write('\n')
# Close opend file
file1.close()
file2.close()
file3.close()
end = time.time()
print(end - start)


Y el resultado fue que tardó 12 segundos. Lo peor fue que todos los registros de A estaban en B por lo que me servirá para otra vez pero no para esta. Metí algún resultado falso en A para ver que realmente funcionaba y si.



2016-02-22

Recetas para Mysql

Estas son algunas recetas para el mantenimiento de bases de datos que utilizo. Igual solo lo utilizo dos veces al año.. por eso nunca recuerdo a la perfección el sql necesario. No es algo que haga todos los días.


Exportar en formato csv directamente desde mysql:

SELECT id, name, email INTO OUTFILE '/tmp/result.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
ESCAPED BY ‘\\’
LINES TERMINATED BY '\n'
FROM users WHERE 1

Importar sql comprimido con gunzip a Mysql:

zcat /home/usuario/database-backup/data.sql.gz | mysql -u usuario -p nombre_base_de_datos


Exportar base de datos

mysqldump --opt -u usuario -p nombre_BD> /ruta/documentos/archivo.sql 

Importar csv a una tabla:

LOAD DATA LOCAL INFILE 'abc.csv' INTO TABLE abc
FIELDS TERMINATED BY ';'
ENCLOSED BY '"'
LINES TERMINATED BY '\n';