Herramientas de usuario

Herramientas del sitio


informatica:programacion:python:modulos:beautiful_soup

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
informatica:programacion:python:modulos:beautiful_soup [2021/02/09 21:51] – [Python: Beautiful Soup] tempwininformatica:programacion:python:modulos:beautiful_soup [2024/06/14 17:24] (actual) – [Recursos] tempwin
Línea 4: Línea 4:
  
   * [[https://www.crummy.com/software/BeautifulSoup/|Web oficial]]   * [[https://www.crummy.com/software/BeautifulSoup/|Web oficial]]
 +  * [[https://www.crummy.com/software/BeautifulSoup/bs4/doc/|Documentación]]
  
  
Línea 11: Línea 12:
 pip install beautifulsoup4 pip install beautifulsoup4
 </code> </code>
 +
 +También es necesario instalar ''requests'' para poder descargar contenido web, añadir cabeceras, etc.
 +
 +<code>
 +pip install requests
 +</code>
 +
 +===== Uso =====
 +
 +Pasos:
 +
 +  - URL a analizar
 +  - Descarga de la URL con ''requests'' (indicando cabeceras si es necesario).
 +  - Conversión de la respuesta en un objeto de Beautiful Soup
 +  - Búsqueda de los datos que queremos (''find()'')
 +  - Tratamiento del resultado para adaptarlo a nuestro gusto.
 +
 +Si queremos usar la misma cabecera que la de nuestro navegador, podemos ir a la web http://www.xhaus.com/headers y anotar lo que ponga en ''User-Agent'':
 +
 +<code python>
 +headers = {
 +    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:85.0) Gecko/20100101 Firefox/85.0" 
 +}
 +</code>
 +===== Ejemplos =====
 +
 +==== Amazon ====
 +
 +<code python>
 +import bs4
 + 
 +import requests # es el módulo que hará la descarga
 + 
 +# Para las webs que no permiten scraping, le hacemos creer que 
 +# nos estamos conectando con un navegador
 +headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'}
 + 
 +res = requests.get("https://www.amazon.es/dp/B078211KBB/", headers = headers)
 + 
 +# Nos aseguramos de que no ha habido errores al descargar la web anterior
 +res.raise_for_status()
 + 
 +soup = bs4.BeautifulSoup(res.text, "html.parser")
 +
 +titulo = soup.find("span", attrs={"id": "productTitle"}).string.strip()
 +
 +try:
 +    # Precios normales
 +    precio = soup.find("span", attrs={'id':'priceblock_ourprice'}).string.strip()
 +
 +except AttributeError:
 +    # Precios de oferta
 +    precio = soup.find("span", attrs={'id':'priceblock_dealprice'}).string.strip() 
 + 
 +# Se crea un objeto 'BeautifulSoup' donde se podrán hacer búsquedas
 +# utilizando selectores CSS, por ejemplo:
 +#elementos = soup.select('html head title')
 +
 +print(titulo)
 +print(precio)
 +
 +# Eliminamos el HTML quedándonos solo con el texto:
 +#elementos[0].text
 + 
 +# Quitamos también saltos de línea y espacios:
 +#elementos[0].text.strip()
 +</code>
 +
 +Otro similar:
 +
 +<code python>
 +#! /usr/bin/env python
 +
 +import requests
 +from bs4 import BeautifulSoup
 +import smtplib
 +
 +headers = {
 +    "User-agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'}
 +
 +URL = 'https://www.amazon.es/Raspberry-PI-4B-8GB-RAM/dp/B0899VXM8F/ref=sr_1_6?__mk_es_ES=%C3%85M%C3%85%C5%BD%C3%95%C3%91&dchild=1&keywords=raspberry+pi&qid=1612905463&sr=8-6'
 +
 +def amazon():
 +
 +    page = requests.get(URL, headers=headers)
 +
 +    soup = BeautifulSoup(page.content, 'html.parser')
 +
 +    title = soup.find(id="productTitle").get_text()
 +    price = soup.find(id="priceblock_ourprice").get_text()
 +    sep = ','
 +    con_price = price.split(sep, 1)[0]
 +    converted_price = int(con_price.replace('.', ''))
 +
 +    # título y precio
 +    print(title.strip())
 +    print(converted_price)
 +
 +amazon()
 +</code>
 +===== Ejemplo 2: leyendo HTML de una web =====
 +
 +<code python>
 +from bs4 import BeautifulSoup
 +import requests
 +
 +url = "https://direccion.web"
 +
 +result = requests.get(url)
 +
 +# Contenido de la petición
 +# print(result.text)
 +
 +doc = BeautifulSoup(result.text, "html.parser")
 +
 +# Mostrarlo bien sangrado
 +# print(doc.prettify())
 +
 +"""
 +Buscar por un texto (y aprovechar el resultado para obtener el elemento padre)
 +Queremos llegar a un precio que comienza por el signo "$"
 +"""
 +
 +prices = doc.find_all(text="$")
 +parent = prices[0].parent
 +strong = parent.find("strong")
 +print(strong.string)
 +</code>
 +
 +===== Búsquedas =====
 +
 +  * ''find()'': busca el primer elemento que encuentre
 +  * ''find_all()'': busca todos los elementos
 +
 +Podemos buscar más de un elemento a la vez:
 +
 +<code python>
 +doc.find_all(["p", "div", "li"])
 +</code>
 +
 +Podemos buscar un elemento que tenga cierto texto:
 +
 +<code python>
 +doc.find_all(["option"], text="Rojo")
 +</code>
 +
 +Buscar atributos de cierto elemento, por ejemplo el atributo ''value'' de la etiqueta ''option'':
 +
 +<code python>
 +doc.find_all(["option"], value="rojo")
 +</code>
 +
 +Búsqueda por clases CSS:
 +
 +<code python>
 +tag = doc.find_all(class_="btn-item")
 +</code>
 +
 +<WRAP center round info 60%>
 +''class'' es una palabra reservada de Python, así que el argumento para buscar por clases lleva un guion bajo, y así diferenciarlo.
 +</WRAP>
 +
 +Búsqueda por expresión regular:
 +
 +<code python>
 +import re
 +
 +# Buscar un signo de dólar y lo que venga después
 +tags = doc.find_all(text=re.compile("\$.*"))
 +</code>
 +
 +Limitar los resultados de búsqueda:
 +
 +<code python>
 +import re
 +
 +# Buscar un signo de dólar y lo que venga después
 +tags = doc.find_all(text=re.compile("\$.*"), limit=1)
 +</code>
 +
 +Búsqueda por proximidad en la estructura de árbol, por ejemplo, nodos hermanos, padre y descendientes:
 +
 +<code python>
 +from bs4 import BeautifulSoup
 +import requests
 +
 +url = "https://coinmarketcap.com/"
 +result = requests.get(url).text
 +doc = BeautifulSoup(result, "html.parser")
 +
 +tbody = doc.tbody
 +trs = tbody.contents
 +
 +print(trs[1].next_sibling)
 +
 +# Nodo padre:
 +print(trs[0].parent)
 +
 +# Descendientes
 +print(trs[0].descendants)
 +#print(trs[0].children)
 +#print(trs[0].contents)
 +</code>
 +
 +Recorrer una tabla buscando precios:
 +
 +<code python>
 +from bs4 import BeautifulSoup
 +import requests
 +
 +url = "https://coinmarketcap.com/"
 +result = requests.get(url).text
 +doc = BeautifulSoup(result, "html.parser")
 +
 +tbody = doc.tbody
 +trs = tbody.contents
 +
 +prices = {}
 +
 +for tr in trs[:10]:
 +    for td in tr.contents:
 +        name, price = tr.contents[2:4]
 +        fixed_name = name.p.string
 +        fixed_price = price.a.string
 +        
 +        prices[fixed_name] = fixed_price
 +        
 +print(prices)  
 +</code>
 +===== Recursos =====
 +
 +  * [[https://towardsdatascience.com/top-5-beautiful-soup-functions-7bfe5a693482|Top 5 Beautiful Soup Functions That Will Make Your Life Easier]]
 +  * [[https://www.youtube.com/watch?v=gRLHr664tXA| Beautiful Soup 4 Tutorial #1 - Web Scraping With Python ]]
informatica/programacion/python/modulos/beautiful_soup.1612903902.txt.gz · Última modificación: por tempwin