lunes, 2 de diciembre de 2013

Obtener el tipo de cambio de SUNAT del mes actual con C#

Después de varios meses de inactividad en el blog, quisiera compartir con todos el código para poder obtener el tipo de cambio del mes desde la web de SUNAT que es tan útil para conversiones de moneda sol a dolar en temas tributarios.

Primero tengo que obtener la librería HtmlAgilityPack que nos ayudara a manejar el HTML de la pagina web de SUNAT (http://www.sunat.gob.pe/cl-at-ittipcam/tcS01Alias). Para esto, descargamos la versión 1.4.6 de la pagina web del proyecto https://htmlagilitypack.codeplex.com/. Posteriormente, lo importamos como referencia en nuestro proyecto.


Ahora nos toca implementar el código que se encargará de conectarse a la pagina web y obtener el documento HTML.

string sUrl = "http://www.sunat.gob.pe/cl-at-ittipcam/tcS01Alias";
 
Encoding objEncoding = Encoding.GetEncoding("ISO-8859-1");
WebProxy objWebProxy = new WebProxy("proxy", 80);
CookieCollection objCookies = new CookieCollection();
 
//USANDO GET
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(sUrl);
getRequest.Proxy = objWebProxy;
getRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
getRequest.ProtocolVersion = HttpVersion.Version11;
getRequest.UserAgent = ".NET Framework 4.0";
getRequest.Method = "GET";
 
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(objCookies);
 
Como se puede ver usamos el Httpwebrequest para realizar la petición a la web de SUNAT y con esto deberíamos obtener una respuesta que se cargara en el Httpwebresponse que se muestra continuación.

string sGetResponse = string.Empty;
 
using (HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse())
{
 objCookies = getResponse.Cookies;
 
 using (StreamReader srGetResponse = new StreamReader(getResponse.GetResponseStream(), objEncoding))
 {
  sGetResponse = srGetResponse.ReadToEnd();
 }
}

Se ve que el resultado de la consulta se guarda en la variable sGetResponse y esta contendrá el código HTML de la web de tipo de cambio. Con esta información ya podremos saber cuales son los tipos de cambio de este mes pero nos faltaría obtener los valores de día, venta y compra sin los demás datos redundante del HTML. Para ello, usaremos la librería HtmlAgilityPack que ya tenemos en nuestro proyecto.
//Obtenemos Informacion
HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
document.LoadHtml(sGetResponse);
Como se puede apreciar, se ha cargado la variable sGetResponse, que contiene el código HTML, como  un objeto de tipo HtmlDocument. Con esto ya podemos navegar entre los TAG'S HTML y poder quitar los datos redundante y solo obtener los que necesitamos. Estos datos los colocaremos en una tabla que contendrá 3 columnas (día, compra y venta).
HtmlNodeCollection NodesTr = document.DocumentNode.SelectNodes("//table[@class='class=\"form-table\"']//tr");
if (NodesTr != null)
{
 DataTable dt = new DataTable();
 dt.Columns.Add("Día", typeof(String));
 dt.Columns.Add("Compra", typeof(String));
 dt.Columns.Add("Venta", typeof(String));

 int iNumFila = 0;
 foreach (HtmlNode Node in NodesTr)
 {
  if (iNumFila > 0)
  {
   int iNumColumna = 0;
   DataRow dr = dt.NewRow();
   foreach (HtmlNode subNode in Node.Elements("td"))
   {

    if (iNumColumna == 0) dr = dt.NewRow();

    string sValue = subNode.InnerHtml.ToString().Trim();
    sValue = System.Text.RegularExpressions.Regex.Replace(sValue, "<.*?>", " ");
    dr[iNumColumna] = sValue;

    iNumColumna++;

    if (iNumColumna == 3)
    {
     dt.Rows.Add(dr);
     iNumColumna = 0;
    }
   }
  }
  iNumFila++;
 }

 dt.AcceptChanges();
 this.dgvHtml.DataSource = dt;
 this.dgvHtml.ReadOnly = true;

}
Como se puede apreciar,  se filtra por el TAG
, la cual contiene los datos que necesitamos y procedemos a recorrer la pagina web y extraer los datos que necesitamos colocar en nuestra tabla. El resultado final será esto:


Resultado de web de SUNAT

Resultado de la aplicación después de manipular los datos que queremos mostrar.


Espero que sea tan útil como me sirvió a mi y les dejo el link de los archivos para que puedan descargarlo








32 comentarios:

Daniel dijo...

Hola que talme parece muy interesante tu proyecto, quisiera ver si me puedes ayudar con un ejemplo paravisual basic 6.0 o.net te estaria muy agradecido

r3xet dijo...

Hola daniel, te puedo apoyar con cualquier duda q tengas. Slds

Daniel dijo...

Ok muchas gracias por tu disposión la verdad no se por donde empezar no quisiera que pienses que quiero que hagas algo para mi y yo usarlo sin ningun esfuerzo mio pero lo que pasa es que solo soy aficionado a esto de la programacion no tengo estudios .
Y la pregunta en concreto seria como hago lo que tu haz hecho de obtener el tipo de cambio de sunat en C# con codigo de visual basic 6.0 o .net

Daniel dijo...

Hola r3xet disculpa si te causo alguna incomodidad quisera ver si me puedes ayudar con esto:
http://www.lawebdelprogramador.com/foros/Visual_Basic/1441122-Obtener_tipo_de_cambio_de_sunat.html
es sobre mi pregunta anterior estuve avanzando pero creo que ya no e mas a que hacer
Espero tu ayuda

Rodrigo Bezada dijo...

Molestandote y todo, pero funciono xD jaja! Funciono muy bien, tuve que hacerles una modificaciones para que funcione con SDK, pero el codigo es casi lo mismo ! Muy bueno,Gracias!

r3xet dijo...

De nada, que el conocimiento se debe compartir :D

r3xet dijo...

Que tal daniel, bueno le di una ojeada a VB, ya que no me acuerdo, y veo que tienes bien avanzado tu proyecto y te felicito. Ademas, que el problema ya no es el obtener el tipo de cambio si no en el uso de la grilla.

Daniel dijo...
Este comentario ha sido eliminado por el autor.
Daniel dijo...

Muchas gracias por dedicar un uno poco te tu valioso tiempo a leer mi consulta y en responderme espero que me puedas ayudar en este tema de la grilla .Bendiciones

Anónimo dijo...

HOLA QUE TAL BUEN APORTE PODRIAS PONER EL CODIGO EN VISUAL 2008 TE LO AGRADECERIA MUCHO Y COMO AGRADECIMIENTO PONDRIA ENVIAR A TU CORREO :

*PAGINACION DEL DATAGRIVIEW (PUEDO MOSTRAR 50,000.00 REGISTROS EN 2 SEGUNDOS QUE SE ENCUANTRAN PAGINADOS 100 REGISTROS POR PAGINA)

*EXPORTAR LOS DATOS DEL DATAGRIDVIEW A UN ARCHIVO XML (SE CREA EL ARCHIVO CON EL ICONO DEL EXCEL Y OBVIAMENTE SE ABRE CON EXCEL) LO HICE DE ESTA MANERA POR QUE QUERIA EXPORTAR MUCHOS DATOS Y DE ESTA MANERA PUEDO EXPORTAR 50,000.00 REGISTROS EN SEGUNDOS COSA QUE NO SE PUEDE DE LA MANERA CONVENCIONAL QUE ES EXPORTARLO A EXCEL QUE SE DESMORA COMO 8 MINUTOS

BUENO MI CORREO ES MARKHO34 EN H_O_T_M_A_I_L

Anónimo dijo...

Tengo un problema me sale este mensaje de error --> No se puede resolver el nombre del proxy.: 'proxy', sería de gran ayuda que me brindaras tu apoyo

r3xet dijo...

Si no están en une red privada (por lo generar restringida y filtrada por un proxy) pueden quitar la opción de proxy.

r3xet dijo...

En vista que es un tema interesante el poder extraer el tipo de cambio SUNAT, esteré liberando la librería para hacer mas fácil el acceso y obtención de dichos datos. De antemano gracias por su interes. Slds

Anónimo dijo...

Hola, y cómo harías para filtrar por mes y año? se puede?

ANTHONY ERICK FARFAN RODRIGUEZ dijo...

Pata y que libreia esocjes net40

Saúl A. Bonilla dijo...

Bueno tu post, pero no puedo descargar tu proyecto, me puedes enviar el nuevo link?..Gracias

Aaron Castillo dijo...

Hola , muy buen post , buscando scrapers para obtener datos de sunat me encontre con este , actualmente estoy trabajando en algo similiar pero usando la tecnologia Nodejs, los datos que busco son los de consulta ruc , dejo el link del proyecto si es que a alguien le interesa. https://github.com/Cshion/sunatRucScraper

r3xet dijo...

Estimados, pueden encontrar el proyecto en https://tcsunatperu.codeplex.com/ difundan y no se olviden de mencionarme ;) slds

Fernando Cordova dijo...
Este comentario ha sido eliminado por el autor.
nill frank ushiñahua flores dijo...

hola tio esta buena tu código, aun no lo he probado pero no encuentro el link de descarga para ver el ejemplo en si. seria de mucha ayuda que resubieras el ejemplo o otro link. gracias por aporte de antemano. ah y tu crees que el valor se puede cargar en un label?. gracias de todas maneras

Elias Fuentes dijo...

Yo tengo una solucion mas practica y listo para consumir, es usando los webservice para mas informacion ingresa a http://dataservice.insite.pe.

Esa pagina contiene informacion de:
* consulta RUC
* establecimientos anexos
* tipo de cambio
* info plame

Dandi L dijo...

Gran aporte ideal para nuestros proyectos personales en contabilidad. Creo que ha actualizado el formato de verificación de cambio, les comparto el link que encontré. Saludos.

Sunat Tipo de Cambio Oficial

Dandi L dijo...

Ops, creo que no salió, aquí de nuevo, saludos

http://tramites-sunat.blogspot.com/2016/07/sunat-tipo-de-cambio-oficial.html

Abigail Rossi dijo...

Buenas noches, no puedo referenciar HtmlAgilityPack, por favor si me puede ayudar. Gracias

Dandi L dijo...

Apoyo la consulta, siempre es bueno tener el tipo de cambio oficial bien aplicado en nuestra base. saludos.

Eduardo Quiroz Cosme dijo...

Sabes como sacar el tipo de cambio de otros meses?

Anónimo dijo...

Hola esta muy bueno, Yo quiero cargarlo por año y mes , al momento de obtener los datos de la web , le trato de insertar el mes y año pero me sale "es solo lectura". alguien me da una mano, gracias

Unknown dijo...

http://www.sunat.gob.pe/cl-at-ittipcam/tcS01Alias?mes=06&anho=2017

En el URL

Breismar Gomez dijo...

Es el registro informático de la SUNAT. En él se encuentran inscritos los contribuyentes de todo el país, así como otros obligados a inscribirse en él por mandato legal, que deben pagar a impuestos al Gobierno Central y son materia de administración por la SUNAT. Allí Contiene información como el nombre, denominación o razón social, el domicilio fiscal, la actividad económica principal y las secundarias de cada contribuyente.
Fuente: www.sunatoperacionesenlinea.review

Josue Rodriguez Puruguay dijo...

Aquí les copio lo que desarrollé para PHP, espero le pueda servir a alguien:

$sUrl = "http://www.sunat.gob.pe/cl-at-ittipcam/tcS01Alias";
$sContent = file_get_contents($sUrl);
$doc = new DOMDocument();
$doc->loadHTML($sContent);
$xpath = new DOMXPath($doc);
$tablaTC = $xpath->query("//table[@class='class=\"form-table\"']"); //obtenemos la tabla TC
$filas = [];

foreach($tablaTC as $fila){
$filas = $fila->getElementsByTagName("tr"); //obtiene todas las tr de la tabla de TC
}

$tcs = array(); //array de tcs, por dia como clave

foreach($filas as $fila){//recorremos cada tr
$tds = [];
$tds = $fila->getElementsByTagName("td");
$i = 0;
$j = 0;
$arr = [];
$dia = "";
foreach($tds as $td){//recorremos cada td
if($j == 3){
$j = 0;
$arr = [];
}
if($j == 0){
$dia = trim(preg_replace("/[\r\n]+/", " ", $td->nodeValue));
$tcs[$dia] = [];
}
if($j > 0 && $j < 3){
$tcs[$dia][] = trim(preg_replace("/[\r\n]+/", " ", $td->nodeValue));
}
$j++;
}
}

Josué Rodriguez P.

Karlos Uriarte dijo...

Hola,
Alguien me puede enviar el codigo fuente para .net y revisarlo

Karlos Uriarte dijo...
Este comentario ha sido eliminado por el autor.