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')
Scrapy, Tesseracts y Proxies
Introducción, definiciones y ética
Introducción y definiciones
Ética y Legalidad
Configuración del entorno de trabajo con Jupyter
HTML: Requests y BeautifulSoup
Descargando una página web
Parseando HTML con BeautifulSoup
Extrayendo información
Manejo de errores
Descargando contenido
Contenido multimedia
Unificando el scraper
Scraping JavaScript con Selenium
Instalación y configuración de Selenium
Sitios dinámicos y Selenium
Selección de elementos
Interactuando con los elementos
Scrapeando escalas y tarifas
Construyendo Funciones
Construyendo la función para unificar el scraper
Demoras dinámicas
Comentarios finales
APIs
Introducción a APIs
Utilizando APIs: Construir una URL
Utilizando APIs: Tokens y Búsqueda
Obteniendo la discografía
Obteniendo los albums
Fin del proyecto + bonus
Scrapy, Tesseract y Proxies
Scrapy
Ejecutando el scraper con scrapy
Proxies
Tesseract
Conclusión y cierre del curso
Crea una cuenta o inicia sesión
¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera
Martín Sokolowicz
Aportes 53
Preguntas 27
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?"
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
from bs4 import BeautifulSoup
s = BeautifulSoup(p12.text, 'lxml')
print(s.prettify())
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!!!
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')
Para quienes quieran profundizar en BeautifulSoup https://j2logo.com/python/web-scraping-con-python-guia-inicio-beautifulsoup/
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:
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
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?