CursosEmpresasBlogLiveConfPrecios

Guardando las noticias en archivos de texto

Clase 20 de 21 • Curso de Fundamentos de Web Scraping con Python y Xpath

Clase anteriorSiguiente clase

Contenido del curso

Introducción al web scraping
  • 1
    ¿Qué es el web scraping?

    ¿Qué es el web scraping?

    02:06
  • 2
    ¿Por qué aprender web scraping hoy?

    ¿Por qué aprender web scraping hoy?

    03:05
  • 3
    Python: el lenguaje más poderoso para extraer datos

    Python: el lenguaje más poderoso para extraer datos

    03:21
Fundamentos de la web
  • 4
    Entender HTTP

    Entender HTTP

    07:02
  • 5
    ¿Qué es HTML?

    ¿Qué es HTML?

    08:08
  • 6
    Robots.txt: permisos y consideraciones al hacer web scraping

    Robots.txt: permisos y consideraciones al hacer web scraping

    05:41
XML Path Language
  • 7
    XML Path Language

    XML Path Language

    03:35
  • 8
    Tipos de nodos en XPath

    Tipos de nodos en XPath

    05:18
  • 9
    Expresiones en XPath

    Expresiones en XPath

    08:18
  • 10
    Predicados en Xpath

    Predicados en Xpath

    05:34
  • 11
    Operadores en Xpath

    Operadores en Xpath

    05:51
  • 12
    Wildcards en Xpath

    Wildcards en Xpath

    06:11
  • 13
    In-text search en Xpath

    In-text search en Xpath

    08:21
  • 14
    XPath Axes

    XPath Axes

    05:16
  • 15

    Resumen de XPath

    00:01
  • 16
    Aplicando lo aprendido

    Aplicando lo aprendido

    08:52
Proyecto: scraper de noticias
  • 17
    Un proyecto para tu portafolio: scraper de noticias

    Un proyecto para tu portafolio: scraper de noticias

    10:08
  • 18
    Construcción de las expresiones de XPath

    Construcción de las expresiones de XPath

    10:29
  • 19
    Obteniendo los links de los artículos con Python

    Obteniendo los links de los artículos con Python

    10:56
  • 20
    Guardando las noticias en archivos de texto

    Guardando las noticias en archivos de texto

    14:53
Conclusiones
  • 21
    Cómo continuar tu ruta de aprendizaje

    Cómo continuar tu ruta de aprendizaje

    02:13
    Pamela Pimentel

    Pamela Pimentel

    student•
    hace 5 años

    Hola, les dejo la solución de los títulos y en mi caso también de los links. Por algún motivo el response toma el tag h2 como text-fill.

    code.png

      Mario Alberto Vásquez Arias

      Mario Alberto Vásquez Arias

      student•
      hace 5 años

      Tienes mucha razón. También tenia el problema de que me aparecía una lista vacía, y solo cambie h2 por text-fill y se solucionó. Alguien sabrá por que ocurre esto?

      María José Medina

      María José Medina

      student•
      hace 5 años

      Hola Pamela, tambien tuve el mismo problema con el h2. De hecho, cuando ejecuto el código incluyendo h2 en el Xpath me trae 15 de los 84 urls de la página. Ahora, cuando lo ejecuto con tu modificación (el text-fill) me trae las restantes 69... Es extraño

    Alonso Melgar Lopez

    Alonso Melgar Lopez

    student•
    hace 5 años

    Excelente día veo que aun no hay solución al problema de no generar los archivos, esto se debe a un problema con el título de la noticia, lo que regresa es una lista vacía, y por eso entra en el "except", sin embargo en la propia URL de la noticia se encuentra el título, por lo tanto e creado una pequeña función que extrae dicho título.

    Es la solución que encontré, sin embargo seria bueno que alguien que sepa más del tema pueda ayudar con este error

    import requests import lxml.html as html import os import datetime HOME_URL = 'https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE = '//a[contains(@class,"kicker")]/@href' #XPATH_TITLE = Titulo XPATH_SUMMARY = '//div[@class="lead"]/p/text()' XPATH_BODY ='//div[@class="html-content"]//text()' def get_title(link): #separamos por "/" y nos quedamos con el ultimo que elemento url = link.split('/')[-1] #separamos por "-" y eliminamos el ultimo elemento title_list=url.split('-')[:-1] #Unimos lo anterior title = " ".join(title_list) return(title) def parse_notice(link, today): try: response = requests.get(link) if response.status_code == 200: notice = response.content.decode('utf-8') parsed = html.fromstring(notice) try: title = get_title(link) summary = parsed.xpath(XPATH_SUMMARY)[0] body = parsed.xpath(XPATH_BODY) except IndexError: print("as") return with open(f'{today}/{title}.txt', 'w', encoding='utf-8') as f: f.write(title) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def parse_home(): try: response = requests.get(HOME_URL) if response.status_code == 200: home = response.content.decode('utf-8') parsed = html.fromstring(home) links_to_notices = parsed.xpath(XPATH_LINK_TO_ARTICLE) #print(links_to_notices) today = datetime.date.today().strftime('%d-%m-%Y') if not os.path.isdir(today): os.mkdir(today) for link in links_to_notices: parse_notice(link, today) else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__ == "__main__": run()
      José Alberto Ortiz Vargas

      José Alberto Ortiz Vargas

      student•
      hace 5 años

      Muy buena solucion para extraer el titulo desde la URL eliminando los guinones (-) y quedarnos con el texto. Asi lo pude solucionar para poder crear mis archivos. Sin embargo, considero que el problema esta al momento de ejecutar el XPATH del titulo en el request y que este traiga algo diferente que como lo vemos en Chrome. Me hare un espacio para buscar la solucion.

      Gracias y excelente solucion.

      Edwin San

      Edwin San

      student•
      hace 5 años

      Muchas gracias!!! Me sirvióoo :DD

    Hector F

    Hector F

    student•
    hace 5 años

    Les comparto mi repositorio con mejoras en el proyecto del curso aquí.

    Modularize el código y ahora se puede scrapear varios sitios.

    ¡Saludos!

    Bardo Santiago

    Bardo Santiago

    student•
    hace 5 años

    PROBLEMA CARPETA SE CREA PERO NO SE GUARDAN LOS ARCHIVOS. Todo funcionaba bien el momento de crear la carpeta, pero los archivos no se creaban dentro. El problema estaba en uno de los XPATH. Originalmente estaba usando las siguientes constantes:

    XPATH_LINK_TO_ARTICLE = '//a[@class="globoeconomiaSect"]/@href' XPATH_TITLE = '//div[@class="mb-auto"]/h2/span/text()' XPATH_SUMMARY = '//div[@class="lead"]/p/text()' XPATH_BODY = '//div[@class="html-content"]/p[not(@class)]/text()'

    Después de buscar entre los aportes de la comunidad encontré un ejemplo que me ayudó. Sin modificar mucho, realicé un cambio en la constante XPATH_TITLE y quedo de la siguiente manera.

    #ANTES XPATH_TITLE = '//div[@class="mb-auto"]/h2/span/text()'
    #DESPUES XPATH_TITLE = '//div[@class="mb-auto"]//span/text()'

    Lo que hice fue remover la etiqueta h2 de la sentencia. Sin embargo hacer este ajuste implicó modificar el índice en la siguiente línea.

    #Antes title = parsed.xpath(XPATH_TITLE)[0]
    #Despues title = parsed.xpath(XPATH_TITLE)[1]

    Este cambio se debe a que la nueva estructura de XPATH_TITLE devuelve dos elementos y el título es el segundo, por esta razón utilicé el índice [1]. ..

    Utilicé el código tal cual se desarrolló en la clase solo realice estos dos ajustes para que me funcionara.

      Aaron Fabrizio Calderon Guillermo

      Aaron Fabrizio Calderon Guillermo

      student•
      hace 5 años

      Genial! También funciona correctamente y con dos cambios en el código.

      Rodrigo Rodriguez

      Rodrigo Rodriguez

      student•
      hace 5 años

      Gracias Bardo Santiago, fuiste de gran ayuda para encontrar el title. Igualmente seria bueno plantear la pregunta: ¿Porque en python no funciona, si en chrome el xpath propuesto por el profesor obtiene el titulo ?

      Yo he hecho las pruebas el 1-5-21 de los xpath de title, summay y body , en la consola de chrome y todos funcionan.

    Alejandro Giraldo Londoño

    Alejandro Giraldo Londoño

    student•
    hace 5 años

    RESUMEN:Guardando las noticias en archivos de texto ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

    Vamos a realizar una lógica para ir de cada link al sitio de cada noticia y de ahí extraer:

    • Titulo
    • Resumen
    • Cuerpo
    import requests import lxml.html as html # Lo usaremso para crear una carpeta import os # Lo usaremos para manipular fechas. import datetime # Creamos constantes HOME_URL = 'https://www.larepublica.co/' #Recuerda que tu Xpath puede variar. XPATH_LINK_TO_ARTICLE = '//text-fill[not(@class)]/a/@href' XPATH_LINK_TO_TITLE = '//div[@class="mb-auto"]/h2/a/text()' XPATH_LINK_TO_SUMMARY = '//div[@class="wrap-post col-9"]/div/div[@class="lead"]/p/text()' XPATH_LINK_TO_BODY = '//div[@class="html-content"]/p[not(@class)]/text()' def parse_notice(link, today): try: response = requests.get(link) if response.status_code == 200: # Traigo el docuemnto html de la noticia. notice = response.content.decode('utf-8') parsed = html.fromstring(notice) #Quiero traer el título, el cuerpo y el resumen, hago una validación # try -except, estoy haciendolo para los índices de la lista. # Pueden haber noticias con nodos faltantes por lo que arrojará un error try: #Traemos el primer elemento de la lista. title = parsed.xpath(XPATH_LINK_TO_TITLE)[0] # No es deseable tener comillas en los títulos porque presentan un error en OS. # Para solucionar esto, hacemos uso de que title es un str y del metodo replace() title = title title = title.replace('\"','') summary = parsed.xpath(XPATH_LINK_TO_SUMMARY)[0] body = parsed.xpath(XPATH_LINK_TO_BODY) except IndexError: return # Guardamos en un archivo # with es un manejador contextual. Si algo sucede y el script se cierra, mantiene las cosas # de manera segura y así no se corrompe el archivo. with open(f'{today}/{title}.txt','w', encoding ='utf-8') as f: f.write(title) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) # Creamos las funcioens para ejecutar el script. def parse_home(): # Creamos un bloque try para manejar los errores. Y manejar los Status Code. try: response = requests.get(HOME_URL) # Aqui va la lógica para traer los links. if response.status_code == 200: # .content trae el HTML que necesita ser traducido con un decode para que python lo entienda # en terminos de caracteres, me devuelve un string que no es más que el HTML crudo. home = response.content.decode('utf-8') # home = response.text # print(home) # En esta línea uso el parser html para transformar el contentido # html a un archivo que sea de utilidad para las expresiones xpath parsed = html.fromstring(home) print(parsed) # En esta línea estoy usando el archivo parseado con la función xpath y le paso por parámetro mi constante # la cual almacena la expresión Xpath. links_to_notices = parsed.xpath(XPATH_LINK_TO_ARTICLE) # La línea de código me arroja un array vacío. Pero en google si lo enseña. print(len(links_to_notices)) # Depende de tu Xpath y la página web. print(type(links_to_notices)) # Tipo lista print(links_to_notices) # Traigo una fecha con la función fecha. Y Today, la fecha del dái de hoy. La variable today # se almacena un objeto de tipo fecha, pero nos interesa más tener una cadena de caracteres que contenga la fecha # en determinado formato que será guardado en la carpeta y con la función strftime logramos esto today = datetime.date.today().strftime('%d-%m-%Y') # Este condicional sirve para decirle que si no existe una carpeta con la fehca del día de hoy # me cree una carpeta. if not os.path.isdir(today): os.mkdir(today) # Creo la función para recorrer la lista de links y ejecuto en cada ciclo la función parse_notice() for link in links_to_notices: parse_notice(link,today) else: #Elevamos el error para ser capturado en el try-except, too lo que sea un error. raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__ == '__main__': run()
    Daniel Noreña

    Daniel Noreña

    student•
    hace 5 años

    Les compartomi codigo realizado en Abrl 15 (He visto difernecia entre varios compañeros en la estructura de la pagina). Como varios tuve problemas con los h2 que se solucionó reemplazando por text-fill. Así mismo tuve problemas con otras etiquetas que soluciones haciendo la expresión regular lo mas sencilla posible.

    Saludos a todos.

    <code> import requests import lxml.html as html import os import datetime HOME_URL='https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE= '//text-fill/a[@class="economiaSect" or @class="empresasSect" or @class="ocioSect" or @class="globoeconomiaSect" or @class="analistas-opinionSect"]/@href' XPATH_TITTLE='//div[@class="mb-auto"]/text-fill/span/text()' XPATH_SUMMARY='//div[@class ="lead"]/p/text()' XPTAH_BODY='//div[@class="html-content"]/p[not(@class)]/text()' def parse_notice(link,today): try: response=requests.get(link) if response.status_code==200: notice=response.content.decode('utf-8') parsed=html.fromstring(notice) try: tittle=parsed.xpath(XPATH_TITTLE)[0] print(tittle) tittle=tittle.replace('\"','') summary=parsed.xpath(XPATH_SUMMARY)[0] body=parsed.xpath(XPTAH_BODY) except IndexError: return with open(f'{today}/{tittle}.txt','w',encoding='utf-8') as f: f.write(tittle) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def parse_home(): try: response= requests.get(HOME_URL) if response.status_code==200: home=response.content.decode('utf-8') parsed=html.fromstring(home) links_to_notices=parsed.xpath(XPATH_LINK_TO_ARTICLE) today=datetime.date.today().strftime('%d-%m-%Y') if not os.path.isdir(today): os.mkdir(today) for link in links_to_notices: parse_notice(link,today) else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__=='__main__': run()
      Andres muñoz

      Andres muñoz

      student•
      hace 5 años

      muchas gracias por compartir la solución, a mi me tenia cabezón que solo me traía una noticia y cuando vi su código vi que en la variable XPATH_LINK_TO_ARTICLE yo la tenia trayendo una sola. Ya con su respuesta traer todo. Excelente bro

      Oscar Eduardo Chaparro Blancas

      Oscar Eduardo Chaparro Blancas

      student•
      hace 4 años

      Gracias a tu código encontré un error bien tonto en el mío, en donde estaba generando el response dentro del parseo de noticias con el link del home en vez del link de la noticia especifica.

      Agradezco mucho tu aporte compañero :)

    Elliot Ramirez

    Elliot Ramirez

    student•
    hace 4 años

    02/2022

    Para la solución removí el tag h2 del xpath titile, de resto todo continuo igual a la clase.

    import requests import lxml.html as html import os import datetime HOME_URL = 'https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE = '//text-fill[not(@class)]/a/@href' XPATH_TITTLE = '//div[@class="mb-auto"]//span/text()' XPATH_SUMMARY = '//div[@class = "lead"]/p/text()' XPATH_BODY = '//div[@class = "html-content"]/p[not (@class)]/text()' def parse_notice(link,today): try: response=requests.get(link) if response.status_code==200: notice=response.content.decode('utf-8') parsed=html.fromstring(notice) try: tittle=parsed.xpath(XPATH_TITTLE)[0] print(tittle) tittle=tittle.replace('\"','') summary=parsed.xpath(XPATH_SUMMARY)[0] body=parsed.xpath(XPATH_BODY ) except IndexError: return with open(f'{today}/{tittle}.txt','w',encoding='utf-8') as f: f.write(tittle) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def parse_home(): try: response= requests.get(HOME_URL) if response.status_code==200: home=response.content.decode('utf-8') parsed=html.fromstring(home) links_to_notices=parsed.xpath(XPATH_LINK_TO_ARTICLE) today=datetime.date.today().strftime('%d-%m-%Y') if not os.path.isdir(today): os.mkdir(today) for link in links_to_notices: parse_notice(link,today) else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__=='__main__': run()
      Raul Burbano

      Raul Burbano

      student•
      hace 4 años

      Genial, pase mas una hora viendo que fallaba y esto me funciono perfecto

      Andres Matías Andreotta

      Andres Matías Andreotta

      student•
      hace 4 años

      Gracias! No encontraba el problema!

    Osvaldo Damián Ruiz

    Osvaldo Damián Ruiz

    student•
    hace 3 años

    Funcional al 3/1/2023

    saque lo del titulo del comentario de alonmar y de Pamela Pimentel lo de remplazar el h2

    import requests import lxml.html as html import os import datetime #Url de la pagina HOME_URL = 'https://www.larepublica.co' #url del articulo XPATH_LINK_TO_ARTICLE = '//text-fill/a/@href' #Extraer de cada articulo XPATH_TITTLE='//div/text-fill/span/text()' XPATH_SUMMARY='//*[@id="proportional-anchor-1"]/div/div/p/text()' XPATH_BODY='//div/div[4]/p/text()' def get_title(link): #separamos por "/" y nos quedamos con el ultimo que elemento url = link.split('/')[-1] #separamos por "-" y eliminamos el ultimo elemento title_list=url.split('-')[:-1] #Unimos lo anterior title = " ".join(title_list) return(title) def parse_notice(link, today): try: response = requests.get(link) if response.status_code==200: notice = response.content.decode('utf-8') #Guarda el contenido parsed = html.fromstring(notice) try: tittle = get_title(link) #obtiene el titulo summary = parsed.xpath(XPATH_SUMMARY)[0] #get te summary body = parsed.xpath(XPATH_BODY) #get the body except IndexError as ie: print(ie) return try: with open(f'{today}/{tittle}.txt', 'w', encoding='utf-8') as f: f.write(tittle) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: if p.endswith('.'): f.write(p) f.write('\n') else: f.write(p) except: print('no se pudo escribir') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) #Extraer links def parse_home(): try: response = requests.get(HOME_URL) if response.status_code == 200: #si la conexion es correcta home = response.content.decode('utf-8') #guarda en formato leible parsed = html.fromstring(home) #parsea links_to_notice = parsed.xpath(XPATH_LINK_TO_ARTICLE) # print(links_to_notice) today = datetime.date.today().strftime('%d-%m-%Y') if not os.path.isdir(today): os.mkdir(today) for link in links_to_notice: parse_notice(link,today) else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__ == '__main__': run()
      Rafael Rivera

      Rafael Rivera

      student•
      hace 3 años

      Lo tenia muy similar, gracias por compartir.

      Julian Loaiza Lopez

      Julian Loaiza Lopez

      student•
      hace 3 años

      Gracias, me sacaste de un punto donde no podia avanzar

    Diego Martín

    Diego Martín

    student•
    hace 4 años

    06 de noviembre 2021 Con esto me funcionó:

    HOME_URL ='https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE = '//text-fill/a/@href' XPATH_TITLE = '//div[@class="mb-auto"]/text-fill/span/text()' XPATH_SUMMARY = '//div[@class="lead"]/p/text()' XPATH_BODY = '//div[@class="html-content"]/p[not(@class)]/text()'

    El resto, todo es igual :)

      Mauro Andino

      Mauro Andino

      student•
      hace 4 años

      Gracias Diego, me funciono tu aporte

      Giocrisrai Godoy Bonillo

      Giocrisrai Godoy Bonillo

      student•
      hace 4 años

      genial muchas gracias por tu aporte

    David Santiago Martínez Vargas

    David Santiago Martínez Vargas

    student•
    hace 3 años

    Xpath a 14 de agosto de 2022

    En Body se usa descendant-or-self:: * para poder extraer TODO el texto ya que las palabras resaltadas en algunos artículos no son tomadas en la extracción.

    from string import printable import requests import lxml.html as html import os import datetime HOME_URL = 'https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE = "//text-fill/a/@href" XPATH_TITLE = "//div[@class='mb-auto']/h2/span/text()" XPATH_SUMMARY = "//div[@class='lead']/p/text()" XPATH_BODY = "//div[@class='html-content']/p/descendant-or-self::*/text()" #to do: check how to extract the u html def parse_notice(link, today): try: response = requests.get(link) if response.status_code == 200: notice = response.content.decode('utf-8') #save the content of the page in a variable parsed = html.fromstring(notice) #parse the html content try: title = parsed.xpath(XPATH_TITLE)[0] #get the title of the article title.replace('\"', '') #remove the quotes from the title title = title.replace('\'', '') #remove the quotes from the title title = title.replace('\n', '') #remove the newlines from the title title = title.replace('\t', '') #remove the tabs from the title title = title.replace('\r', '') #remove the carriage returns from the title title = title.strip() #remove the whitespaces from the title final_title = title title = title.replace('á', 'a').replace('é', 'e').replace('í', 'i').replace('ó', 'o').replace('ú', 'u') #replace the accents from the title title = title.replace('Á', 'A').replace('É', 'E').replace('Í', 'I').replace('Ó', 'O').replace('Ú', 'U') #replace the accents from the title title = title.replace('?', '').replace('¿', '').replace('!', '').replace('¡', '') #remove the question marks and exclamation marks from the title title = title.replace(':', '').replace(';', '').replace(',', '').replace('.', '').replace('(', '').replace(')', '') #remove the colons, semicolons, commas, dots, parentheses and spaces from the title title = title.replace('%', '').replace('$', '').replace('#', '').replace('@', '').replace('&', '').replace('*', '').replace('+', '').replace('=', '').replace('-', '').replace('_', '').replace('/', '').replace('\\', '').replace('|', '').replace('<', '').replace('>', '').replace('"', '').replace('\'', '') #remove the special characters from the title summary = parsed.xpath(XPATH_SUMMARY)[0] #get the summary of the article body = parsed.xpath(XPATH_BODY) #get the body of the article except IndexError as ie: print(ie) return try: with open(f'{today}/{title}.txt', 'w', encoding='utf-8') as file: file.write(final_title) file.write('\n\n') file.write(summary) file.write('\n\n') for p in body: file.write(p) file.write('\n') except: print('No se pudo escribir el archivo') else: raise ValueError(f'Error {response.status_code}') except ValueError as ve: print(ve) def parse_home(): try: response = requests.get(HOME_URL) if response.status_code == 200: home = response.content.decode('utf-8') #save the content of the page in a variable parsed = html.fromstring(home) #parse the html content links_to_notices = parsed.xpath(XPATH_LINK_TO_ARTICLE) #get the links to the articles # print(links_to_notices) today = datetime.date.today().strftime('%d-%m-%Y') #get the current date if not os.path.isdir(today): #if the directory doesn't exist, create it os.mkdir(today) for link in links_to_notices: #for each link parse_notice(link, today) else : raise ValueError(f'Error {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__ == "__main__": run()
    Juan Fernando Moyano Ramírez

    Juan Fernando Moyano Ramírez

    student•
    hace 5 años

    Hola a todos, os comparto como ha quedado mi codigo al final:

    #el primer paso es importar todas las libreias que voy #a utilizar: import requests from lxml import html #la funcion HTML sirve para convertir archivos de HTML a un tipo de archivo con el cual pueda aplicar XPath import os #vamos a utilizar este modulo para crear una carpeta con la fecha de hoy import datetime #nos permite traer la fecha de hoy #despues debo crear las constantes que me llevaran #al cuerpo, el titulo y el resumen de la noticia. #contiene el link a la pagina principal de la republica HOME_URL = 'https://www.larepublica.co' XPATH_LINK_TO_ARTICLE = '//div[@class="V_Title"]/text-fill/a/@href' XPATH_LINK_TO_TITLE = '//div[@class="mb-auto"]/text-fill/span/text()' XPATH_LINK_TO_SUMMARY = '//div[@class="lead"]/p/text()' XPATH_LINK_TO_BODY = '//div[@class="html-content"]/p[not(@class)]/text()' #ahora voy a crear las funciones de este programa #la funcion parse_home es la que se encarga de obtener #los links a las noticias: def parsed_notice(link, today): #envuelvo en un bloque try en caso de que el status_code de mi #peticion sea distinto a 200 try: response = requests.get(link)#solicito respusta al link de la noticia if response.status_code == 200: #primero quiero traer el documento html de la noticia notice = response.content.decode('utf-8') parsed = html.fromstring(notice)#lo convierto a un documento para aplicar xpath(un HTML con superpoderes) #el error contra el que me quiero proteger es si summary no tiene indices #es decir, no existe, en ese caso lo que quiero es salirme de la fucnion porque no #quiero noticias sin resumen try: #a estas variables pongo indices porque el resultado de aplicar xpath #a un html con superpoderes (parsed) nos devuleve una lista que puede tener uno a varios elementos #en este caso nosotros sabemos que el titulo, el resumen y el cuerpo #son el elemento 1 de una lista (index 0) title = parsed.xpath(XPATH_LINK_TO_TITLE)[0] #ahora voy a manejar el posible error de que el titulo tenga comillas #este link explica porque https://platzi.com/comentario/2198698/ title = title.replace('\"','') summary = parsed.xpath(XPATH_LINK_TO_SUMMARY)[0] #a body lo dejamos sin indice porque body es una lista de parrafos y quiero traerme la lista completa body = parsed.xpath(XPATH_LINK_TO_BODY) except IndexError: return #ahora vamos a guardar esta informacion. with es un gestor de contexto #es como un try bloc, en caso de que algo salga mal hace que el #archivo se cierre y no se corrampa. despues uso la funcion open para abrir archivo. Con esta fucnion #busco la carpeta que se creo con la fecha de hoy y dentro de esa carpeta #guardo un archivo que tiene como nombre el titulo de la noticia. #dentro de la funcion open el primer parametro nos indica la ruta del archivo, el segundo #nos dice que entramos en modo escritura, y el encoding nos permite guardar los caracteres especiales #de manera correcta para que no haya errores. Finalmente, nombro todo esto como # f with open(f'{today}/{title}.txt','w', encoding='utf-8') as f: f.write(title) f.write('\n\n') f.write(summary) f.write('\n\n') #necesito el for porque el body es una lista de parrafos for p in body: f.write(p) f.write('\n') else: raise ValueError(f'ERROR: {response.status_code}') except ValueError as ve: print(ve) def parse_home(): #sin embargo, tendo que proteger mi codigo en caso #de errores como el codigo 404 try: #con la funcion de request me traigo el archivo #HTML de la pagina response = requests.get(HOME_URL)#con esto no solo obtengo el documentos HTML sino tambien http, como las cabeceras if response.status_code == 200: home = response.content.decode('utf-8') #.content traer el archivo HTML y el .decode('utf-8') #me ayuda a convertir los caracteres raros (ñ, tildes) en algo que #python pueda entender parsed = html.fromstring(home) #toma el archivo html de home y lo convierte en un tipo de archivo #a partir del cual yo puedo hacer XPath #ahora lo que me falta es obtener una lista de los links #que obtenga que he obtenido hasta ahora links_to_notices = parsed.xpath(XPATH_LINK_TO_ARTICLE) #print(links_to_notices) today = datetime.date.today().strftime('%d-%m-%Y') #del modulo datetime traemos la funcion date y traemos #la fecha de hoy. Hasta esta parte guardamos un objeto #que nos da la fecha de hoy, pero lo que yo quiero es una string #que me de la fecha en el formato dia/mes/año, par ello uso #la funcion .strftime('%d-%m-%Y') #os.path.isdir(today) trae un booleano cuyo valor dependen de si hay #o no una carpeta con el nombre que hemos establecido (today) en la #carpeta en la que estamos. Si esa carpeta no existe creamos esa carpeta. isdir() method in Python is #used to check whether the specified path is an existing directory or not. if not os.path.isdir(today): #con esto creamos una carpeta con el nombre de la fecha de hoy si esa carpeta no existe os.mkdir(today) #por cada link en la lista vamos a entrar y extraer lo que queremos for link in links_to_notices: #esta funcion entra al link y extrae la infomacion que queremos #y eso lo va a guardar usando la fecha de hoy. parsed_notice(link, today) else: raise ValueError(f'ERROR: {response.status_code}') except ValueError as ve: print(ve) #la siguiente es la funcion principal, la que se va a ejecutar def run(): parse_home() if __name__ == '__main__': run()
    Jose David Ballesteros Paternina

    Jose David Ballesteros Paternina

    student•
    hace 5 años

    Tengo un problema al scrapear titulos que contengan simbolos como "¿?", lo que es raro ya que con el encoding UTF-8 arreglaria este tipo de problemas. El error es el siguiente:

    OSError: [Errno 22] Invalid argument: '19-03-2021/¿Los hombres son los que más compran vivienda nueva? Un estudio le aclara la duda.txt
      Jesús Eduardo Salgado Hernández

      Jesús Eduardo Salgado Hernández

      student•
      hace 4 años

      Hola, yo lo hice de esta manera, creando una función en donde use replace cada vez que encuentra un caracter especial:

      def delete_punctuation(sentence): for c in '?¿\"': sentence = sentence.replace(c, "") return sentence def parse_notice(link, today): try: response = requests.get(link) if response.status_code == 200: notice = response.content.decode('utf-8') parse = html.fromstring(notice) try: title = parse.xpath(xpath_title)[0] new_title = delete_punctuation(title) summary = parse.xpath(xpath_summary)[0] body = parse.xpath(xpath_body) except IndexError: return with open(f'{today}/{new_title}.txt', 'w', encoding='utf-8') as f: f.write(title) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve)
      Juan de Jesús Seco Arias

      Juan de Jesús Seco Arias

      student•
      hace 3 años

      Hola! a todos los que les salga este error, se soluciona incluyendo est linea inmediatamente debajo de la creación de la variable title:

      title= title.replace('\n', '').replace('“', '').replace('”', '')

    Joel Blanco

    Joel Blanco

    student•
    hace 4 años

    Lo que genera el cambio de h2 a text-fill és el decode.

    response.content.decode("utf-8")

    Si lo quitan no realitzarà cambios

    Yerson Alexander Arredondo García

    Yerson Alexander Arredondo García

    student•
    hace 5 años

    Les comparto mi código con la solución del ejercicio. Haciendo el análisis en la web, para sacar el titulo lo hice con //div[@class="mb-auto"]/h2/a/text(), pero la respuesta era diferente y tuve que usar //div[@class="mb-auto"]/text-fill/a/text()

    Vi en la sección de comentarios que también le paso a varios.

    import requests import lxml.html as html import os import datetime HOME_URL = 'https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE = '//div[@class="V_Title"]/a/@href' XPATH_TITLE = '//div[@class="mb-auto"]/text-fill/a/text()' XPATH_SUMMARY = '//div[@class="lead"]/p/text()' XPATH_BODY = '//div[@class="html-content"]/p[not(@class)]/text()' def parse_notice(link, today): try: response = requests.get(link) if response.status_code == 200: notice = response.content.decode('utf-8') parsed = html.fromstring(notice) try: title = parsed.xpath(XPATH_TITLE)[0] title = title.replace('\"', '') summary = parsed.xpath(XPATH_SUMMARY)[0] body = parsed.xpath(XPATH_BODY) except IndexError: return with open(f'{today}/{title}.txt', 'w', encoding='utf-8') as f: f.write(title) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') f.write('\n\n') f.write(f'Más información en: {link}') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def parse_home(): try: response = requests.get(HOME_URL) if response.status_code == 200: home = response.content.decode('utf-8') parsed = html.fromstring(home) link_to_notices = parsed.xpath(XPATH_LINK_TO_ARTICLE) # print(link_to_notices) today = datetime.date.today().strftime('%d-%m-%Y') if not os.path.isdir(today): os.mkdir(today) for link in link_to_notices: parse_notice(link, today) else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__ == '__main__': run()
      Aaron Fabrizio Calderon Guillermo

      Aaron Fabrizio Calderon Guillermo

      student•
      hace 5 años

      Genial! Funciona correctamente y con un solo cambio en el código.

    Alex Dario Portilla Chungandro

    Alex Dario Portilla Chungandro

    student•
    hace 5 años

    Por alguna razón mi codigo corre sin ningun error, pero al momento que me crea la carpeta que es donde se supone que se guardaran los archivos .txt estos no aparecen, la carpeta queda totalmente vacía. Alguien sabe como solucionarlo??. Les dejo mi codigo

    import requests import lxml.html as html import os import datetime HOME_URL = 'https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE = '//div/h2/a/@href' XPATH_TITLE = '//h2[@style="font-size: 49px; line-height: 53px;"]/a/text()' XPATH_SUMMARY = '//div[@class="lead"]/p/text()' XPATH_BODY = '//div[@class="autoArticle" or @class="html-content"]/p/text()' def parse_notice(link, today): try: response= requests.get(link) if response.status_code == 200: notice = response.content.decode('utf-8') parsed = html.fromstring(notice) try: title = parsed.xpath(XPATH_TITLE)[0] title = title.replace('\"','') summary = parsed.xpath(XPATH_SUMMARY)[0] body = parsed.xpath(XPATH_BODY) except IndexError: return with open(f'{today}/{title}.txt', 'w', encoding='utf-8') as f: f.write(title) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ver: print(ve) def parse_home(): try: response = requests.get(HOME_URL) if response.status_code == 200: home = response.content.decode('utf-8') parsed = html.fromstring(home) links_to_notices = parsed.xpath(XPATH_LINK_TO_ARTICLE) today = datetime.date.today().strftime('%d-%m-%Y') if not os.path.isdir(today): os.mkdir(today) for link in links_to_notices: parse_notice(link, today) else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__=="__main__": run()
      Massimo Di Berardino

      Massimo Di Berardino

      student•
      hace 5 años

      ¡Hola Alex! Validaste que el contenido de las variables title, summary y body esté llegando de manera correcta, puede ser que estas variables no estén tomando los valores y por eso no se escribe nada en el archivo.

      Alex Dario Portilla Chungandro

      Alex Dario Portilla Chungandro

      student•
      hace 5 años

      Hola si, yo tambien pense que ese podría ser el causante del porque no se guardan mis archivos, pero al revisar los xpath estos si me regresaban el texto, los verifique usando el .map(x => x.wholeText) para ver si realmente me regresaban el texto y efectivamente estos si me traen el texto que solcite.

    Helberts Andres Mosquera Clavijo

    Helberts Andres Mosquera Clavijo

    student•
    hace 4 años

    comence sacando noticias y el what if en mi cabeza se encendio y termine sacando todas las url de las paginas que ponia

    Alan Mariño

    Alan Mariño

    student•
    hace 3 años

    Los archivos no se pueden nombrar con caracteres como el ?, ¿ o el >, <, sin embargo, es posible que las noticias los tengan en sus títulos. Por esto se puede crear una simple solución con el mismo método que utiliza el profe cambiando las comillas por otros caracteres que nos interesen:

    title = title.replace('\"', '') title = title.replace('¿', '') title = title.replace('?', '')
      Anthony Campos

      Anthony Campos

      student•
      hace 3 años

      genial, con esta correción, triplqué mis archivos aprox a 30.

      = )

    Rene Rosas Villanueva

    Rene Rosas Villanueva

    student•
    hace 4 años

    Yo decidi hacer como ejercicio extraer la informacion de los libros de la tienda de toscrape(pagina que recomendo el profe facundo para practicar) con categoria "sequential art" extrae(titulo, precio, existencia y calificacion):

    import requests import lxml.html as html import os #BOOKS DATA XPATH_LINKS='//section/div/ol[@class="row"]/li/article[@class="product_pod"]/h3/a/@href' XPATH_TITLE='//section/div/ol[@class="row"]/li/article[@class="product_pod"]/h3/a/text()' XPATH_PRICE='//section/div/ol[@class="row"]/li/article[@class="product_pod"]/div[@class="product_price"]/p[@class="price_color"]/text()' XPATH_AVAILABILITY='//section/div/ol[@class="row"]/li/article[@class="product_pod"]/div[@class="product_price"]/p[@class="instock availability"]/text()' XPATH_RATE='//section/div/ol[@class="row"]/li/article[@class="product_pod"]/p/@class' URL='http // books toscrape com/catalogue/category/books/sequential-art_5/'#platzi me pidio romper el codigo URL_LIST= [] LINK_LIST=[] TITLE_LIST=[] PRICE_LIST=[] AVAILABILITY_LIST=[] RATE_LIST=[] #rate 1 to 5 def URL_PAGES(): for i in range(1,5): x=i y=(f'{URL}page-{x}.html') URL_LIST.append(y) def BOOK_INFO(): LINK=[] TITLE=[] PRICE=[] AVAILABILITY=[] RATE=[] for a in range(len(URL_LIST)): try: response=requests.get(URL_LIST[a]) if response.status_code == 200: home=response.content.decode('utf-8') parsed = html.fromstring(home) try: link= parsed.xpath(XPATH_LINKS) title= parsed.xpath(XPATH_TITLE) for i in range(len(title)): title[i]=title[i].replace('\"','') price= parsed.xpath(XPATH_PRICE) availability= parsed.xpath(XPATH_AVAILABILITY) for i in range(len(availability)): availability[i]=availability[i].strip('\n ') rate= parsed.xpath(XPATH_RATE) for i in range(len(rate)): rate[i]=rate[i].replace('star-rating ','') for x,n in enumerate(['One','Two','Three','Four','Five']): if rate[i]==n: rate[i]=x+1 except IndexError: return else: raise ValueError(response.status_code) except ValueError as ve: print(ve) LINK+=link TITLE+=title PRICE+=price AVAILABILITY+=availability RATE+=rate LINK_LIST.append(LINK) TITLE_LIST.append(TITLE) PRICE_LIST.append(PRICE) AVAILABILITY_LIST.append(AVAILABILITY) RATE_LIST.append(RATE) def run(): URL_PAGES() BOOK_INFO() print(TITLE_LIST[0][3]) print(PRICE_LIST[0][3]) print(AVAILABILITY_LIST[0][3]) print(RATE_LIST[0][3]) if __name__=='__main__': run()
    Geovany Uribe Aguirre

    Geovany Uribe Aguirre

    student•
    hace 5 años

    No me dejó correr el script, me aparece: UnboundLocalError: local variable 'title' referenced before assignment

      Saúl Alejandro Tapia Loya

      Saúl Alejandro Tapia Loya

      student•
      hace 5 años

      ¿Resolviste el problema? El error te está diciendo precisamente que estás accediendo a la variable "title" antes de que esta sea definida, puede ser que haya habido un error y se haya saltado la parte donde se definió.

    Luis Blas

    Luis Blas

    student•
    hace 4 años

    Les comparto como termine haciendo el reto. Cosas a considerar:

    • Como muchos otros notaron, en el XPath que usamos para extraer el titulo en Python, hay que cambiar el h2 por text-fill.

    • En el parse_home(), cuando extraigamos los links puede hayan algunos que estén repetidos. Por esto, usamos el links_to_notice = list(set(links_to_notice)) para quitar los duplicados de la lista. El set() transforma la lista en un conjunto donde todos sus elementos son diferentes, despues el list() lo vuelve a lista

    import requests import lxml.html as html import os import datetime HOME_URL = 'https://www.larepublica.co/' XPATH_LINK_TO_ARTICLE = '//div[@class="news V_Title_Img"]//a/@href' XPATH_TITLE = '//div[@class="mb-auto"]/text-fill/span/text()' XPATH_SUMMARY = '//div[@class="lead"]/p/text()' XPATH_BODY = '//div[@class="html-content"]/p/text()' def parse_notice(link,today): try: response = requests.get(link) if response.status_code == 200: notice = response.content.decode('utf-8') parsed = html.fromstring(notice) try: title = parsed.xpath(XPATH_TITLE)[0] title = title.replace('\"','') summary = parsed.xpath(XPATH_SUMMARY)[0] body = parsed.xpath(XPATH_BODY) except IndexError: print(IndexError) with open(f'{today}/{title}.txt', 'w', encoding='utf-8') as f: f.write(title) f.write('\n\n') f.write(summary) f.write('\n\n') for p in body: f.write(p) f.write('\n') else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def parse_home(): try: response = requests.get(HOME_URL) if response.status_code == 200: home = response.content.decode('utf-8') parsed = html.fromstring(home) links_to_notice = parsed.xpath(XPATH_LINK_TO_ARTICLE) # print(links_to_notice) links_to_notice = list(set(links_to_notice)) today = datetime.date.today().strftime('%d-%m-%Y') if not os.path.isdir(today): os.mkdir(f'{today}') for link in links_to_notice: parse_notice(link,today) else: raise ValueError(f'Error: {response.status_code}') except ValueError as ve: print(ve) def run(): parse_home() if __name__ == '__main__': run()

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads