Crea una cuenta o inicia sesión

¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera

Parseando HTML con BeautifulSoup

5/30
Recursos

Aportes 53

Preguntas 27

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Si a alguien le sale ouldn’t find a tree builder with the features you requested: lxml.
Pueden probar con:

s = BeautifulSoup(p12.text, 'html.parser')

este es el código que usé para extraer la lista

s.find('ul',attrs={'class':'horizontal-list main-sections hide-on-dropdown'}).find_all('li')

Una forma abreviada de usar el metodo find_all() es buscar con un parentesis despues de un objeto BeautifulSoup o Tag

Ejemplo

soup.find_all("a")
soup("a")

Otras maneras de expresar lo mismo

soup_p12.find(class_='hot-sections')('a')
soup_p12.find(class_='hot-sections').a
soup_p12.find(class_='hot-sections').find_all('a')

Si alguien se le presenta el error:

"Couldn't find a tree builder with the features you requested: %s. Do you need to install a parser library?"

Anaconda Navigator

Debes instalar el módulo de lxml. Lo puedes hacer instalándolo desde Anaconda Navigator o directamente a la versión de Python Environment que esta ejecutando jupyter.

Si es el entorno base (root):

~/anaconda3/bin/pip install lxml

Si es un determinado entorno.

~/anaconda3/envs/<environment_name>/bin/pip install lxml

Importante

Al crear un objeto de tipo beautifulsoup (o de cualquier otra biblioteca, librería, etc.) tenemos acceso a las funciones que contiene la biblioteca que importamos. ¿Dónde podemos encontrar todas estas funciones? en la documentación.

Imagínenlo como una caja de herramientas para algo en concreto. Es como decir me voy a traer mi caja de herramientas especial para cortar madera. Y dentro tenemos las herramientas especializadas para esta tarea

Agrego esta info porque me parece que esto no está muy claro para muchas personas que están empezando y creo que puede llegar a ser de ayuda para más de uno.

Por si se preguntan cómo hace los atajos en Jupyter e profesor, acá les comparto un enlace:
https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/

Actualizado tag y class:

s.find('ul', attrs = {'class': 'horizontal-list main-sections hide-on-dropdown'})

Cambió la página web. Aquí les dejo el código para obtener las secciones en una lista:

secciones = s.find('ul', attrs={'class':'horizontal-list main-sections hide-on-dropdown'}).find_all('li')

No se si Anaconda trae por defecto el parser ‘lxml’, en caso de que les salga este error “Couldn’t find a tree builder with the features you” para los que solo instalaron Jupyter y las librerías mediante pip deben instalar la parser library de ‘lxml’ con el siguiente comando:

pip install lxml

Hoy, en 2023, el ejercicio es similar, pero tengamos en cuenta lo siguiente:

Cambiar “hot-sections” por “horizontal-list main-sections hide-on-dropdown”

Como es de esperarse, el contenido de la página y el diseño cambia a lo largo del tiempo.

Para extraer información de una pagina web ya teniendo el link y habiéndola descargado

  1. Descargar bs4
from bs4 import BeautifulSoup
  1. Crear una variable con con el texto (html) de la pagina que deseamos scrappiar y lxlm para poder convertir esa información xdml en xpath
s =  BeautifulSoup(p12.text, 'lxml')
  1. ver en un forato mas organizado (opcional)
print(s.prettify())
  1. Se desea extraer la información de los headers del banner, con la función find traemos todos las llaves ul, para traer los atributos de esta usamos attrs y colocamos la clase a buscar, posteriormente usamos find de nuevo para traer el siguiente nodo
s.find('ul', attrs ={'class': 'horizontal-list main-sections hide-on-dropdown'}).find_all('li')

La expresión:

s .find('ul', attrs={'class':'hot-sections'}).find_all('li')

puede acortarse a simplemente esto:

s.find('ul', 'hot-sections').find_all('a')

y funciona de la misma manera.

Les dejo esta y todas las anotaciones del curso actualizados al 2023, tome nota de los comentarios y ejercicios resueltos de cada sección. Lleve en cuenta las explicaciones del docente y más! Espero les sirva. 👌
Anotaciones y Ejercicios Curso de Web Scraping - Modulo II
(si quieres apoyar deja una estrella a la repo ✌⭐)

La página cambió un poco desde la versión de la clase a hoy que hago el comentario:

Les comparto la ligera modificación de la sección en la que se encuentran las categorías:

s.find('ul', attrs={'class':'horizontal-list main-sections hide-on-dropdown'}).find_all('li')

Que buen curso!!!

En 2023 para en el minuto 6:50

Usa este código para encontrar el encabezado.

soup.find('nav', attrs={'id':'header-main-nav'})

Este es el código actual al 26 de enero de 2021:

s.find('ul', attrs={'class': 'horizontal-list main-sections hide-on-dropdown'}).find_all('li')

Beautiful Soup es una librería Python que permite extraer información de contenido en formato HTML o XML. Para usarla, es necesario especificar un parser, que es responsable de transformar un documento HTML o XML en un árbol complejo de objetos Python. Esto permite, por ejemplo, que podamos interactuar con los elementos de una página web como si estuviésemos utilizando las herramientas del desarrollador de un navegador.

!(

En mi caso usé Xpath para exrtaer los links con el siguiente código:

$x('//ul[@class="hot-sections"]/li/a/@href')

Lo ejecutan en la consola de su navegador favorito y obtendrán los enlaces de cada sección.

hola este el Código para extraer esa sección ya que ahora esta dentro de un div y dividido por <a>

s.find('div', attrs={'class':'p12-dropdown-column'}).find_all('a')

Mis notas de la clase.

#Clase #5

#Importamos BeautifulSoup
from bs4 import BeautifulSoup

#variable = funcionBeautifulSoup(p12, "funcionParser")
s = BeautifulSoup(p12.text, "lxml")

#Comprobamos tipo de s
type(s)

#Imprimir s con metodo prettify
#Prettify nos deja ver de manera jerarquica el DOM
print(s.prettify())

#Buscamos UL con el metodo find()
#BS devuelve el primer UL que encuentra
s.find("ul")

#Utilizar la clase actualizada
#horizontal-list main-sections hide-on-dropdown
s.find("ul", attrs={"class": "horizontal-list main-sections hide-on-dropdown"}).find_all("li")
#find_all() para traer todos los "li"

Ok. Asi me quedo.

s.find('ul', attrs={'class' : 'horizontal-list main-sections hide-on-dropdown'}).find_all('li')

Hola, el sitio ha cambiado desde el video y al dìa de hoy solo debemos encontrar la nueva clase, a mi me funciono:

s.find('ul',attrs={'class':'horizontal-list main-sections hide-on-dropdown'})

Mi resumen de la clase

excelente clase!! muy bueno el profe explicando!!

La estructura del periódico cambio, ahora es:

s.find('div', attrs={'class':'header-bottom-content mobile-menu'}).find_all('li')

Actualización 01/2021 funcionando- La estructura de la pagina ha variado
En mi caso yo lo hice con el titulo de “economía” y la class de la ul que lo contiene es ‘horizontal-list main-sections hide-on-dropdown’


s.find('ul')
s.find('ul', attrs={'horizontal-list main-sections hide-on-dropdown'})
s.find('ul', attrs={'class':'horizontal-list main-sections hide-on-dropdown'}).find_all('li')

Importamos la libreria

from bs4 import BeautifulSoup

Parser separa el texto largo en pedazos mas pequeños y mas fácil de identificar

s = BeautifulSoup(p12.text, 'lxml')
s = BeautifulSoup(p12.text, 'html.parser')

print (s.prettify())

#extraemos la clase
s.find('ul', attrs={'class':'main-sections'})

#especificamos todos los li
s.find('ul', attrs={'class':'main-sections'}).find_all('li')

#extraemos la etiqueta a
s.find('ul', 'main-sections').find_all('a')
🤨🤨

El resultado que obtengo cuando quiero obtener información de otra página:

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

Hubiera sido más completo con una página que requiera LOGIN y en ambos ejemplos uno con request y el otro con Selenium.

Actualmente la página ha cambiado su clase, hasta el 12/07/2021 el siguiente código es el que funciona

 s.find('ul', attrs={'class': 'horizontal-list main-sections hide-on-dropdown'})

s.find(‘ul’, attrs={‘class’:‘main-sections’})

Actualizando en el 2021 la url : https://www.pagina12.com.ar/secciones/el-pais

F12 para los que no sepan cómo obtener el inspector de elementos

El análisis de código HTML es un skill importante que todo desarrollador o programador debe dominar, para analizar HTML con Python podemos usar:

  1. El módulo html.parse que define la clase HTMLParser la cual sirve de base para el análisis de archivos de texto con formato en HTML y XHTML

2.Analizar HTML con la librería BeautifulSoup

En la configuración de la consola, pueden colocar el tema Dark para que no se les quemen los ojos

A mi me funcionó el siguiente comando teniendo en cuenta el cambio en el diseño de la página web

print(s.find('ul', attrs={'class':'horizontal-list main-sections hide-on-dropdown'}).find_all('a'))

Espero les sea útil

Wow

Esta es otra manera de hacerlo.

s.find(class_="hot-sections").find_all('li')

Para instalar la librería lxml con anaconda:

conda install lxml

A mí me resulta más fácil seleccionar la etiqueta como si estuviera seleccionando un elemento en CSS:

s.select('.hot-sections li')

No se si justo cambió el html del diario pero a mi me resultó con este código:

s.find('div', attrs={'class':'p12-dropdown-column'})
s.find('div', attrs={'class':'p12-dropdown-column'}).find_all('a')

Suerte!

Hola, estoy intentando hacer un scrapping de una pagina que requiere autenticacion, como es ese proceso?

alguien sabe por que emplea ‘lxml’ y no solo ‘html.parser’?

LA PÁGINA WEB SE RENOVÓ, así que creo que un reto mejor ahora es ENCONTRAR Escriben hoy.

Yo lo hice y obtuve esto:

s.find('ul')
#Regresa el primer valor que encuentra dentro de la estruutra de la pág.

<ul class="horizontal-list main-supplements"><li><span class="today">Hoy:</span></li><li class=""><a href="https://www.pagina12.com.ar/suplementos/libero">Líbero</a></li></ul>

Cómo este no es reulstado que desea uso attrs

s.find('ul',attrs={'class':'list column small-12'})
<ul class="list column small-12"><li><a href="/autores/74412-candela-gomes-diez">Candela Gomes Diez</a></li><li><a href="/autores/659-eduardo-aliverti">Eduardo Aliverti</a></li><li><a href="/autores/8445-elena-llorente">Elena Llorente</a></li><li><a href="/autores/831-federico-lisica">Federico Lisica</a></li><li><a href="/autores/272597-flor-de-la-v">Flor de la V</a></li><li><a href="/autores/227200-francisco-d-andrea">Francisco D'Andrea</a></li><li><a href="/autores/217531-guido-vassallo">Guido Vassallo</a></li><li><a href="/autores/845-gustavo-veiga">Gustavo Veiga</a></li><li><a href="/339380-alcira-profesora-y-diputada">Jorge Carpio y Horacio González</a></li><li><a href="/339322-se-amplian-las-restricciones-por-la-pandemia">Juan Giosa</a></li><li><a href="/autores/863-juan-jose-panno">Juan José Panno</a></li><li><a href="/autores/1998-julian-varsavsky">Julián Varsavsky</a></li><li><a href="/autores/872-laura-vales">Laura Vales</a></li><li><a href="/autores/1808-leandro-arteaga">Leandro Arteaga</a></li><li><a href="/339276-en-esta-noche-en-este-mundo">Lila M. Feldman</a></li><li><a href="/autores/217276-maira-lopez">Maira López</a></li><li><a href="/autores/237906-melisa-molina">Melisa Molina</a></li><li><a href="/autores/1856-mempo-giardinelli">Mempo Giardinelli</a></li><li><a href="/autores/217443-nicolas-hirtz">Nicolás Hirtz</a></li><li><a href="/autores/83836-pablo-amalfitano">Pablo Amalfitano</a></li><li><a href="/autores/287997-patricia-chaina">Patricia Chaina</a></li><li><a href="/autores/275187-pibas-con-pelotas">Pibas con Pelotas</a></li><li><a href="/autores/1239-raul-kollmann">Raúl Kollmann</a></li><li><a href="/339251-ella-tiembla">Sebastián Rogelio Ocampo</a></li><li><a href="/autores/5997-silvina-friera">Silvina Friera</a></li><li><a href="/autores/1243-victor-wolf">Victor Wolf</a></li><li><a href="/339262-que-hacer-para-controlar-la-inflacion">Victoria Giarrizzo y Nadia Schuffer</a></li><li><a href="/autores/335568-yemina-castellino">Yémina Castellino</a></li></ul>

Finalmete ordeno el contenido:

s.find('ul',attrs={'class':'list column small-12'}).find_all('li')

[<li><a href="/autores/74412-candela-gomes-diez">Candela Gomes Diez</a></li>,
 <li><a href="/autores/659-eduardo-aliverti">Eduardo Aliverti</a></li>,
 <li><a href="/autores/8445-elena-llorente">Elena Llorente</a></li>,
 <li><a href="/autores/831-federico-lisica">Federico Lisica</a></li>,
 <li><a href="/autores/272597-flor-de-la-v">Flor de la V</a></li>,
 <li><a href="/autores/227200-francisco-d-andrea">Francisco D'Andrea</a></li>,
 <li><a href="/autores/217531-guido-vassallo">Guido Vassallo</a></li>,
 <li><a href="/autores/845-gustavo-veiga">Gustavo Veiga</a></li>,
 <li><a href="/339380-alcira-profesora-y-diputada">Jorge Carpio y Horacio González</a></li>,
 <li><a href="/339322-se-amplian-las-restricciones-por-la-pandemia">Juan Giosa</a></li>,
 <li><a href="/autores/863-juan-jose-panno">Juan José Panno</a></li>,
 <li><a href="/autores/1998-julian-varsavsky">Julián Varsavsky</a></li>,
 <li><a href="/autores/872-laura-vales">Laura Vales</a></li>,
 <li><a href="/autores/1808-leandro-arteaga">Leandro Arteaga</a></li>,
 <li><a href="/339276-en-esta-noche-en-este-mundo">Lila M. Feldman</a></li>,
 <li><a href="/autores/217276-maira-lopez">Maira López</a></li>,
 <li><a href="/autores/237906-melisa-molina">Melisa Molina</a></li>,
 <li><a href="/autores/1856-mempo-giardinelli">Mempo Giardinelli</a></li>,
 <li><a href="/autores/217443-nicolas-hirtz">Nicolás Hirtz</a></li>,
 <li><a href="/autores/83836-pablo-amalfitano">Pablo Amalfitano</a></li>,
 <li><a href="/autores/287997-patricia-chaina">Patricia Chaina</a></li>,
 <li><a href="/autores/275187-pibas-con-pelotas">Pibas con Pelotas</a></li>,
 <li><a href="/autores/1239-raul-kollmann">Raúl Kollmann</a></li>,
 <li><a href="/339251-ella-tiembla">Sebastián Rogelio Ocampo</a></li>,
 <li><a href="/autores/5997-silvina-friera">Silvina Friera</a></li>,
 <li><a href="/autores/1243-victor-wolf">Victor Wolf</a></li>,
 <li><a href="/339262-que-hacer-para-controlar-la-inflacion">Victoria Giarrizzo y Nadia Schuffer</a></li>,
 <li><a href="/autores/335568-yemina-castellino">Yémina Castellino</a></li>]

ESPERO QUE LES SIRVA A LOS QUE NUEVOS 😄

A mí me funcionó:

s.find(‘div’, attrs = {‘class’: ‘p12-dropdown-pane’}).find_all(‘a’)

Código para encontrar las secciones (Hoy 20/3/2021)

url = "https://www.pagina12.com.ar"
p12 = requests.get(url)

dropdown_id = "p12-dropdown-desktop"
dropdown_content_class = "p12-dropdown-column"
links_item = "p12-dropdown-item"

soup = BeautifulSoup(p12.text, "html.parser")
dropdown = soup.find("div", attrs={"id": dropdown_id})
soup = BeautifulSoup(str(dropdown), "html.parser")
column = soup.find("div", attrs={"class": dropdown_content_class})
soup = BeautifulSoup(str(column), "html.parser")
sections = soup.find_all("a", attrs={"class": links_item})
sections = [section.text for section in sections]
sections

La página ha cambiado desde entonces, así me quedo a mi.

S.find('ul', attrs={'class':'main-sections'}).find_all('li')

no me funciona el .find all

Con Esc salen del “cell” del notebook, con b crean la nueva “celda” debajo de la que estan, con d+d eliminan esa celda, y con ctrl + enter ejecutan la linea (celda)

Hola, yo estoy trabajando con uan version de jupyter notebook online de binder por un problema de memoria que tengo en mi computadora. Alguien por causalidad ha intentado instalar BeautifulSoup4 en este ambiente? Gracias