Herramientas de usuario

Herramientas del sitio


informatica:programacion:cursos:python_avanzado_proyectos_seguridad:extraccion_imagenes_enlaces_modulo_bs4

Extracción de imágenes y enlaces con el módulo bs4

Módulo perteneciente al curso Python avanzado para proyectos de seguridad

De la misma forma que en la sección anterior hemos extraído las enlaces, documentos e imágenes con el módulo de lxml, también podemos hacerlo directamente con BeautifulSoup.

En este ejemplo realizamos la petición a la url pasada por parámetro con el módulo requests. Posteriormente construimos el objeto BeautifulSoup a partir del cual vamos a extraer aquellas etiquetas que sean <img>. Si la url es correcta, se descarga la imagen de nuevo utilizando el módulo requests.

Para el caso de extraer imágenes a partir de una url podemos hacer uso del método bs.find_all("img").

Esto nos devolverá el listado de etiquetas img encontradas en el código html obtenido.

Puede encontrar el siguiente código en el fichero obtener_images_bs4.py:

#!/usr/bin/env python3
 
import os
import requests
from bs4 import BeautifulSoup
 
class Scraping:
 
    def scrapingImages(self,url):
        print("Obtener imágenes de la url con bs4:"+ url)
 
        try:
            response = requests.get(url)  
            bs = BeautifulSoup(response.text, 'lxml')
 
            images = bs.find_all("img")
 
            print('Imágenes encontradas %s' % len(images))
 
            #crear directorio para guardar las imagenes
            os.system("mkdir imagenes")
 
            for tagImage in images:
                if tagImage['src'].startswith("http") == False:
                    download = url + tagImage['src']
                else:
                    download = tagImage['src']
                print(download)
                # descargar las imagenes en el directorio creado
                r = requests.get(download)
                f = open('imagenes/%s' % download.split('/')[-1], 'wb')
                f.write(r.content)
                f.close()
 
        except Exception as e:
                print("Error de conexión en: " + url)
                pass
 
 
if __name__ == "__main__":
    target = "https://www.python.org"
    scraping = Scraping()
    scraping.scrapingImages(target)

Desde nuestro programa principal main llamaríamos al método scrapingImages de la clase Scraping pasándole por parámetro la url o target a analizar.

Como podemos ver en la salida nos devuelve aquellas imágenes que se encuentran en la página principal que estamos analizando.

Extraer enlaces a partir de una url con BeautifulSoup

Considere una situación en la que desea obtener todos los hipervínculos de la página web.

En el siguiente ejemplo extraemos todos los enlaces de una determinada URL. La idea es hacer la petición con requests y con BeautifulSoup parsear los datos que devuelve la petición.

Puede encontrar el siguiente código en el fichero extract_links_from_url.py:

#!/usr/bin/env python3
 
from bs4 import BeautifulSoup
import requests
 
url = input("Ingrese a un sitio web para extraer los links: ")
 
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
response = requests.get("http://" +url, headers = headers)
data = response.text
soup = BeautifulSoup(data,'lxml')
 
for link in soup.find_all('a'):
    link = link.get('href')
    if(link.startswith("http")):
        print(link)
    else:
        print(url+link)

En el código anterior la declaración from bs4 import BeautifulSoup permite importar la biblioteca BeautifulSoup. La variable url almacena la URL del sitio web y usamos el módulo requests para realizar la petición http.

La instrucción data = response.text asigna la página web a una variable data. En la instrucción soup = BeautifulSoup(data,'lxml'), se crea un objeto soup. La siguiente instrucción soup.find_all('a') guarda todos los hipervínculos.

Para su ejecución, bastaría con introducir un sitio web y extraerá todos los enlaces utilizando el método find_all() del módulo BeautifulSoup.

También podríamos utilizar el módulo urllib.requests para realizar la petición en lugar del módulo requests.

En el siguiente ejemplo estamos extrayendo los enlaces realizando la petición con urllib.requests.

Puede encontrar el siguiente código en el fichero links_pyvideo.py:

#!/usr/bin/env python3
 
import urllib.request
from bs4 import BeautifulSoup
 
def get_video_links(archive_url):
    # crear objeto respuesta
    response = urllib.request.urlopen(archive_url)
    # crear objeto beautiful-soup
    soup = BeautifulSoup(response.read(),'lxml')
    links = []
    for link in soup.find_all('a'):
        file_link = link.get('href')
        links.append(file_link)
    return links
 
links = get_video_links('https://pyvideo.org')
print(links)

<p>Como podemos ver en la salida nos devuelve aquellos enlaces&nbsp;que se encuentran&nbsp;en la página principal que estamos analizando.</p>

['https://github.com/pyvideo/pyvideo/wiki/How-to-Contribute-Media', '/pages/thank-you-contributors.html', 'https://pyvideo.org/index.html', 'https://pyvideo.org/events.html', 'https://pyvideo.org/tags.html', 'https://pyvideo.org/speakers.html', 'https://pyvideo.org/pages/about.html', 'https://pyvideo.org/pages/thank-you-contributors.html', 'https://pyvideo.org/pages/thanks-will-and-sheila.html', 'https://pyvideo.org/', '/pycon-us-2020/1-1-1-or-record-deduplication-with-python.html', '/pycon-us-2020/1-1-1-or-record-deduplication-with-python.html', '/events/pycon-us-2020.html', '/speaker/flavio-juvenal-da-silva-junior.html', '/pycon-us-2020/9-years-of-pyladies-lessons-learned-and-what-comes-next.html', '/pycon-us-2020/9-years-of-pyladies-lessons-learned-and-what-comes-next.html', '/events/pycon-us-2020.html', '/speaker/lorena-mesa.html', '/speaker/elaine-wong.html', '/speaker/mariatta.html', '/pycon-us-2020/a-s-guide-to-unicode.html', '/pycon-us-2020/a-s-guide-to-unicode.html', '/events/pycon-us-2020.html', '/speaker/james-bennett.html', '/pycon-us-2020/asyncio-music.html', '/pycon-us-2020/asyncio-music.html', '/events/pycon-us-2020.html', '/speaker/lukasz-langa.html', '/pycon-us-2020/automate-the-boring-stuff-with-slackbot.html', '/pycon-us-2020/automate-the-boring-stuff-with-slackbot.html', '/events/pycon-us-2020.html', '/speaker/takanori-suzuki.html', '/pycon-us-2020/beautiful-python-refactoring.html', '/pycon-us-2020/beautiful-python-refactoring.html', '/events/pycon-us-2020.html', '/speaker/conor-hoekstra.html', 'https://pyvideo.org/events/pycon-us-2020.html', 'https://pyvideo.org/events/pyninsula-2020.html', 'https://pyvideo.org/events/minsk-python-meetup.html', 'https://pyvideo.org/events/pyjamas-conf-2019.html', 'https://pyvideo.org/events/pydata-warsaw-2019.html', '/events.html', 'https://pyvideo.org/speaker/russell-keith-magee.html', 'https://pyvideo.org/speaker/james-powell.html', 'https://pyvideo.org/speaker/brandon-rhodes.html', 'https://pyvideo.org/speaker/dustin-ingram.html', 'https://pyvideo.org/speaker/andrew-godwin.html', '/speakers.html', 'https://pyvideo.org/tag/lightning-talks/', 'https://pyvideo.org/tag/talk/', 'https://pyvideo.org/tag/tutorial/', 'https://pyvideo.org/tag/django/', 'https://pyvideo.org/tag/python/', 'https://pyvideo.org/tag/keynote/', 'https://pyvideo.org/tag/machine-learning/', 'https://pyvideo.org/tag/belarus/', 'https://pyvideo.org/tag/minsk/', 'https://pyvideo.org/tag/data-science/', '/tags.html', 'https://pyvideo.org/languages.html#eng', 'https://pyvideo.org/languages.html#spa', 'https://pyvideo.org/languages.html#rus', 'https://pyvideo.org/languages.html#por', 'https://pyvideo.org/languages.html#jpn', 'https://pyvideo.org/languages.html#fra', 'https://pyvideo.org/languages.html#kor', 'https://pyvideo.org/languages.html#ita', 'https://pyvideo.org/languages.html#deu', 'https://pyvideo.org/languages.html#zho', '/languages.html', 'https://github.com/pyvideo/pyvideo/blob/master/LICENSE', 'https://github.com/pyvideo/data/blob/master/LICENSE']

Actividad práctica: Completar el código que permite la extracción de enlaces con el módulo beautifulSoup

Completar el código que permite la extracción de enlaces con el módulo beautifulSoup

#!/usr/bin/env python3
 
import os
import xxx
from bs4 import xxx
 
class Scraping:
 
    def scrapingLinks(self,xxx):
            print("Obtener links de la url:"+ xxx)
 
            try:
                response = requests.xxx(url) 
                bs = xxx(xxx.text, 'lxml')
 
                links = bs.xxx("a")
 
                print('Links encontrados %s' % len(xxx))
 
                for xxx in links:
                    if xxx['href'].startswith("http") == False:
                        print(xxx+xxx['href'])
                    else:
                        print(xxx['href'])
 
            except Exception as e:
                    print("Error de conexión en:  " + xxx)
                    pass
 
if __name__ == "__main__":
    target = "https://www.python.org"
    scraping = Scraping()
    scraping.xxx(xxx)

Desde nuestro programa principal main llamaríamos al método scrapingLinks de la clase Scraping pasándole por parámetro la url o target a analizar.

Como podemos ver en la salida, nos devuelve aquellos link que se encuentran en la página principal que estamos analizando.

Obtener links de la url:https://www.python.org
Links encontrados 206
https://www.python.org#content
https://www.python.org#python-network
https://www.python.org/
https://www.python.org/psf-landing/
https://docs.python.org
https://pypi.org/
https://www.python.org/jobs/
https://www.python.org/community/
https://www.python.org#top
https://www.python.org/
https://psfmember.org/civicrm/contribute/transact?reset=1&amp;id=2
https://www.python.org#site-map
https://www.python.org#
https://www.python.orgjavascript:;
https://www.python.orgjavascript:;
https://www.python.orgjavascript:;
https://www.python.org#
https://www.facebook.com/pythonlang?fref=ts
https://twitter.com/ThePSF

Solución

#!/usr/bin/env python3
 
import os
import requests
from bs4 import BeautifulSoup
 
class Scraping:
 
    def scrapingLinks(self,url):
            print("Obtener links de la url:"+ url)
 
            try:
                response = requests.get(url)  
                bs = BeautifulSoup(response.text, 'lxml')
 
                links = bs.find_all("a")
 
                print('Links encontrados %s' % len(links))
 
                for link in links:
                    if link['href'].startswith("http") == False:
                        print(url+link['href'])
                    else:
                        print(link['href'])
 
            except Exception as e:
                    print("Error de conexión en:  " + url)
                    pass
 
if __name__ == "__main__":
	target = "https://www.python.org"
	scraping = Scraping()
	scraping.scrapingLinks(target)

Implementar un crawler de enlaces a partir de una URL

El siguiente ejemplo permite implementar un crawler de enlaces a partir de una url.

Puede encontrar el siguiente código en el fichero obtener_links_spyder.py:

#!/usr/bin/env python3
 
import requests
import sys
 
from bs4 import BeautifulSoup
 
# Creamos las listas 2 niveles
urls_nivel1 = []
urls_nivel2 = []
 
# Recibimos los argumentos
target_url = sys.argv[1] 
 
# Realizamos una conexión al argumento pasado y además, leemos todo el contenido del código fuente que existe en la página
url = requests.get(target_url).content
# Usamos nuestra librería de bs4 para posteriormente recatar lo que deseamos
soup = BeautifulSoup(url,'lxml')
# Mediante el for y el método de bs4 llamado find_all, recolectamos todas las etiquetas donde existe a href
for line in soup.find_all('a'):
    new_line = line.get('href')
    try: 
       # Si existe en alguna línea del código fuente el http, lo almacenamos en nuestra lista llamada urls
        if new_line[:4] == "http": 
            if target_url in new_line: 
               urls_nivel1.append(str(new_line)) 
        # Si no existe, intentamos combinar nuestro argumento(url de la página) + lo que encontramos
        elif new_line[:1] == "/": 
            try:
                comb_line = target_url+new_line 
                urls_nivel1.append(str(comb_line))  
            except: 
                pass
        # Recorremos lo que hemos guardado anteriormente en nuestra lista(urls).
        print(urls_nivel1)
        for get_this in urls_nivel1: 
           # Como dentro de urls están todos los enlaces, realizamos una conexión a dicha url y leemos el código fuente
            url = requests.get(get_this).content 
            # Usamos nuestra librería de bs4 para posteriormente obtener nuevos enlaces
            soup = BeautifulSoup(url,'lxml') 
            for line in soup.find_all('a'): 
                new_line = line.get('href') 
                try: 
                    if new_line[:4] == "http": 
                        if target_url in new_line:
                            urls_nivel2.append(str(newline)) 
                    elif new_line[:1] == "/": 
                        comb_line = target_url+new_line 
                        urls_nivel2.append(str(comb_line)) 
                except: 
                    pass
 
    except:
       pass
 
print(urls_nivel2)

Ejemplo de ejecución:

$ python obtener_links_spyder.txt http://python.org
[]
['http://python.org/']
['http://python.org/', 'http://python.org/jobs/']
['http://python.org/', 'http://python.org/jobs/', 'http://python.org/community-landing/']
['http://python.org/', 'http://python.org/jobs/', 'http://python.org/community-landing/', 'http://python.org/', 'http://python.org/community/irc/']

FAQ

¿Qué es BeautifulSoup?

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.

informatica/programacion/cursos/python_avanzado_proyectos_seguridad/extraccion_imagenes_enlaces_modulo_bs4.txt · Última modificación: por tempwin