>Actualizar anuncios automáticamente en Clasipar.

>

Todos sabemos que clasipar es el sitio número 1 para la compra/venta de lo que sea en Paraguay.

Cuando uno trata de vender algo le dedica tiempo a buscar compradores o a actualizar sus anuncios de modo a maximizar sus posibilidades y es justamente acá donde entré a improvisar una vez más.

Definición de la problemática.

  • Tengo varios anuncios ofreciendo productos
  • Tengo que entrar a actualizar diariamente mis anuncios pero son varios y me hacen perder mucho tiempo
  • Muchas veces me olvido y pierdo oportunidades

Es un quilombo, pero tengo la suerte de ser informático (he’i) y las computadoras son mi área de expertise por lo puedo abusar sin remordimiento de ellas (de las computadoras).

El programa

Se trata de un Internet bot que recorre clasipar como su fuera un humano. El programa recibe las instrucciones desde un archivo de texto de donde lee qué anuncio(s) actualizar, se conecta a Internet, navega clasipar como si fuera un browser normal (Internet Explorer o Firefox por ejemplo), explora el panel de control del usuario, busca cuál anuncio actualizar y genera un HTTP request con los datos necesarios.

Está hecho en C# (me encanta), corriendo sobre Linux (aunque también funciona en Windows y MacOS) y funcionando sin problemas desde hace más de un mes.

El programa es relativamente corto en líneas de código pero requiere de un background decente sobre el protocolo HTTP. Me tomé mi tiempo snifeando el tráfico de mi browser conectado a clasipar para averiguar qué datos necesitaba y bajo qué formato se hacía la transmisión. Wireshark es un espectáculo para esto y pronto pude hacer reverse engineering de lo que el sitio esperaba. El siguiente paso fue identificar las cookies y las variables POST que cambiaban (y a veces no) en cada petición. Los datos enviados venían de hidden input boxes en algunos casos por lo que no me pude salvar del pattern matching usando expresiones regulares. La basura puesta por google analytics en el request fue especialmente rompebolas y mi falta de experiencia analizando su tráfico me hizo perder tiempo pues no sabía si estos datos eran necesarios y lo peor, de dónde venían. Finalmente, leyendo el fuente HTML de respuesta pude terminar el análisis y reunir lo necesario para construir el programa.
El código

Los espacios de nombre importados hablan de las porciones del framework que usé

using System;using System.IO;using System.Net;using System.Web;using System.Text;using System.Text.RegularExpressions;
[csharp]
using HtmlAgilityPack;

using ClasiparBot.Utils;
[/csharp]
El entry pointsolo contiene lo siguiente ya que la lógica está contenida dentro de la clase ClasiBot.

[csharp]
public static void Main (string[] args){if (args.Length != 1){ Debug.PrintError(“MainClass.Main(): Invalid command line parameter(s)”); return;}

if (!File.Exists(args[0])){ Debug.PrintError(“MainClass.Main(): Configuration file is missing”); return;}

List <botparameters > botParams = ParseConfigurationFile(args[0]);

foreach(BotParameters botParameter in botParams) Debug.Notify(“MainClass.Main(): Error free? “, new ClasiBot(botParameter).StartBot().ToString().ToUpper());}
[/csharp]

El método StartBot()

[csharp]
ServicePointManager.Expect100Continue = false;

HttpWebRequest request = (HttpWebRequest) WebRequest.Create(_parameter.ManagementLink);request.UserAgent = “Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9rn”;

request.CookieContainer = new CookieContainer();

HttpWebResponse response = (HttpWebResponse) request.GetResponse();StreamReader reader = new StreamReader(response.GetResponseStream());

HtmlDocument htmlDoc = new HtmlDocument();htmlDoc.LoadHtml(reader.ReadToEnd());

string hashID = ParseHashID(_parameter.ManagementLink.ToString()).Trim();string authToken = htmlDoc.DocumentNode.SelectSingleNode(“//input[@name=’authenticity_token’]”).Attributes[“value”].Value;

Debug.Notify(“ClasiBot.StartBot(): HashID is”, hashID);Debug.Notify(“ClasiBot.StartBot(): Authenticity token is”, authToken);

string output = AccessDashboard(request.CookieContainer, hashID, authToken);output = PerformAnnouncementOperation(request.CookieContainer);Debug.Notify(“ClasiBot.StartBot(): Operation result is ‘”, ParseResult(output), “‘”);
[/csharp]

Este método genera el URI dependiendo de la decisión de actualizar, concretar o eliminar el anuncio.
[csharp]
string BuildURIByOperation(Uri mainUri, AnnouncementOperation operation, Uri announcementUri){string operationUri = “http://” + mainUri.Host + “/ad/”;

switch(operation){case AnnouncementOperation.Refresh:operationUri += “refresh_ad”;break;case AnnouncementOperation.Delete:operationUri += “delete_ad”;break;case AnnouncementOperation.MarkAsSold:operationUri += “mark_as_sol”;break;}

operationUri += announcementUri.AbsolutePath.Replace(“.html”, “”);

return operationUri;

}
[/csharp]

Este método determina el resultado de la operación

[csharp]
public string ParseResult(string html){Match match = Regex.Match(html, @”(?.+)”);}

if (match.Success)return match.Groups[“message”].Value;

match = Regex.Match(html, @”(?.+)”);

if (!match.Success)throw new Exception(“Unable to match result in output html”);

return match.Groups[“message”].Value;}

[/csharp]

La salida

Faltan algunas otras cosas pero esto explica cómo funciona el programa para el que sabe cómo leerlo.

No publico todo el fuente porque aunque lo que hago no es ilegal, puede perjudicar su negocio y lo último que yo quiero es dañar a la industria paraguaya.

Este programa es más bien una h erramienta personal y este post pretende ser un artículo científico para gente que esté interesada en el funcionamiento de los bots.

>Un traductor confiable en tu celular

>

Sigo en la búsqueda del servicio perfecto que a todo el mundo le haga falta y que sea fácil de alcanzar. Como todavía no llego a esa meta sigo tratando y hoy les traigo otro de mis intentos.

¿Cuántas veces necesitaste traducir algo y no pudiste?

En mi caso particular esto es imposible de contabilizar, de hecho, cuando no estoy frente a mi PC conectada a Internet con Google Translator abierto, creo que me resulta difícil sino imposible conseguir una traducción.

Bueno, sin más introducción les presento el traductor español/inglés – inglés/español del mismísimo Google en tu celular!

¿Cómo funciona?
  • Envía ain + texto-en-castellano al 0981157325 para traducir un texto (o palabra) de castellano a inglés. Ejemplo: ain hola mundo!
  • Envía aes + texto-en-inglés al mismo número para el proceso inverso, español a inglés. Ejemplo: aes hello world!
Para hacerte más claro el panorama: ain viene de A-Inglés y aes de A-Español.

Lo único que tenés que hacer ahora es probar 🙂

>La guía telefónica del país en tu celular

>

No exagero. Podés tener la guía de todos los usuarios de línea fija (COPACO) en tu celular al alcance de un mensaje de texto.

Muchas veces recibí llamadas de línea baja desde números desconocidos. Muchas de esas llamadas resultaron ser importantes por lo que perdí oportunidades que pude haber aprovechado si hubiera sabido quién llamaba o si hubiera podido identificar el número cuando no estaba registrado entre mis contactos.

Con este nuevo proyecto pretendo ayudar a las personas a identificar esas llamadas perdidas que podrían llegar a ser relevantes en cierto aspecto, así, ya no te quedás con la duda de saber quién te llamó.

La guía telefónica

Lo que hago no es ilegal en ningún aspecto hasta donde llega mi conocimiento legislativo. Uso una base de datos pública, no muy user friendly, le creé una interfaz un poco más intuitiva y la expongo al público con ánimos de ayudar. Es un servicio gratuito que seguirá vivo mientras dure mi saldo para mensajes. No veo nada de malo en esto.

Cómo usar

Enviá quien + nro-linea-baja al 0981157325 y recibirás un mensaje con el nombre del titular y la dirección registrada.

Por ejemplo: “quien 021998877”. Quince segundos después estarás recibiendo la información que buscás.

A tener en cuenta

  • Si el número de teléfono que buscas no existe o esta mal formado, no se responde el mensaje informando tal cosa con el fin de ahorrar saldo.
  • Si el número que buscas existe, está bien construido y no recibís respuesta, probablemente me quedé sin saldo.
  • Si el número que buscás tiene menos de 6 dígitos de largo o más 6 dígitos de largo (longitud(número) <> 6) , tenés que enviar el mensaje de ésta forma: área.número. Por ejemplo: 0541.66777.

En general, es fácil de usar.

Probá

El sistema está on-line, probá, comprobá que funciona y hacele propaganda para que otros puedan usar 🙂 .