{"id":1878,"date":"2021-04-26T07:59:10","date_gmt":"2021-04-26T07:59:10","guid":{"rendered":"https:\/\/apachedigital.io\/?post_type=insight&#038;p=1878"},"modified":"2021-09-15T12:16:52","modified_gmt":"2021-09-15T12:16:52","slug":"proceso-rpa-en-python-para-integracion-de-datos","status":"publish","type":"insight","link":"https:\/\/apachedigital.io\/en\/insight\/proceso-rpa-en-python-para-integracion-de-datos\/","title":{"rendered":"Proceso RPA en Python para integraci\u00f3n de datos"},"content":{"rendered":"\n<p>Actualmente, la limpieza e integraci\u00f3n de diferentes datos en la empresa se est\u00e1 convirtiendo en el d\u00eda a d\u00eda de muchos desarrolladores.<\/p>\n\n\n\n<p>Existen diferentes fuentes y de muy diversas caracter\u00edsticas, como bases de datos relacionales, sistemas de ficheros, plataformas de datos de terceros y datos que vienen directamente de fuentes p\u00fablicas de internet. Cualquier fuente de datos puede ser de valor en alg\u00fan punto de nuestra estrategia de datos.<\/p>\n\n\n\n<p>Algunas de las fuentes no siempre est\u00e1n disponibles, pueden pertenecer a terceros y su extracci\u00f3n no siempre puede ser v\u00eda conexi\u00f3n ODBC, API ,SFTP. Adem\u00e1s de encontrarnos con fuentes que debemos integrar extrayendo desde el origen de datos u obtener el fichero y cargar la informaci\u00f3n a mano desde una web.<\/p>\n\n\n\n<h2><strong>Caso de uso en Apache Digital<\/strong><\/h2>\n\n\n\n<p>Como Consultora de Innovaci\u00f3n y Marketing Digital, tratamos con muchos tipos de clientes diferentes y no todos nos ofrecen sus datos de la misma forma.<\/p>\n\n\n\n<p>Hay clientes que, por cuestiones internas, nos facilitan parte de la informaci\u00f3n en ficheros v\u00eda sftp, mientras que otros nos comparten el acceso a una plataforma de reporting, donde los datos se obtienen a mano y de donde necesitamos obtener varias m\u00e9tricas y dimensiones adicionales.&nbsp;<\/p>\n\n\n\n<p>Esto nos supone un problema, porque el flujo de informaci\u00f3n que queremos integrar est\u00e1 descoordinado y no automatizado, ya que nos vemos forzados a incluir ficheros a mano; el primer mes podr\u00edamos tener un solo fichero, pero, en funci\u00f3n de c\u00f3mo avancen las necesidades del cliente, podr\u00edamos tener m\u00e1s.<\/p>\n\n\n\n<p>Para ahorrar horas y automatizar el flujo de datos en el conjunto de nuestro proyecto, crearemos un bot cuyo objetivo es navegar por el buscador, hacer login en la plataforma, descargar el fichero y enviarlo. De este modo, ahorramos tiempo y ganamos en orden, coordinaci\u00f3n y eficiencia.<\/p>\n\n\n\n<p>Para automatizar estos procesos, podemos recurrir a procesos RPA o automatizaci\u00f3n rob\u00f3tica. Existen muchas herramientas para ello como Uipath. En nuestro caso de uso, nos apoyaremos de <em>Selenium<\/em>, <em>Python<\/em> y <em>Pythongui<\/em> como librer\u00edas principales para construir nuestro proceso.<\/p>\n\n\n\n<ul><li><strong>Selenium Client API de python<\/strong>: Con ella podremos crear tareas que se van a ejecutar en nuestro buscador: como hacer login, descargar un fichero, etc. Selenium es un software que, adem\u00e1s, permite realizar pruebas en la web.<\/li><li><strong>Pythonautogui<\/strong>: es una librer\u00eda que nos permite guiar el rat\u00f3n e interaccionar con elementos del ordenador en funci\u00f3n de las coordenadas XY de la pantalla. Esta dependencia nos ayuda mucho para interacciones ocasionales con elementos que se encuentren fuera del buscador.<\/li><li><strong>Python:<\/strong> versi\u00f3n 3.8<\/li><\/ul>\n\n\n\n<p>El proceso debe realizar las siguientes acciones:<\/p>\n\n\n\n<ol><li>Abrir el navegador y acceder a la URL objetivo<\/li><li>Navegar hasta la URL objetivo<\/li><li>Introducir User, Pass y hacer login<\/li><li>Seleccionar los datos de un reporte objetivo y descargarlo en formato .csv<\/li><li>Obtener el fichero y renombrarlo<\/li><\/ol>\n\n\n\n<p>Exposici\u00f3n del c\u00f3digo:<\/p>\n\n\n\n<h5><strong>1.Abrir el navegador.<\/strong><\/h5>\n\n\n\n<p>Como paso previo a ordenar a Selenium que abra el navegador, debemos realizar varias configuraciones. La primera es importar Selenium e indicarle la ruta donde tenemos el driver. Nosotros usamos Chrome.<\/p>\n\n\n\n<p>El enlace de descarga es el siguiente:<\/p>\n\n\n\n<ul><li><a href=\"https:\/\/chromedriver.chromium.org\/downloads\">https:\/\/chromedriver.chromium.org\/downloads<\/a><\/li><\/ul>\n\n\n\n<p>Importamos Selenium mediante import Selenium y configuraremos el driver del siguiente modo:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh5.googleusercontent.com\/x59urY3TdKx788gNEfFy1coeY-dkcI7rA64Q_0uQrCjmEXyuhM-El5CHlmYt8kzgy3xXtGBEVSimyUkdMUdpWc-Ruq3OQXWU9Lh9h7uTSjg4wy06r-9ZhtehjXDc-5iW-ItmMQ5O\" alt=\"\"\/><\/figure>\n\n\n\n<p>Sobre el objeto webdriver de Selenium, buscamos nuestro buscador y le pasamos como variable el <em>path<\/em> donde se encuentra en nuestro sistema. A continuaci\u00f3n, seleccionamos la URL a la que queremos acceder.<\/p>\n\n\n\n<h5><strong>2.Navegar hasta la url objetivo:<\/strong><\/h5>\n\n\n\n<p>Ahora que hemos probado el navegador, solamente debemos incluir la url objetivo que queramos poner en el par\u00e1metro URL.<\/p>\n\n\n\n<h5><strong>3.Introducir User, Pass y hacer login:<\/strong><\/h5>\n\n\n\n<p>En este paso, debemos buscar el navegador qu\u00e9 objetos son los que permiten la interacci\u00f3n con el user y pass para hacer login. Por lo tanto, debemos seleccionar el rect\u00e1ngulo de usuarios, hacer click derecho e inspeccionar el elemento.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh5.googleusercontent.com\/Pg7bS2_qe0vpe_iK_IUyUoq4B0WwUljYVxBf7cJS7oYSY9q6aqAnRc2CmjTlloMcLSpc18GEb7YEA8AY91XNSyPjuK5GysSetqyK8VZ51WECSwh_4osk74GsuD3sBrDgcIqTaOWa\" alt=\"\"\/><\/figure>\n\n\n\n<p>El elemento id se llama indentifierId. Para llamar a este elemento desde Selenium usaremos la siguiente instrucci\u00f3n:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh6.googleusercontent.com\/yM6Arw2M6PEFwskzkrI5VpAE3zxWuMsFsR711ebhgPTYGJwUO15yvsxzZW8n8X_x-MejRr72VCSi1tv7v0snT_s_5Kfo-BrRYCRjcvSDsv5NXaQAEdiUfJIhpnHsHJqAPnLk0ORq\" alt=\"\"\/><\/figure>\n\n\n\n<p>El objeto find_element_by_id(&lt;NOMBRE OBJETO&gt;) llamar\u00e1 al elemento de la web. Nosotros adem\u00e1s usaremos el objeto send_keys, que nos permitir\u00e1 enviar las claves a ese objeto e interaccionar con \u00e9l.<\/p>\n\n\n\n<p>Ahora debemos pulsar el bot\u00f3n siguiente. Para estos casos, no es tan simple encontrar el objeto correspondiente, una forma alternativa de encontrar objetos es mediante la ruta XPATH, que marca el lugar del objeto en el html. Para localizar la ruta XPATH debemos realizar los siguientes pasos:<\/p>\n\n\n\n<p><strong>Seleccionar elemento&#8211;&gt;inspeccionar elemento&#8211;&gt;click derecho&#8211;&gt;copiar&#8212;&gt; como xpath<\/strong><\/p>\n\n\n\n<p>La instrucci\u00f3n quedar\u00eda definida del siguiente modo:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh5.googleusercontent.com\/qDqy4OOOdwCZ84LvsGwwLZT0y24OQtwV5wSxUBFoMpBlHpxcBffDatonbaTvzdxT255fJ8R3h1JF1uhddT0HU0is2BSxBrITevFVXoA7KFj4uXnU8vLsFup3kzrX4s9Srcca9mRP\" alt=\"\"\/><\/figure>\n\n\n\n<h5><strong>4.Seleccionamos los datos del reporte objetivo.<\/strong><\/h5>\n\n\n\n<p>En mi caso el fichero est\u00e1 en un e-mail, pero la metodolog\u00eda es la misma, inspeccionar el elemento v\u00eda id o bien xpath, incorporarlo al objeto de Selenium e interaccionar con \u00e9l.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh5.googleusercontent.com\/eI_83PQ9Nz4UKn4WqkmCdIO9KKbBTEmPV2g9ovKfmPBrKreZdM5ryjPlEQ5Zs8uDZLE9xZ3to-MQVNAOAaGzEiRs9VvoZdbd1pK87uJiTRwKSUBU1h-iA8DbTjEPxUa3M1KJ-hZH\" alt=\"\"\/><\/figure>\n\n\n\n<p>En este caso, y a modo de bonus, hemos incorporado una funci\u00f3n llamada WebDriverWait. Esta funci\u00f3n no se ejecuta hasta que el elemento visual se ha cargado en la p\u00e1gina, espera N segundos e interacciona con \u00e9l. En nuestro caso, seleccionamos el objeto donde se encuentra el fichero, realizamos un click y entramos, despu\u00e9s el fichero lo descargamos.<\/p>\n\n\n\n<h5><strong>5.Renombramos el fichero y lo enviamos<\/strong><\/h5>\n\n\n\n<p>Renombramos el fichero con el comando os.rename en python.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh5.googleusercontent.com\/OyAiZD4f72lPkquGGFMyGICxsjMPcoaYq5VHmO--nBr8v7ThLJEbZW_EjbVDPVcJVOWSSaSZdbM5LJfWXU47egshkX9XurXY2ZsfWQGBDesJ1obInjjxvopWqpbKwDTO51xZryyu\" alt=\"\"\/><\/figure>\n\n\n\n<p>Ahora el fichero ya est\u00e1 listo para ser enviado. Nosotros nos apoyamos en la librer\u00eda oficial de GCS para realizar el env\u00edo a nuestro bucket.<\/p>\n\n\n\n<p><a href=\"https:\/\/cloud.google.com\/storage\/docs\/uploading-objects\">https:\/\/cloud.google.com\/storage\/docs\/uploading-objects<\/a><\/p>\n\n\n\n<p>En este punto, el proceso ya ha finalizado y el fichero est\u00e1 en nuestro GCS.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh3.googleusercontent.com\/_9WnFzuU1HYH-5va4lwvfRwjSvYr02lyjWpnaAboTZ_j7qTI_yODwAiQLXNltU5E9wDzGXVRAPkoWKtqcjzWfvU1oBP9mlP8D5ST_rFH5Lb6n67zrpRAd-fcP1vW3pXstRM5-bTR\" alt=\"\"\/><\/figure>\n\n\n\n<p>Como podemos apreciar, el proceso ha incorporado los datos en nuestro Bucket de Google Cloud. Nosotros disponemos de una tabla en BQ con la capacidad de leer los ficheros de ese directorio en el bucket. De este modo, ya tenemos los datos en un mismo punto, junto con los otros or\u00edgenes de datos. As\u00ed, ya podemos empezar a integrar en nuestro Data Warehouse.<\/p>\n\n\n\n<h2><strong>Orquestaci\u00f3n del proceso y tecnolog\u00edas implicadas&nbsp;<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh6.googleusercontent.com\/dxdYycS2HrhNt-gejIy7GbfdJ0ZAXnhdsBPC8bDd374wGtSOLQRQwseOausj8jdalCJv7aPyqs4A0VcYR6MVLwbSdHJteNL60EJFfJb7vlFOU5kIFX1FdmLmi_G-VSl3CEr0Bbw0\" alt=\"\"\/><\/figure>\n\n\n\n<p>\u00bfD\u00f3nde se encontrar\u00e1 la m\u00e1quina donde va a ejecutarse el proceso?<\/p>\n\n\n\n<p>Nosotros disponemos de una m\u00e1quina virtual windows, sobre la que hemos creado un directorio llamado proceso donde estar\u00e1 localizado el proceso de python que vamos a ejecutar. Nos apoyaremos en Task Scheduler de Windows para determinar la hora y la frecuencia con la que vamos a querer ejecutar nuestro proceso. En nuestro caso, ser\u00eda cada d\u00eda a las 9 de la ma\u00f1ana. A esa hora, el proceso de Python va a ejecutarse y en varios minutos dispondremos, cada d\u00eda, de nuestro fichero en GCS y en nuestra BBDD.<\/p>\n\n\n\n<p>Dado que trabajamos en Cloud, no tenemos la m\u00e1quina activa las 24h del d\u00eda y por ello nos apoyamos en <strong>Cloud Functions,<\/strong> que nos permiten delimitar a qu\u00e9 horas debe encenderse la m\u00e1quina virtual y a qu\u00e9 hora se apaga.<\/p>\n\n\n\n<p>Las Cloud Functions son las siguientes:<\/p>\n\n\n\n<p>El concepto es simple, debemos usar nuestras credenciales de GCP, determinar el proyecto, la ubicaci\u00f3n de la m\u00e1quina y la instalaci\u00f3n sobre la que queremos trabajar, una vez ejecutado el c\u00f3digo la m\u00e1quina se apagar\u00e1\/encender\u00e1.<\/p>\n\n\n\n<ul><li>Encendido:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh3.googleusercontent.com\/UStu591HzODh_RTotjj001PMuKmglYhuNP8Yf2orGKrsPKQOnNXJCgH_uwDBG7vw5sCNEfMaE2KdNFnSFSEoHgDnW8IBZZ24IlHaVOMIUYnicTtLRS0O3ZkGcoYWz7KX7CvxmPvj\" alt=\"\"\/><\/figure>\n\n\n\n<ul><li>Apagado<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/lh4.googleusercontent.com\/voKCEvZx_VpzOxLUworTH3ExGJXcEP2bpyuemXZ9oNx_c9KdGn6N4q9iOFmCy9JJov2fFIfcNsbdvDieOuGzuuKq8BnUFYP28GhN5Gc6NHEM8V-ayGrMZq0YhjIqLkaeIJRJkCME\" alt=\"\"\/><\/figure>\n\n\n\n<p>Nosotros establecemos el encendido de la m\u00e1quina a las 8 de la ma\u00f1ana y su apagado a las 19 horas de la tarde. De modo que a las 9h se activ\u00f3 la tarea y la ejecuci\u00f3n del fichero en Python.<\/p>\n\n\n\n<h2><strong>Conclusi\u00f3n<\/strong><\/h2>\n\n\n\n<p>Mediante el proceso creado, hemos automatizado un flujo de trabajo. Gracias a ello ahorramos horas que podemos dedicar a mejorar y mantener procesos m\u00e1s relevantes para el proyecto. Adem\u00e1s, alcanzamos nuestro objetivo principal, que es el de automatizar un nuevo flujo de trabajo e integrarlo con el resto de datos en nuestro ecosistema de trabajo.<\/p>\n\n\n\n<p>Como todo proceso, puede fallar y vamos a necesitar realizar un control de errores firme para detectar si algunos de los ficheros no est\u00e1n descargados y cargados en el sistema.<\/p>\n\n\n\n<p>Las principales ventajas son:<\/p>\n\n\n\n<ul><li>Automatizaci\u00f3n de una tarea manual<\/li><\/ul>\n\n\n\n<ul><li>Extracci\u00f3n de una nueva fuente de datos<\/li><\/ul>\n\n\n\n<ul><li>Oportunidad de integrar una fuente de dato<\/li><\/ul>\n\n\n\n<ul><li>Proceso sencillo<\/li><\/ul>\n\n\n\n<p>Las principales desventajas son:<\/p>\n\n\n\n<ul><li>Si el rendimiento del servidor web de origen es bajo, nuestro proceso puede ser inestable<\/li><\/ul>\n\n\n\n<ul><li>Cambios en front visuales afectar\u00e1n al proceso<\/li><\/ul>\n\n\n\n<ul><li>Solo es para tareas sencillas<\/li><\/ul>\n","protected":false},"author":27,"featured_media":1874,"template":"","category_insight":[57],"_links":{"self":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/insight\/1878"}],"collection":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/insight"}],"about":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/types\/insight"}],"author":[{"embeddable":true,"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/users\/27"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/media\/1874"}],"wp:attachment":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/media?parent=1878"}],"wp:term":[{"taxonomy":"category_insight","embeddable":true,"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/category_insight?post=1878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}