Viendo este curso, siento que este debería ser primero que el de ingeniería de datos, porque acá, explican todo de forma muy detallada, en el otro me perdía demasiado porque el profe iba muy rápido.
el de ingeniería de datos para mi es mas avanzado
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
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Martín Sokolowicz
Aportes 50
Preguntas 4
Viendo este curso, siento que este debería ser primero que el de ingeniería de datos, porque acá, explican todo de forma muy detallada, en el otro me perdía demasiado porque el profe iba muy rápido.
el de ingeniería de datos para mi es mas avanzado
Como resolví el reto en la clase pasada sin darme cuenta, muestro como me quedó la sección de la función que extrae la imagen 😅
# Extraemos las imágenes
try:
media = s_nota.find('div', attrs={
'class': 'article-main-media-image'
}).find_all('img')
if len(media) == 0:
print('Media: vacío', '\n')
else:
image_link = media[-1].get('data-src')
# Descargamos la imagen
img_req = requests.get(image_link)
# Mostramos la imagen
from IPython.display import Image, display
print('Media:', '\n')
display(Image(img_req.content))
except:
print('Media: vacío', '\n')
Intenté no hacer tantas funciones para no perder el hilo
from IPython.display import Image
def obtener_contenido(url_nota):
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
try:
fecha = s_nota.find('span', attrs = {'pubdate':'pubdate'}).get('datetime')
volanta = s_nota.find('h2', attrs = {'class':'article-prefix'})
titulo = s_nota.find('h1', attrs = {'class':'article-title'})
copete = s_nota.find('div', attrs = {'class':'article-summary'})
cuerpo = s_nota.find('div', attrs = {'class':'article-text'})
autor = s_nota.find('div', attrs = {'class':'article-author'})
#Buscar imagen
media = s_nota.find('div', attrs={'class':'article-main-media-image'})
imagen = media.find_all('img')
imagen = imagen[-1]
img_req = requests.get(imagen.get('data-src'))
except Exception as e:
pass
print(fecha) if fecha != None else print("fecha no disponible")
print(volanta.text) if volanta != None else print("volanta no disponible")
print(titulo.text) if titulo != None else print("titulo no disponible")
print(copete.text) if copete != None else print("Copete no disponible")
print(cuerpo.text) if cuerpo != None else print("cuerpo no disponible")
print(autor.text) if autor != None else print("Autor no disponible")
if 'img_req' in locals(): return Image(img_req.content)
obtener_contenido(url_nota)```
Anotaciones y Ejercicios Curso de Web Scraping - Modulo II
Aquí 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. 👌
(si quieres apoyar deja una estrella a la repo ✌⭐)
def scrapper(url_nota):
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
# Extraemos el titulo
titulo = s_nota.find('h1', attrs={'class':'article-title'})
print(f"titulo: {titulo.text}")
print('\n')
# Extraer la fecha
fecha = s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
print(f"fecha: {fecha}")
print('\n')
# Extraer la volanta
volanta = s_nota.find('h2', attrs={'class':'article-prefix'})
print(f"volanta: {volanta.text}")
print('\n')
# Extraer copete
copete = s_nota.find('div', attrs={'class':'article-summary'})
print(f"copete: {copete.get_text()}")
print('\n')
# Extraer cuerpo
cuerpo = s_nota.find('div', attrs = {'class':'article-text'})
print(f"cuerpo: {cuerpo.get_text()}")
print('\n')
# Extraer autor
autor = s_nota.find('div', attrs = {'class':'article-author'})
if autor:
print(f"autor: {autor.get_text()}")
print('\n')
else:
print("no se encontró autor")
print('\n')
# Multimedia
media = s_nota.find('div', attrs={'class' : 'article-main-media-image'})
imagenes = media.find_all('img')
if not imagenes:
print('no se encontraron imágenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
img_req = requests.get(img_src)
display(Image(img_req.content))
except Exception as e:
print('\n')
print('----' *20)
print('Errores:')
print(e)
print('\n')
Ejemplo:
url_nota = 'https://www.pagina12.com.ar/284590-alberto-fernandez-en-el-199-aniversario-de-la-universidad-de'
scrapper(url_nota)
RETO
def _lector(url):
"""Lee la pagina web y mira si el servidor responde
ENTRADA
(str) url, la url de la página web
SALIDA
RETURN (BeautifulSoup) nota_s, ó
"""
nota = requests.get(url)
nota.enconding ='UTF-8'
if nota.status_code == 200:
print('Se entrado a la página')
nota_s = BeautifulSoup(nota.text, 'lxml')
return nota_s
else:
print('Fue rechazado')
def _titulo(nota_s, url):
"""Extrae el título del artículo
ENTRADA
(BeautifulSoup) nota_s, de la página web
(str) url, url de la página web
SALIDA
(str) return titulo.text """
print(f'Extrayendo titulo de {url}')
titulo = s_nota.find('h1', attrs = {'class':'article-title'})
if titulo:
print('se extrajo la titulo')
return titulo.text
else:
print('no se encontró el titulo')
return None
def _fecha(nota_s, url):
"""Extrae la fecha del artículo
ENTRADA
(BeautifulSoup) nota_s, de la página web
(str) url, url de la página web
SALIDA
(str) return fecha """
print(f'Extrayendo fecha de {url}')
fecha = s_nota.find('span', attrs={'pubdate': 'pubdate'}).get('datetime')
if fecha:
print('se extrajo la fecha')
return fecha
else:
print('no se encontró la fecha')
return None
def _volanta(nota_s, url):
print(f'Extrayendo la fecha de {url}')
volanta = s_nota.find('h2', attrs={'class':'article-prefix'})
if volanta:
print('se extrajo la volanta')
return volanta.text
else:
print('no se encontró la volanta')
return None
def _autor(nota_s, url):
"""Extrae el autor del autor
ENTRADA
(BeautifulSoup) nota_s, de la página web
(str) url, url de la página web
SALIDA
(str) return autor.text """
print(f'extrayendo el autor de {url}')
autor = s_nota.find('div', attrs={'class':'article-author'}).a
if autor:
print('se extrajo la autor')
return autor.text
else:
print('no se encontró el autor')
return None
def _copete(nota_s, url):
"""Extrae el copete del autor
ENTRADA
(BeautifulSoup) nota_s, de la página web
(str) url, url de la página web
SALIDA
(str) return copete.text """
print(f'Extrayendo el copete de {url}')
copete = s_nota.find('div', attrs={'class': 'article-summary'})
if copete:
print('se extrajo el copete')
return copete.text
else:
print('no se encontró el copete')
return None
def _texto_articulo(nota_s, url):
"""Extrae el texto del artículo
ENTRADA
(BeautifulSoup) nota_s, de la página web
(str) url, url de la página web
SALIDA
(str) return articulo_texto """
print(f'extrayendo el texto de {url}')
texto = s_nota.find('div', attrs={'class':'article-text'}).find_all('p')
if texto :
print('se extrajo el articulo')
articulo_texto = ''
for pedazo_texto in texto:
articulo_texto += pedazo_texto.text
return articulo_texto #str
else:
print('no se encontró el texto del artículo')
return None
def _imagen(nota_s, url):
"""Extrae la imagen del artículo
ENTRADA
(BeautifulSoup) nota_s, de la página web
(str) url, url de la página web
SALIDA
(bytes) imagen_req.content """
print(f'Extrayendo la imagen de {url}')
media = s_nota.find('div', attrs={'class' : 'article-main-media-image'})
imagenes = media.find_all('img')
if len(imagenes) == 0:
print('no se encontró')
return None
else :
print('se encontró la imagen')
imagen = imagenes[-1]
img_src = imagen.get('data-src')
imagen_req = requests.get(img_src)
return imagen_req.content # pixeles de la imagen
def scraper_articulo(url):
"""Escrapea la pagina web PG12,
ENTRADA:
(str) url, la url de la página web
SALIDA
(dict) cosas, los valores son lo que componen la página y los items son los componentes extraidos"""
cosas = {}
nota_s = _lector(url)
#exctraemos las cosas
titulo = _titulo(nota_s, url)
cosas['titulo'] = titulo
fecha = _fecha(nota_s, url)
cosas['fecha'] = fecha
volanta = _volanta(nota_s, url)
cosas['volanta'] = volanta
copete = _copete(nota_s, url)
cosas['copete'] = copete
autor = _autor(nota_s, url)
cosas['autor'] = autor
texto_articulo=_texto_articulo(nota_s, url)
cosas['aticulo'] = texto_articulo
imagen = _imagen(nota_s, url)
cosas['imagen'] = imagen
return cosas
def lector_imagen(imagen_pixel):
"""Leé las imagenes"""
if len(imagen_pixel) == 0:
print(f'no existe')
else:
return Image(imagen_pixel)```
import requests
from bs4 import BeautifulSoup
from IPython.display import Image
def getNotaInfo(url):
try:
nota = requests.get(url)
if (nota.status_code == 200):
s_nota = BeautifulSoup(nota.text, 'lxml')
article_titles = s_nota.find('div', attrs={'class': 'article-titles'})
#GET TITULO
if article_titles:
if article_titles.h1:
titulo = article_titles.h1.get_text()
print("Titulo: ")
print(titulo)
print("\n")
#GET FECHA
pubdate = s_nota.find('span', attrs={'pubdate': 'pubdate'})
if pubdate:
fecha = pubdate.get('datetime')
print("Fecha: ")
print(fecha)
print("\n")
#GET VOLANTA
if article_titles:
if article_titles.h2:
volanta = article_titles.h2.get_text()
print("Volanta: ")
print(volanta)
print("\n")
#GET COPETE
if article_titles:
if article_titles.find('div', attrs={'class': 'article-summary'}):
copete = article_titles.find('div', attrs={'class': 'article-summary'}).get_text()
print("Copete: ")
print(copete)
print("\n")
#GET CUERPO
article_text = s_nota.find('div', attrs={'class': 'article-text'})
if article_text:
cuerpo = article_text.get_text()
print("Cuerpo: ")
print(cuerpo)
print("\n")
#GET AUTOR
article_author = s_nota.find('div', attrs={'class': 'article-author'})
if article_author:
if article_author.find('a'):
autor = article_author.find('a').get_text()
print("Autor: ")
print(autor)
print("\n")
#GET IMAGENES
article_main_media_image = s_nota.find('div', attrs={'class': 'article-main-media-image'})
if article_main_media_image:
imagenes = article_main_media_image.find_all('img')
if len(imagenes) == 0:
print("No se encontraron imagenes")
else:
imagen = imagenes[-1].get('data-src')
r_imagen = requests.get(imagen)
if r_imagen.status_code == 200:
Image(r_imagen.content)
else:
print("Error al descargar la imagen")
except Exception as e:
print("Error")
print(e)
print("\n")
Me pareció que en una sola función quedaba bastante cargado (con lo de la imagen), entonces lo hice en 3 funciones
Este es el uso:
title, fecha, volanta, copete, cuerpo, autor, img_content = scrapear_nota(article_links[0])
Y estas las funciones:
Función principal
def scrapear_nota(link_nota):
try:
title=fecha=volanta=copete=cuerpo=autor=img_content=''
nota_req = requests.get(link_nota)
if nota_req.status_code == 200:
# https://k60.kn3.net/taringa/0/B/6/F/2/3/MoraCaceres/4F4.jpg -> Re pro
soup_nota = BeautifulSoup(nota.text, 'lxml')
title = soup_nota.find('div', attrs={'class': 'article-title'})
title = title.text if title else ''
fecha = soup_nota.find('span', attrs={'pubdate': 'pubdate'})
fecha = fecha.get('datetime') if fecha else ''
# Ahora con la volanta
volanta = soup_nota.find('div', attrs={'class': 'article-prefix'})
volanta = volanta.text if volanta else ''
# Ahora con el copete
copete = soup_nota.find('div', attrs={'class': 'article-summary'})
copete = copete.text if copete else ''
# Cuerpo
cuerpo = soup_nota.find('div', attrs={'class': 'article-text'})
cuerpo = cuerpo.text if cuerpo else ''
# Autor
autor = soup_nota.find('div', attrs={'class': 'article-author'})
autor = autor.a.text if autor and autor.a else ''
# Imagen
img_src = tomar_src_imagen(soup_nota)
if img_src != '':
img_content = tomar_imagen(img_src)
else:
print('Error: Status code:', nota_req.status_code)
except Exception as e:
print('Ha ocurrido un error en el Scraper')
print(e)
print('\n')
return title, fecha, volanta, copete, cuerpo, autor, img_content
Función que toma la src de la imagen
def tomar_src_imagen(soup_nota):
prefix = 'Tomar SRC'
print('Iniciando proceso con prefix: {}'.format(prefix))
img_src = ''
media = soup_nota.find('div', attrs={'class': 'article-main-media-image'})
imagenes = media.find_all('img')
if len(imagenes) > 0:
print('{}: Se está seleccionando la imágen más grande (la última)'.format(prefix))
imagen = imagenes[-1]
img_src = imagen.get('data-src')
print('{}: El enlace a la imagen que se ha seleccionado es: {}'.format(prefix, img_src))
else:
print('{}: No se han encontrado imágenes'.format(prefix))
return img_src
Función que toma el contenido de la imagen
def tomar_imagen(img_src):
prefix = 'Tomar Imagen: '
print ('{} Tomando imagen de {}'.format(prefix, img_src))
content = None
img_req = requests.get(img_src.r)
if img_req.status_code == 200:
print('{} Request exitoso'.format(prefix))
content = img_req.content
else:
print('{} Error\nStatus code: '.format(prefix))
print(img_req.status_code,'\n')
return content
¿Y como puedo usar esa imagen? La puedo descargar directo a mi ordenador? O subirla a una base de datos?
comparto mi solución al reto:
def parse_note(note):
try:
dic={}
noticia = requests.get(note)
if noticia.status_code == 200:
s_noticia = BeautifulSoup(noticia.text, 'lxml')
title = s_noticia.find('div', attrs= {'class':'col 2-col'}).h1.get_text()
#extraer la fecha del articulo
date = s_noticia.find('div', attrs = {'class':'date'}).find('span', attrs= {'class':'p12-separator--right--blue'}).text
#copete
copete = s_noticia.find('h2', attrs = {'class':'h3'}).get_text()
#Volante
volante = s_noticia.find('h2', attrs = {'class':'h4'}).get_text()
#cuerpo
cuerpo = s_noticia.find('div', attrs = {'class':'section-2-col article-main-content'}).find_all('p')
cuerpo_entero = [parrafo.get_text() for parrafo in cuerpo]
print(cuerpo_entero)
#autor
try:
author = s_nota.find('div', attrs = {'class': 'author-name'}).get_text()
print(author)
except:
print('no tiene autor')
media = s_noticia.find('figure', attrs ={'class':'object-fit-block--contain intrinsic-container intrinsic-container-3x2'})
imagen = media.img.get('src')
if len (imagen) ==0:
print('no se encontraron imagenes')
else:
img_req = requests.get(imagen)
imagen_decode = Image(img_req.content)
print(title)
print(date)
print(copete)
print(volante)
print(cuerpo_entero)
print(imagen_decode)
else:
raise ValueError(f'Error: {noticia.status_code}')
except ValueError as ve:
print(ve)
Esto recién lo aprendí del curso de Python Intermedio. Por buenas prácticas es mejor en vez de:
.
if len(imagenes) == 0:
.
Escribir:
.
if imagenes:
De esta manera se puede extraer la url de la imagen, actualmente
media = s_nota.find('div', attrs={'class':'image-wrapper'})
imagen = media.find('img')
img_src = imagen.get('data-src')
El profe Martín es de los pocos maestros que clase a clase te ayuda con los desafíos y sirve de complementario para el aprendizaje a veces la forma que uno piensa hacerlo no es la mas optima o para quienes no manejan bien los programas o están aprendiendo les dan una guía para que su aprendizaje sea mas óptimo en el futuro de los cursos espero hayan mas clases así
Función para extraer la información de una noticia, recibe como parámetro la URL:
# Función para scrapear una noticia
def News_scraper(link):
from IPython.display import Image
try:
nota = requests.get(link)
except Exception as e:
print('Error: ', e)
if nota.status_code == 200:
try:
s_nota = BeautifulSoup(nota.text, 'lxml')
print('Título: ')
# Extraer el título
titulo = s_nota.find('div', attrs={'class': 'col 2-col'}).h1.get_text()
print(titulo)
print('\n Autor: ')
# Extraer el autor de la noticia
autor = s_nota.find('div', attrs={'class':'author-name'}).get_text()
print(autor)
print('\n Fecha de publicación: ')
# Extraer la fecha
fecha = s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
print(fecha)
print('\n Copete: ')
# Extraer el copete o bajada
copete = s_nota.find('div', attrs={'class': 'col 2-col'}).h3.get_text()
print(copete)
print('\n Volanta: ')
# Extraer la volanta
volanta = s_nota.find('div', attrs={'class': 'col 2-col'}).h4.get_text()
print(volanta)
print('\n Cuerpo:')
# Extraer el cuerpo de la noticia
cuerpo = s_nota.find('div', attrs={'class': 'article-main-content article-text'}).find_all('p')
cuerpo_text = [parrafo.getText() for parrafo in cuerpo]
for parrafo in cuerpo_text:
print(parrafo)
print('\n')
imagenes = s_nota.find('div', attrs={'class': 'image-wrapper'}).find_all('img')
if len(imagenes) == 0:
print('No se encontraron imágenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
try:
img_req = requests.get(img_src)
if img_req.status_code == 200:
print('\n Imágen principal: \n')
return(Image(img_req.content))
else:
print('URL de la imágen no encontrada, error: ', img_req.status_code)
except Exception as e3:
print('Error: ', e3)
except Exception as e2:
print('Error: ', e2)
A quien le pueda servir
import requests
from bs4 import BeautifulSoup
from IPython.display import display, Image
url_Initial = "https://www.pagina12.com.ar/"
def Get_OptionsMenu(url):
try:
pag12 = requests.get(url)
# validamos estado
#print(pag12.status_code)
#print(pag12.text)
# devuelve bytes
#pag12.content
# Optenemos los encabezados
#pag12.headers
#Encabezado con el que sale la solicitud
#pag12.request.headers
#Saber el metodo con el que se hizo la solicitud
#pag12.request.method
#Saber a que pag se hizo la solicitud
#pag12.request.url
if(pag12.status_code == 200):
#Buscaremos la seccion de Deportes en el menu asi que parseamos la pag
s_Home = BeautifulSoup(pag12.text, 'lxml')
# vamos a buscar los li de cada opcion del menu
menu_list = s_Home.find('ul', attrs={'class': 'hot-sections'}).find_all('li')
return menu_list
else:
return []
except Exception as exp:
print("Get_OptionsMenu: " + exp)
print('\n')
return []
# definimos una funcion que sacara la url y el texto de cada opcion de menu
def OptionsMenu(section):
url_menu = section.a.get('href')
text_menu = section.a.get_text()
return {'url': url_menu, 'text': text_menu}
# definimos funcion que traera la informacion de los articulos por opcion de menu
def get_InfoArticlesBySecction(name):
try:
url_section = ''
# buscamos por seccion
for item in filter(lambda item: item['text'] == name , options_menu):
url_section = item['url']
section_articles = requests.get(url_section)
if(section_articles.status_code == 200):
s_article = BeautifulSoup(section_articles.text, 'lxml')
# articulo principal
feature_article_main = s_article.find('div', attrs={'class': 'featured-article__container'})
# Lista de articulos secundarios
feature_article_list = s_article.find('ul', attrs={'class': 'article-list'}).find_all('li')
# sacamos el titulo y la url de cada articulo incluido el principal
articles_list = [{'url':item.a.get('href'), 'Tittle': item.a.get_text()} for item in feature_article_list if item.a]
articles_list.append({'url':feature_article_main.a.get('href'), 'Tittle': feature_article_main.a.get_text()})
return articles_list
else:
print('no se logro hacer el request a ' + url_deports)
return []
except Exception as exp:
print("get_InfoArticlesBySecction: " + exp)
print('\n')
return []
def get_InfoArticle(url):
try:
r_article = requests.get(url)
if(r_article.status_code == 200):
s_article = BeautifulSoup(r_article.text, 'lxml')
# Extraemos informacion de cada Art¡culo
Header = s_article.find("h2", attrs={ "class": "article-prefix" })
Tittle = s_article.find("h1", attrs={ "class": "article-title" })
Descriptions = s_article.find("div", attrs={ "class": "article-text" }).find_all('p')
Author = s_article.find("div", attrs={ "class": "article-author" })
SubTittle = s_article.find("div", attrs={ "class": "article-summary" })
Date = s_article.find("span", attrs={"pubdate": "pubdate"}).get("datetime")
Images = s_article.find("div", attrs={"class": "article-main-media-image"}).find_all('img')
text_description = ""
for paragraph in Descriptions:
text_description += paragraph.get_text();
article = {
'Header': Header.get_text() if Header else "",
'Tittle': Tittle.get_text() if Tittle else "",
'SubTittle': SubTittle.get_text() if SubTittle else "",
'Author': Author.a.get_text() if Author else "",
'Descriptions': text_description,
'Date': Date,
'UrlImage': Images[0].get("data-src") if len(Images) > 0 else ""
}
return article
else:
print('no se logro hacer el request a ' + url)
return []
except Exception as exp:
print("get_InfoArticle: " + exp)
print('\n')
return []
def DownLoadImage(url_image):
try:
r_image = requests.get(url_image)
if(r_image.status_code == 200):
#Visualizamos la imagen
Image(r_image.content)
#Guardamos la imagen
with open("Photo.png", "wb") as png:
png.write(r_image.content)
else:
print('no se logro hacer el request a ' + url_image)
except Exception as exp:
print("DownLoadImage: " + exp)
print('\n')
menu_list = Get_OptionsMenu(url_Initial)
# llenamos una lista con cada opcion de menu con su url y texto
options_menu = [OptionsMenu(section) for section in menu_list]
articles = get_InfoArticlesBySecction('Deportes')
listInfo = [get_InfoArticle(article["url"]) for article in articles]
# descargamos una imagen
DownLoadImage(listInfo[1]["UrlImage"])
media = s_nota.find('div', attrs={'class':'article-main-media-image__container'})
media
# %%
imagen = media.find('img')
imagen
# %%
img_src = imagen.get('src')
img_src
# %%
img_req = requests.get(img_src)
img_req.status_code
# %%
from IPython.display import Image
# %%
Image(img_req.content)
def display_image_from_soup(soup):
try:
# Obtener el elemento <div> con clase "article-main-media-image__container"
media = soup.find('div', attrs={'class': 'article-main-media-image__container'})
# Obtener el elemento <img> dentro del <div>
imagen = media.find('img')
# Obtener la URL de la imagen desde el atributo "src"
img_src = imagen.get('src')
# Realizar la solicitud HTTP para obtener la imagen
img_req = requests.get(img_src)
img_req.raise_for_status() # Verificar si hay errores en la solicitud
# Mostrar la imagen utilizando IPython.display.Image
img = Image(img_req.content)
display(img)
except requests.exceptions.HTTPError as e:
print(f"Error de solicitud HTTP: {e}")
except Exception as e:
print(f"Error: {e}")
# Ejemplo de uso:
# Supongamos que "s_nota" es el objeto Beautiful Soup de la página que contiene la imagen
display_image_from_soup(s_nota)
Me parecio como magia descargar el contenido de la imagen y luego con la libreria convertirlo de nuevo en imagen.
Uniendo todo lo aprendido y evitando todos los errores posibles que detengan mi función
#Importacion de Librerias
import requests
from bs4 import BeautifulSoup
from IPython.display import Image #Funcion necesaria para visualizar imagenes
#Funciones
def GetDataNews(url):
try:
page = requests.get(url)
if(page.status_code == 200):
soup = BeautifulSoup(page.text,'lxml')
#Extraer Titulo
titulo=''
try:
titulo = soup.find('div',{'class','col 2-col'}).h1.get_text()
except:
pass
#Extraer Fecha
fecha=''
try:
fecha=soup.find('div',{'class','date modification-date'}).time.get('datetime')
except:
pass
#Extraer Copete
copete=''
try:
copete=soup.find('div',{'class','article-main-content article-text'}).find_all('b')[0].get_text()
except:
pass
#Extraer Volanta
volanta=''
try:
volanta=soup.find('div',{'class','col 2-col'}).h4.get_text()
except:
pass
#Extraer Cuerpo
cuerpo=''
try:
cuerpo=soup.find('div',{'class','article-main-content article-text'}).find_all('p')
#print(cuerpo)3
contenido=''
for parrafo in cuerpo:
contenido= contenido + parrafo.get_text()
except:
pass
#Extraer Autor
autor=''
try:
autor=soup.find('div',{'class','author-name'}).get_text()
except:
pass
#Extraer Imagen
imagen=''
try:
imagenes=soup.find('figure',{'class','object-fit-block--contain intrinsic-container intrinsic-container-3x2'}).find_all('img')
if(len(imagenes)==0): #Verificar que se haya encontrado por lo menos una imagen
print('No se encontraron imagenes')
else:
urlImagen=imagenes[-1].get('src') #Extraemos el link o url de la imagen
imagen = requests.get(urlImagen) #descargamos la imagen comouna pagina cualquiera con el url que obtuvimos
except:
pass
except Exception as e:
print('error')
print(e)
print('\n')
return([titulo,fecha,copete,volanta,cuerpo,autor,imagen])
#Variables
AllNews=[]
AllLinks=['https://www.pagina12.com.ar/441054-cristina-kirchner-compartio-un-mensaje-despues-de-reunirse-c',
'https://www.pagina12.com.ar/441008-antes-y-ahora-en-las-investigaciones-por-los-atentados-a-la-',
'https://www.pagina12.com.ar/440906-primer-ministro-de-facto-un-diseno-sin-precedentes']
#Extraccion de datos para cada URL
for url in AllLinks:
AllNews.append(GetDataNews(url))
#Todos los Datos Extraidos
AllNews
Reto
def get_content_resources(url):
from IPython.display import Image
#Funcion que imprime la imagen
def print_image(src):
if src.status_code == 200:
return Image(src.content)
try:
articulo = requests.get(url_art)
if articulo.status_code == 200:
soup_articulo = BeautifulSoup(articulo.text,'lxml')
#Extraer el titulo
titulo = soup_articulo.find('h1')
print(titulo.text)
#Extraer fecha
fecha = soup_articulo.find('div',attrs={'class': 'date'}).find('span')
print(fecha.text)
#Extraer volanta
volanta = soup_articulo.find('h4')
print(volanta.text)
#ExtraerImagen
media = soup_articulo.find('div',attrs={'class','article-main-media-image__container'}).find('img')
if media:
img = media.get('src')
img_request = requests.get(img)
else:
return
return print_image(img_request)
except Exception as e:
print('Error:')
print(e)
print('\n')
url_base = 'https://www.pagina12.com.ar'
url_art = url_base + get_links(soup)[0]
get_content_resources(url_art)
Comparto mi solución
try:
nota=requests.get(url_nota)
if nota.status_code == 200:
s_nota= BeautifulSoup(nota.text, 'lxml')
#Extraer el titulo
titulo= s_nota.find('div', attrs={'class': 'col 2-col'}).find('h1')
#titulo= titulo_div.find('h1')
print(titulo.text)
#extraer la fecha del articulo
fecha= s_nota.find('div', attrs={'class': 'date modification-date'}).span.time.get('datetime')
print(fecha)
#extrar volanta o encabezado
encabezado= s_nota.find('div', attrs={'class': 'col 2-col'}).find('h4')
print(encabezado.text)
#extraer copete o bajada
copete = s_nota.find('div', attrs={'class': 'col 2-col'}).find('h3')
print('\n')
print(copete.text)
#extraer el autor
print('\n')
Autor = s_nota.find('div', attrs={'class': 'author-name'})
print(Autor.text)
#extraer cuerpo
print('\n')
cuerpo = s_nota.find('div', attrs= {'class': 'article-main-content article-text'}).find_all('p')
body_text= ""
if cuerpo:
for p in cuerpo:
body_text= body_text+ p.text
print(body_text)
except Exception as e:
print('Error:')
print(e)
print('\n')
Reto completado el 29 de noviembre del 2021:
def scrapper_article(url_nota):
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
# Extraer volanta:
volanta= s_nota.find('div', attrs={'class':'col 2-col'})
print(volanta.h4.text)
# Extraer el titulo
titulo = s_nota.find('div', attrs={'class':'col 2-col'})
print(titulo.h1.text)
# Extraer copete:
copete = s_nota.find('div', attrs={'class':'col 2-col'})
print(copete.h3.text)
# Extraer autor:
autor = s_nota.find('div', attrs={'class':'author-name'})
print(autor.text)
# Extraer imagen:
media = s_nota.find('figure', attrs={'class':'object-fit-block--contain intrinsic-container intrinsic-container-3x2'})
img_src = media.img.get('src')
print(img_src)
# Extraer la fecha
fecha = s_nota.find('time').get('datetime')
print(fecha)
# Extraer el cuerpo:
cuerpo = s_nota.find('div', attrs={'class':'article-main-content article-text'})
print(cuerpo.text)
except Exception as e:
print('Error:')
print(e)
print('\n')
Que laptop usa el profesor? Es para una tarea
excelente…
Mi codigo del reto de la clase pasada.
import requests
from bs4 import BeautifulSoup
# El reto consiste en descargar el Autor, la volanta, el copete y el cuerpo.
def run():
url = 'https://www.pagina12.com.ar/237350-murio-el-dirigente-radical-leandro-despouy'
page = requests.get(url)
soup = BeautifulSoup(page.text, 'lxml')
try:
if page.status_code == 200:
soup.find('div', attrs = {'class': 'article-prefix'})
volanta = soup.find('div', attrs = {'class': 'article-prefix'}).get_text()
autor = soup.find('span', attrs = {'class': 'tag-name'}).get_text()
copete = soup.find('div', attrs = {'class': 'article-text'}).find_all('p')
copete2 = copete[0]
cuerpo = soup.find('div', attrs = {'class': 'article-text'}).find_all('p')
cuerpo2 = cuerpo[1]
print('''Contenido de Volanta: {}
Contenido del Autor: {}
Contenido del Copete: {}
Contenido del Cuerpo: {}'''
.format(volanta, autor, copete2.get_text(), cuerpo2.get_text()))
except Exception as e:
print('Error en ejecucion: ', e)
if __name__ == "__main__":
run()```
def get_infor(pag):
##retorna la imagen
try:
nota = requests.get(pag)
if nota.status_code==200:
s_nota=BeautifulSoup(nota.text,'lxml')
#extraemos el titulo
titulo = s_nota.find('h1', attrs={'class':'article-title'})
print(titulo.text)
print('\n')
#extraer la fecha
fecha= s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
print(fecha)
#extraer volante
volante = s_nota.find('h2',attrs={'class':'article-prefix'})
print(volante.text)
print('\n')
#Extraer copete
try:
copete = s_nota.find('div', attrs={'class':'article-summary'})
print(copete.text)
except:
pass
#cuerpo
cuerpo=s_nota.find('div',attrs={'class':'article-text'})
print('\n')
print(cuerpo.text)
#Imagen
media = s_nota.find('div', attrs={'class':'article-main-media-image'})
imagenes=media.find_all('img')
if len(imagenes)==0:
print('no se encontraron imagenes')
print('\n')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
try:
img_req = requests.get(img_src)
except:
print('imagen no encontrada')
print('\n')
img = Image(img_req.content)
return(img)
except Exception as e:
print('error')
print(e)
print('\n')
```
def get_image_content(media):
"""
Return image content from media
"""
imagenes = media.find_all('img')
if len(imagenes) == 0:
raise Exception('No se encontraron imágenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
img_req = requests.get(img_src)
if img_req.status_code == 200:
return img_req.content
else:
raise Exception('No se pudo descargar la imágen')
from IPython.display import Image, display
def info_nota(url_nota):
"""
Extrae información de la nota.
"""
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'html.parser')
# Extraenos el título
titulo = s_nota.find('h1', attrs={'class':'article-title'})
print(color.BOLD + 'Título: ' + color.END + titulo.text)
# Extraer la fecha
fecha = s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
print('Fecha: ' + fecha)
# Extraer volanta
volanta = s_nota.find('h2', attrs={'class':'article-prefix'})
print('Volanta: ' + volanta.text)
# Extraer imagen
media = s_nota.find('div', attrs={'class':'article-main-media-image'})
imagen = get_image_content(media)
print('Imagen: \n')
display(Image(imagen))
else:
raise Exception('No se pudo acceder a la nota.')
except Exception as e:
print('Error:')
print(e)
print('\n')
Desafío:
import requests
from bs4 import BeautifulSoup
from pprint import pprint as pp
def make_safe_request(url, method='GET', get_soup=True):
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}
try:
if method == 'GET':
resp = requests.get(url, headers=headers)
elif method == 'HEAD':
resp = requests.head(url, headers=headers)
else:
print(f'Error en "method" de Request: {method}')
return None
if resp.status_code == 200:
if get_soup:
return BeautifulSoup(resp.text, 'lxml')
else: return resp
else:
print(f'Error en "status_code" de Request: {resp.status_code}')
return None
except Exception as e:
print('Error en Request:')
print(e)
return None
def image_from_url_is_valid(url):
resp = make_safe_request(url, method='HEAD', get_soup=False)
if resp is None: return False
else:
headers = resp.headers
content_type = headers.get('Content-Type', '')
return 'image' in content_type
def get_safe_data(item, get='get_text', default=''):
if item:
if get == 'get_text': return item.get_text()
else: return item.get(get, default)
return default
def get_safe_item(soup, css_select, get='get_text', default=''):
temp = soup.select_one(css_select)
return get_safe_data(temp, get, default)
def get_safe_items(soup, css_select, idx=None, get='get_text', default=''):
temp = soup.select(css_select)
if temp:
n = len(temp)
if idx is not None and idx < n:
return get_safe_data(temp[idx], get, default)
else:
return [get_safe_data(subitem, get, default) for subitem in temp]
else:
if idx is not None: return ''
else: return []
def get_content_from_article(url):
data = {'title': '', 'subtitle': '', 'author': '', 'url': '', 'image': '', 'date': '', 'content': ''}
soup = make_safe_request(url)
if soup is None: return data
data['url'] = url
data['title'] = get_safe_item(soup, '.article-title')
data['subtitle'] = get_safe_item(soup, '.article-prefix')
data['author'] = get_safe_item(soup, '.article-author .no-link')
image = get_safe_items(soup, '.article-main-media-image img', idx=-1, get='data-src')
data['image'] = image if image_from_url_is_valid(image) else ''
data['date'] = get_safe_item(soup, '.time span', get='datetime')
content = get_safe_items(soup, '.article-text p')
data['content'] = ' '.join(content)
return data
def main():
data = get_content_from_article('https://www.pagina12.com.ar/255892-estado-presente-y-responsabilidad-ciudadana')
pp(data)
if __name__ == '__main__':
main()
Reto
import requests
from bs4 import BeautifulSoup
from IPython.display import Image
def response(url):
pagina = requests.get(url)
return pagina.text
def parsear(url_texto):
sopa_pagina = BeautifulSoup(url_texto, 'html.parser')
return sopa_pagina
def secciones(url_parser):
secciones = url_parser.select('.hot-sections a')
links = {seccion['href']: seccion.get_text() for seccion in secciones}
return links
def main():
url = 'https://www.pagina12.com.ar/'
p12 = response(url)
s_p12 = parsear(p12)
ligas_secciones = secciones(s_p12)
return ligas_secciones
def links_de_secciones(seccion):
articulos_de_seccion = {} #Creamos un diccionario donde nos almacenara los articulos de nuestra seccion dada
seccion_req = response(seccion) #Hecemos la solicitud a la pagina
sopa_seccion = parsear(seccion_req) #Parseamos la pagina
promocionado = sopa_seccion.select('.featured-article__container a') #Obtenemos el conteneder de nuestro promocional
articulos_de_seccion[promocionado[0]['href']] = promocionado[1].get_text() # Agregamos el promocional al diccionario
extractos = (sopa_seccion.select('.article-list h2 a'))
articulos ={extracto['href']: extracto.get_text() for extracto in extractos}
for llaves, valores in articulos.items():
articulos_de_seccion[llaves] = valores
return articulos_de_seccion
def encontrar_link(n, diccionario):
contador = 0
for keys in diccionario.keys():
if contador == n:
resultado = keys
break
else:
contador += 1
return resultado
def eleccion(diccionario):
n = 0
for i in diccionario.keys():
print('[', n , '] ', diccionario[i])
n += 1
def extraer(url_nota):
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
sopa_nota = BeautifulSoup(nota.text, 'html.parser')
#Extraer el titulo
titulo = sopa_nota.find('h1', attrs = {'class': 'article-title'})
print(titulo.text) # y Obtenemos el titulo
print('')
#Extraer la fecha
fecha = sopa_nota.find('span', attrs = {'pubdate': 'pubdate'}).get('datetime')
print(fecha)
print('')
#Extraer Volanta
volanta = sopa_nota.find('h2', attrs ={'class': 'article-prefix'})
print(volanta.text)
print('')
#Copete
#copete = sopa_nota.find('div', attrs ={'class': 'article-summary'}).text
#print(copete)
#print('')
#Cuerpo
cuerpo = sopa_nota.find('div', attrs = {'class': 'article-body diario'}).find_all('p')
c = ''
for parrafo in cuerpo:
c = c + parrafo.text
print(c)
print('')
#Author
#autor = sopa_nota.find('div', attrs = {'class': 'article-author'}).a.text
#print('Por {}'.format(autor))
#Imagen
media = sopa_nota.find('div', attrs = {'class': 'article-main-media-image'})
imagenes = media.find_all('img')
if len(imagenes) == 0:
print('No se encontraron imagenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
print(img_src)
img_req = requests.get(img_src)
return img_req.content
except Exception as e:
print('Error')
print(e)
print('\n')
if __name__ == "__main__":
print('Iniciando Scrapping')
temas = main()
eleccion(temas)
n_seccion = int(input('Escoge la seccion para extraer sus articulos: '))
print('\n')
seccion = encontrar_link(n_seccion, temas)
articulos = links_de_secciones(seccion)
eleccion(articulos)
n_seccion = int(input('Escoge el articulo a extraer: '))
print('\n')
articulo = encontrar_link(n_seccion, articulos)
imagen = extraer(articulo)
Reto:
import requests
from bs4 import BeautifulSoup
from IPython.display import Image
class Web:
def obtener_noticias(self,url,p12):
global links_secciones
try:
if p12.status_code == 200:
#Cabecera de las distintas fuentes de noticias
s = BeautifulSoup(p12.text, 'lxml')
secciones = s.find('ul', attrs={'class':'hot-sections'}).find_all('li')
seccion = secciones[0]
seccion_links = [seccion.find('a').get_text() for seccion in secciones]
print('\nCabecera\n',seccion_links)
#Enlaces de las noticias
if seccion.a.get('href'):
links_secciones = [seccion.a.get('href') for seccion in secciones]
print('\nEnlaces de las noticias\n',links_secciones)
self.obtener_notas()
except Exception as e:
print('Error en:\n',e)
def obtener_notas(self):
global lista_notas
try:
sec = requests.get(links_secciones[0])
s_seccion = BeautifulSoup(sec.text, 'lxml')
if sec.status_code == 200:
lista_notas = []
# Obtengo el artículo promocionado
featured_article = s_seccion.find('div', attrs={'class':'featured-article__container'})
if featured_article:
lista_notas.append(featured_article.a.get('href'))
# Obtengo el listado de artículos
article_list = s_seccion.find('ul', attrs={'class':'article-list'})
for article in article_list.find_all('li'):
if article.a:
lista_notas.append(article.a.get('href'))
print('\nLista de las notas\n',lista_notas)
self.descripcion_notas()
except Exception as e:
print('Error en obtener datos en:\n',e)
def descripcion_notas(self):
global s_nota
url_nota = lista_notas[0]
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
# Extraemos el titulo
titulo = s_nota.find('div', attrs={'class':'article-title'})
# Extraer la fecha
fecha = s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
print('\nTiutlo y fecha de la nota:\n',titulo.text,'\n',fecha)
self.imagene_nota()
except Exception as e:
print('Error obteniendo descripción en:\n',e)
def imagene_nota(self):
try:
media = s_nota.find('div', attrs={'class':'article-main-media-image'})
imagenes = media.find_all('img')
imagenes
if len(imagenes) == 0:
print('no se encontraron imágenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
#print(img_src)
img_req = requests.get(img_src)
print('\n Imagen es :\n')
Image(img_req.content)
except Exception as e:
print('Error en obtener la imagen en:\n',e)
if __name__ == '__main__':
url = 'https://www.pagina12.com.ar/'
p12 = requests.get(url)
web = Web()
web.obtener_noticias(url,p12)
alguien lo ha intentado con otra pagina ? yo lo estoy haciendo con ‘el pais’ pero ya en este reto me sale un error :
Error:
Invalid URL ‘/internacional/2020-05-08/la-pandemia-se-torna-en-el-mayor-adversario-de-putin.html’: No schema supplied. Perhaps you meant http:///internacional/2020-05-08/la-pandemia-se-torna-en-el-mayor-adversario-de-putin.html?
y ya no se que hacer :c
no me deja extraer solo texto del titulo
Genial
def pagina(url):
try:
nota = requests.get(url)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
#extraer el titulo
titulo = s_nota.find('div', attrs = {'class' : 'article-title'})
print('TITULO\n')
print(titulo.text)
#extraer la fecha
fecha = s_nota.find('span', attrs = {'pubdate' : 'pubdate'}).get('datetime')
print('FECHA\n')
print(fecha)
#extraer volanta
encabezado = s_nota.find('h2', attrs = {'class' : 'article-prefix'})
print('VOLANTA\n')
print(encabezado.text)
#extraer copete
copete = s_nota.find('div', attrs = {'class' : 'article-summary'})
print('COPETE\n')
print(copete.text)
#extraer cuerpo
cuerpo = s_nota.find('div', attrs = {'class' : 'article-text'})
print('CUERPO\n')
print(cuerpo.text)
#extraer epigrafe
epigrafe = s_nota.find('span', attrs = {'class' : 'article-main-media-text-image'})
print('EPIGRAFE\n')
print(epigrafe.text)
#autor
autor = s_nota.find('span', attrs = {'class':'article-author'})
print('AUTOR\n')
print(autor)
#imagen
imagenes = s_nota.find('div', attrs = {'class':'article-main-media-image'}).find_all('img')
if len(imagenes)==0:
print('no se encontraron imagenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
print('IMAGEN\n')
print(img_src)
except Exception as e:
print('error: ')
print(e)
print('\n')
if __name__ == ('__main__'):
url = input('Ingrese el url: ')
pagina(url)```
def get_article(s_nota):
try:
result_dict = {}
# Extraer el título
title = s_nota.find('div', {'class' : 'article-title'})
title = title.text
# La fecha
result_dict['date'] = s_nota.find('span', {'pubdate' : 'pubdate'}).get('datetime')
# Summary
result_dict['summary'] = s_nota.find('div', {'class' : 'article-summary'}).text
# Author
result_dict['author'] = s_nota.find('div', {'class' : 'article-author'}).a.text
# Body
result_dict['body'] = s_nota.find('div', {'class' : 'article-text'}).text
#Image
images_container = s_nota.find('div', attrs={'class' : 'article-main-media-image__container'})
if images_container:
images = images_container.find_all('img')
image_link = (images[-1]['data-src'])
result_dict['img_req'] = requests.get(image_link).content
return result_dict
except Exception as e:
print(e)
return None
Aquí mi prototipo de scraper:
import requests as r
from bs4 import BeautifulSoup
PAGE_URL = 'https://www.pagina12.com.ar/secciones/ciencia'
def getting_the_soup(URL):
"""This function returns a BeautifulSoup
object from the URL given as an input."""
try:
p12_science = r.get(URL)
if p12_science.status_code == 200:
print(f'\nStatus Code: {p12_science.status_code}\n')
science_section = BeautifulSoup(p12_science.text, 'lxml')
else:
print(f'Failed Request! \nStatus Code: {p12_science.status_code}\n')
except ValueError as ve:
print(ve)
return science_section
def getting_links(soup):
"""This function gets as input a BeautifulSoup object
in order to process it and extract links from it."""
try:
featured_article = [soup.find('div', attrs={'class':'featured-article__container'}).a.get('href')]
pre_article_list = soup.find('ul', attrs={'class':'article-list'}).find_all('h2')
article_list = [article_list.a.get('href') for article_list in pre_article_list]
except AttributeError as ae:
print(ae)
return featured_article + article_list
def get_text(post_url):
"""This function extracts the text type
content of the input URL"""
try:
post = r.get(post_url)
if post.status_code == 200:
post_soup = BeautifulSoup(post.text, 'lxml')
title = post_soup.find('div', attrs={'class', 'article-titles'}).find('h1', attrs={'class':'article-title'})
date = post_soup.find('div', attrs={'class':'time'}).span.get('datetime')
try:
volanta = post_soup.find('div', attrs={'class', 'article-titles'}).find('h2', attrs={'class':'article-prefix'})
except:
print('Volanta: None')
body = post_soup.find('div', attrs={'class':'article-text'})
try:
author = post_soup.find('div', attrs={'class':'article-author'})
except:
print('Author: Anonymous')
except Exception as e:
print(f'\nError: {e}\n')
return title, date, volanta, body, author
def get_media(post_url):
try:
post = r.get(post_url)
if post.status_code == 200:
post_soup = BeautifulSoup(post.text, 'lxml')
mediag = post_soup.find('div', {'class':'article-main-media-image'})
media_img = mediag.find_all('img')
if len(media_img) == 0:
return 'No images found'
else:
image = media_img[-1]
img_src = image.get('data-src')
img_req = r.get(img_src)
image_content = img_req.content
except:
print('No images found')
return image_content
def print_results(date, author, volanta, title, body, links, image):
#Print results
show = [print(link) for link in links]
print('\n',date, '\n')
print(author.text, '\n')
print(volanta.text, '\n')
print(title.text, '\n')
print('\n', body.text)
def run():
science_section = getting_the_soup(PAGE_URL)
links = getting_links(science_section)
post_url = links[0]
title, date, volanta, body, author = get_text(post_url)
image = get_media(post_url)
print_results(date, author, volanta, title, body, links, image)
if __name__ == "__main__":
run()
Este es mi código:
import re
is_well_formed_link = re.compile(r'^https?://.+/.+$')
is_root_path = re.compile(r'^/.+$')
host = 'https://www.pagina12.com.ar/'
def _build_link(host, link):
if is_well_formed_link.match(link):
return link
if is_root_path.match(link):
return '{}{}'.format(host, link)
return '{}/{}'.format(host, link)
def extract_article(url):
section = requests.get(_build_link(host, url))
title = None
date = None
author = None
frill = None
body = None
main_img = None
if nota.status_code == 200:
parser_section = BeautifulSoup(section.text, 'lxml')
try:
# Extraemos el título
title = parser_section.find('div', attrs={'class': 'article-title'})
except Exception as e:
print(e)
try:
# Extraemos la fecha
date = parser_section.find('span', attrs={'pubdate': 'pubdate'}).get('datetime')
except Exception as e:
print(e)
try:
# Extraemos el autor
author = parser_section.find('div', attrs={'class', 'article-author'}).a
except Exception as e:
print(e)
try:
# Extraemos la volanta
frill = parser_section.find('h2', attrs={'class': 'article-prefix'})
except Exception as e:
print(e)
try:
# Extraemos el cuerpo
body = parser_section.find('div', attrs={'class': 'article-text'})
except Exception as e:
print(e)
try:
# Extraemos la imagen
media = parser_section.find('div', attrs={'article-main-media-image'})
list_images = media.find_all('img')
if len(list_images) == 0:
print('No se encontraron imagenes')
else:
main_img = requests.get(list_images[-1].get('data-src'))
except Exception as e:
print(e)
return {'title': title.text, 'date': date, 'author': author.text, 'frill': frill.text,
'body': body.text, 'media': main_img.content}```
content_note = extract_article(lista_notas[1])
content_note```
Código para extraer los párrafos:
Primero se seleccionan todos los elementos ‘p’ de la clase ‘article-text’. Aquí están todos los párrafos, sin embargo todavía salen las etiquetas html.
Para eliminar esas etiquetas html, usamos el ciclo for, guardando solamente el contenido (.text) de cada parrafo en una lista (llamada ‘parrafos’).
Luego, usamos el metodo join() sobre la lista ‘parrafos’ para convertirla en un solo elemento de texto.
body = soup_nota1.find('div', attrs={'class':'article-text'}).find_all('p')
parrafos = []
for parrafo in body:
parrafos.append(parrafo.text)
parrafos = '\n'.join(parrafos)
print(parrafos)
La función del reto:
def obtener_datos_nota(url_nota):
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = bs(nota.text, 'lxml')
#Extraer el titulo
titulo = s_nota.find('div', attrs={'class':'article-titles'}).find('h1', attrs={'class':'article-title'})
if titulo:
print('Titulo:', titulo.text)
else:
print('Vacio')
# Extraer la fecha
# La de abajo para quedarse con el texto
#fecha = s_nota.find('div', attrs={'class':'time'}).span
#print(fecha.text)
# Para quedarse con lo que dice el atributo datetime
fecha = s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
if fecha:
print('Fecha:', fecha)
else:
print('Vacio')
# Extraer la volanta
volanta = s_nota.find('div', attrs={'class':'article-titles'}).find('h2', attrs={'class':'article-prefix'})
if volanta:
print('Volanta:', volanta.text)
else:
print('Vacio')
# Extraer autor
autor = s_nota.find('div', attrs={'class':'article-author'}).a
if autor:
print('Autor:', autor.text)
else:
print('Vacio')
# Extraer el cuerpo
cuerpo = s_nota.find('div', attrs={'class':'article-text'})
if cuerpo:
print('Cuerpo:', cuerpo.text)
else:
print('Vacio')
# Extraer la imagen
media = s_nota.find('div', attrs={'class':'article-main-media-image'})
imagenes = media.find_all('img')
if len(imagenes) == 0:
print('No se encontraron imagenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
img_req = requests.get(img_src)
if img_req.status_code == 200:
display(Image(img_req.content))
except Exception as e:
print('Error:')
print(e)
print('\n')
mi funcion
queries= {'titulo': 'div.article-titles>h1.article-title',
'volanta': 'h2.article-prefix',
'copete': '.article-titles .article-summary',
'cuerpo': '.article-body .article-text>p',
'autor': '.breadcrumb span.tag-nam-e',
'img-url': '.article-main-media-image .show-for-small-only'}
def extract(queries, link):
assert len(link)>10 and type(link)==str, " no es un texto de mas de un caracter valido"
datos= {}
try:
req = requests.get(link)
except Exception as e:
print(e)
if req.status_code ==200:
bs_text = bs(req.text, 'lxml')
for key, query in queries.items():
try:
if key=="img-url":
raw=bs_text.select_one(query)
raw = raw.attrs['data-src']
datos[key]=raw
continue
raw=bs_text.select(query)
raw=[i.get_text() for i in raw]
datos[key]=''.join(raw)
except Exception as e:
print('\n Error {} \n'.format(e))
datos['url']=req.url
return datos
Este es el código del reto y de todo el proceso, descarga todas las notas publicadas por cada sección
import requests
from bs4 import BeautifulSoup
from IPython.display import Image
def links_article(section):
url = section
data = requests.get(url)
data_soup = BeautifulSoup(data.text,'lxml')
list_articles = []
try:
list_articles.append(data_soup.find('div', attrs ={'class':'featured-article__container'}).a.get('href'))
except:
print('No tiene nota principal')
list_others_articles = []
articles = data_soup.find('ul', attrs ={'class':'article-list'}).find_all('li')
for article in articles:
if len(article) == 1:
list_articles.append(article.find('div', attrs = {'class':'article-box__container'}).a.get('href'))
return list_articles
def extraer_contenido(url_nota):
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
soup_nota = BeautifulSoup(nota.text,'lxml')
#Extraer el titulo
titulo = soup_nota.find('h1', attrs = {'class':'article-title'})
print('Titulo:',titulo.text)
#Extraer la fecha
fecha = soup_nota.find('span', attrs = {'pubdate':'pubdate'}).get('datetime')
print('Fecha:',fecha)
volanta = soup_nota.find('h2', attrs = {'class':'article-prefix'})
if volanta is not None:
print('Volanta:',volanta.text)
copete = soup_nota.find('div', attrs = {'class':'article-summary'})
if copete is not None:
print('Copete:',copete.text)
media = soup_nota.find('div', attrs = {'class':'article-main-media-image'})
imagenes = media.find_all('img')
if len(imagenes) == 0:
"No se encontraron Imagenes"
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
print(img_src)
img_req = requests.get(img_src)
Image(img_req.content)
text_imagen = soup_nota.find('div', attrs = {'class':'article-main-media-image'})
if text_imagen is not None:
print('Epigrafe:',text_imagen.text)
cuerpo = soup_nota.find_all('p')
print('Cuerpo:')
for text in cuerpo:
print(text.text)
except Exception as e:
print('Error')
print(e,'\n')
if __name__ == "__main__":
url = 'https://www.pagina12.com.ar/'
pag12 = requests.get(url)
soup = BeautifulSoup(pag12.text,'lxml')
sections = soup.find('ul', attrs={'class':'hot-sections'}).find_all('li')
links_sections = [section.a.get('href') for section in sections]
name_sections = [section.a.get_text()for section in sections]
all_links = {}
for section,name in zip(links_sections,name_sections) :
all_links[name] = links_article(section)
print(f'\t\t\t\t\t\t\t{name}\n\n')
for i in all_links[name]:
print(i)
extraer_contenido(i)
print('\n')
Solución al reto, Código:
Output:
Les dejo mi solución al reto, el curso anterior se me hizo complicado pero desarrollar clases creo que se me ha hecho mas fácil.
Si tienen alguna retroalimentación la agradecería para nunca dejar de aprender.
import bs4
import logging
import requests
import argparse
logging.basicConfig(level=logging.INFO)
logger=logging.getLogger(__name__)
class scrapped():
def __init__(self,url):
self._url= url
self._lxml=None
self._page()
def _page(self):
try:
response=requests.get(self._url)
self._lxml=bs4.BeautifulSoup(response.text,'lxml')
except Exception as e:
print('Something went wrong\n ')
print(e,'\n')
def _contenido(self):
''' This method tries to extract the article content and returned a dictionary with it,
output estructure {'title':'value',
'date':'value',
'copete': 'value',
'volanta':'value'
'body':'value'
'author':'value'
'img_src':value'
}
if Exceptions ocurred during the process the'll be raised and varible will be set to them
'''
#check _lxml varible
try:
if self._lxml != None:
pass
except:
print('No page stored please run _page mehtod first')
raise SyntaxError
#title extraction
try:
title=self._lxml.find('div',attrs={'class':'col 2-col'}).find('h1').get_text()
except Exception as e:
print(f'title cant be obtained from {self._url}\n')
print(e,'\n')
title=e
#date extraction
try:
date=self._lxml.find('span',attrs={'pubdate':'pubdate'}).get('datetime')
except Exception as e:
print(f'date cant be obtained from {self._url}\n')
print(e,'\n')
date=e
#copete extraction
try:
copete=self._lxml.find('div',attrs={'class':'col 2-col'}).find('h3').get_text()
except Exception as e:
print(f'copete cant be obtained from {self._url}\n')
print(e,'\n')
copete=e
#volanta extraction
try:
volanta=self._lxml.find('div',attrs={'class':'col 2-col'}).find('h4').get_text()
except Exception as e:
print(f'volanta cant be obtained from {self._url}\n')
print(e,'\n')
volanta=e
#body extraction
try:
body=list(map(lambda content:content.get_text(),self._lxml.find('div',attrs={'class':'article-main-content article-text'}).find_all('p')))
body=' '.join(body)
except Exception as e:
print(f'body cant be obtained from {self._url}\n')
print(e,'\n')
body=e
#author extraction
try:
author=self._lxml.find('div',attrs={'class':'author-name'}).get_text()
if author==None:
raise Exception("No author in text")
except Exception as e:
print(f'author cant be obtained from {self._url}\n')
print(e,'\n')
author=e
#Image
try:
img_src=(self._lxml.find('div',attrs={'class':'article-main-media-image__container'}).find_all('img'))[-1]
img_src=img_src.get('data-src')
except Exception as e:
print(f'image cant be obtained from {self._url}\n')
print(e,'\n')
img_src=e
return {'title':title,
'date':date,
'copete': copete,
'volanta':volanta,
'body':body,
'author':author,
'img_src':img_src
}
def main(url):
logger.info(f'Generating intro from {url}')
_entry=scrapped(url)
_entry._page()
return _entry._contenido()
if __name__=='__main__':
parse=argparse.ArgumentParser()
parse.add_argument('url',help='The article url to scrappe',type=str)
args=parse.parse_args()
main(args.url)
Listo, continuando con el código anterior la función se llama con
|
noticias()
|
Y como argumento la sección de la cual se va a escrapear el contenido
def noticias(section):
url = 'https://www.pagina12.com.ar/secciones/'
section = section.replace(" ", "-")
section_to_scrap = url + section
notices = requests.get(section_to_scrap)
soup = BeautifulSoup(notices.text, 'lxml')
featured_article = soup.find_all('div', attrs={'class': 'article-item__content'})
links_articles = [article.a.get('href') for article in featured_article]
#return links_articles
for link in links_articles:
try:
nota = requests.get(link)
if nota.status_code == 200:
nota_soup = BeautifulSoup(nota.text, 'lxml')
title = nota_soup.find('h1', attrs={'class': 'article-title'})
print('Titulo: ')
print(title.text)
print('\n')
date = nota_soup.find('span', attrs={'pubdate': 'pubdate'}).get('datetime')
print('Fecha:')
print(date)
print('\n')
try:
media = nota_soup.find('div', attrs={'class': 'article-main-media-image'})
images = media.find_all('img')
if len(images) == 0:
print('No se encontraron imagenes')
else:
image = images[-1]
img_src = image.get('data-src')
#print(img_src)
img_req = requests.get(img_src)
display(Image(img_req.content))
except Exception as e:
print(e)
try:
copete = nota_soup.find('div', attrs={'class': 'article-summary'})
print('Copete:')
print(copete.text)
print('\n')
except:
print('No hay copete \n')
volanta = nota_soup.find('h2', attrs={'class': 'article-prefix'})
print('Volanta:')
print(volanta.text)
print('\n')
cuerpo = nota_soup.find('div', attrs={'class': 'article-text'})
print('Cuerpo:')
print(cuerpo.text)
print('\n')
autor = nota_soup.find('div', attrs={'class': 'article-author'}).a.get_text()
print('Autor:')
print(autor)
print('\n')
except Exception as e:
print('Error: ')
print(e)
print('\n')
noticias('el mundo')
Ayuda! Hay un error que no lo puedo entender. Quiero obtener el título de los 35 posts de una página. No tengo problema al hacerlo con 34 de ellos. Pero hay un título que falla. Está ubicado exactamente en la misma ruta que los otros 34 posts. Lo único que hago es cambiar la url , ya que el código es el mismo. Falla siempre. No encuentro el error.
Imagen A: todo bien
Imagen B: cambio url a ese post complicado y falla
Función del reto!
import requests
from bs4 import BeautifulSoup
from IPython.display import Image
def obtener_informacion(soup):
'''
Funcion que recibe un objeto de BeautifulSoup de una página de una sección
y devuelve una lista de URLs a las notas de esta seccón
'''
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
#Extraer el titulo
titulo = s_nota.find('h1', attrs={'class':'article-title'}).get_text()
print(titulo)
# EXtraer la fecha
Fecha = s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
print(Fecha)
# Extraer Volanta
volanta = s_nota.find('h2', attrs={'class':'article-prefix'}).get_text()
print(volanta)
# Extraer cuerpo
Cuerpo = s_nota.find('div', attrs={'class':'article-text'}).get_text()
print(Cuerpo)
#Extraer imagen
media = s_nota.find('div', attrs={'class':'article-main-media-image'}).find_all('img')
if len(imagenes) == 0:
print('no se encontraron imagenes')
else:
imagen = imagenes[-1].get('data_src')
# Descargamos imagen
img_req = requests.get(img_src)
print('Image\n')
# Mostrar la imagen
display(Image(img_req.content))
except Exception as e:
print("Error")
print(e)
if __name__ == '__main__':
url = 'https://www.pagina12.com.ar/'
lista_notas = obtener_notas(soup)
url_nota = lista_notas[0]
nota = requests.get(url_nota)
s_nota = BeautifulSoup(nota.text, 'lxml')
obtener_informacion(s_nota)
No agregué imágenes, sólo los datos importantes (para mí)
def info_noticia (url_noticia):
""" Recibe ulr de una noticia del diario pagina 12
devuelve un diccionario con los datos relevantes"""
try:
noticia = requests.get(url_noticia)
if noticia.status_code == 200:
# Convertir la noticia a una sopa
s_noticia = BeautifulSoup(noticia.text, 'lxml')
# Crear un diccionario vacio
dict_noticia = {}
# Extraer fecha}
date = s_noticia.find('span', attrs={'class':'p12-separator--right--gray'})
if date:
dict_noticia['date'] = date.text
else:
dict_noticia['date'] = None
# Extraer título
title = s_noticia.find('h1', attrs={'class':'article-title'})
if title:
dict_noticia['title'] = title.text
else:
dict_noticia['title'] = None
# Extraer encabezado
header = s_noticia.find('h2', attrs={'class':'article-prefix'})
if header:
dict_noticia['header'] = header.text
else:
dict_noticia['header'] = None
# Extraer resumen
summary = s_noticia.find('div', attrs={'class':'article-summary'})
if summary:
dict_noticia['summary'] = summary.text
else:
dict_noticia['summary'] = None
except Exception as e:
print('Error')
print(e)
print('\n')
return dict_noticia
def page_info(url_note):
try:
note = requests.get(url_note)
if note.status_code ==200:
soup_note = BeautifulSoup(note.text,'lxml')
#Extract title
title=soup_note.find('h1',attrs={'class':'article-title'})
print(f'Titulo: {title.get_text()} \n')
#print(title.text)
#Extract date
date = soup_note.find('span',attrs={'pubdate':'pubdate'}).get('datetime')
print(f'Fecha: {date} \n')
#Extract VOLANTA
volanta = soup_note.find('h2',attrs={'class':'article-prefix'})
print(f'Volanta: {volanta.text} \n')
#Extract Copete
try:
copete = soup_note.find('div',attrs={'class':'article-summary'})
print(f'Copete: {copete.text} \n')
except:
print('COPETE \n')
#Extract body
try:
body_paragraph = soup_note.find('div',attrs={'class':'article-text'}).find_all('p')
paragraph = [p.text for p in body_paragraph]
txt = '\n '.join(paragraph)
print(txt)
except:
print('BODY')
#Extract Author
author = soup_note.find('div',attrs={'class':'article-author'}).find('a')
print(f'Autor: {author.text} \n')
media = soup_note.find('div',attrs={'class':'article-main-media-image'})
images=media.find_all('img')
if len(images) ==0:
print('There arent images')
else:
#I will take the greatest image in the array
image = images[-1]
img_src = image.get('data-src')
img_req = requests.get(img_src)
if img_req.status_code ==200:
display(Image(img_req.content))
except Exception as e:
print('Error:')
print(e)
print('\n')
Excelente curso hasta el momento, siguiendo la ruta de Data Science con gusto. Mi codigo, me inspire en el manejo de errores en Matias Vega Maza.
`import requests
from IPython.display import Image
from bs4 import BeautifulSoup
url = 'https://www.pagina12.com.ar/310664-cristina-kirchner-recordo-a-los-12-desaparecidos-de-la-igles'
def get_data(url):
try:
article = requests.get(url)
print(f'-------status {article.status_code}------------')
if article.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
#Date extraction
date = s_nota.find('span', attrs={'pubdate':'pubdate'}).get('datetime')
if date:
print(date)
print('\n')
else:
print('Not available')
#Article prefix extraction
aprefix = s_nota.find('h2', attrs={'class':'article-prefix'}).get_text()
if aprefix:
print(aprefix)
print('\n')
else:
print('Not available')
#Title extraction
title = s_nota.find('h1', attrs={'class':'article-title'}).get_text()
if title:
print(title)
print('\n')
else:
print('Not available')
#Image extraction
image = s_nota.find('div', attrs={'class':'article-main-media-image'}).find_all('img')[-1].get('data-src')
if image:
print(image)
else:
print('Not available')
#Article summary extraction
summary = s_nota.find('div', attrs={'class':'article-summary'}).get_text()
if summary:
print(summary)
print('\n')
else:
print('Not available')
#Article body extraction
body = s_nota.find('div', attrs={'class':'article-text'}).get_text()
if body:
print(body)
else:
print('Not available')
except Exception as e:
print('Error')
print(e)
print('\n')
get_data(url)
import requests
from bs4 import BeautifulSoup
from IPython.display import Image
def scrapper_nota(url_nota):
try:
nota = requests.get(url_nota)
if nota.status_code == 200:
s_nota = BeautifulSoup(nota.text, 'lxml')
# Extraemos el titulo
titulo = s_nota.find('div', attrs={'class': 'article-titles'}).find('h1', attrs={'class': 'article-title'})
print(f'titulo: {titulo.text} \n')
# Extraer la fecha
fecha = s_nota.find('span', attrs={'pubdate': 'pubdate'}).get('datetime')
print(f'fecha: {fecha}')
# Extraer la volanta
volanta = s_nota.find('div', attrs={'class': 'article-titles'}).find('h2', attrs={'class': 'article-prefix'})
print(f'volanta: {volanta.text} \n')
# Extraer la bajada
cuerpo = s_nota.find('div', attrs={'class': 'article-text'}).find('p').get_text()
print(f'cuerpo: {cuerpo} \n')
# Extraer el autor
author = s_nota.find('div', attrs={'class': 'article-author'}).find('a').get_text()
if author:
print(f'autor: {author} \n')
else:
print('No se encontro author \n')
# multimedia
media = s_nota.find('div', attrs = {'class': 'article-main-media-image'})
imagenes = media.find_all('img')
if len(imagenes) == 0:
print('no se encontraron imagenes')
else:
imagen = imagenes[-1]
img_src = imagen.get('data-src')
print(img_src)
img_req = requests.get(img_src)
display(Image(img_req.content))
except Exception as e:
print('\n')
print(f'Error en la request: {e}')
print('\n')
```
url = 'https://www.pagina12.com.ar/304582-nueva-etapa-las-aulas-de-las-escuelas-solo-se-abren-para-la-'
scrapper_nota(url)
titulo: Nueva etapa: Las aulas de las escuelas sólo se abren para la revinculación
fecha: 2020-11-09
volanta: Guía para saber qué se habilitó en el área educativa de provincia y CABA
cuerpo: En la provincia de Buenos Aires, 26 distritos fueron autorizados por la Dirección General de Escuelas a reabrir sus aulas. Según el semáforo epidemiológico, están en una situación de bajo riesgo de contagios, por lo que pueden comenzar a convocar a sus estudiantes, con protocolos de cuidado. Otros 82 distritos bonaerenses -entre ellos muchos del Conurbano y la zona de La Plata- atraviesan escenarios de riesgo medio y quedaron habilitados para hacer encuentros de revinculación, en patios y campos deportivos, es decir a cielo abierto. En la Ciudad de Buenos Aires, la gestión de Horacio Rodríguez Larreta promete que abrirá las escuelas para todos los alumnos, desde 45 días hasta adultos. Sin embargo, las escuelas deben sumar al riesgo bajo o medio otras condiciones para retomar la presencialidad. En esta nota, una guía sobre qué fue habilitado, y en qué términos.
autor: Laura Vales
https://images.pagina12.com.ar/styles/focal_3_2_960x640/public/2020-11/119172-whatsapp-20image-202020-11-08-20at-2020-53-54.jpeg?itok=9h0RK6cP
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?