[vc_row][vc_column][vc_column_text]En el siguiente articulo revisaremos la creación de un web scraper con Python y Selenium, el código es una forma sencilla de descargar las imágenes de un sitio web, en este caso Unsplash.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Ingredientes para un Web Scraping sencillo
- Python (3.6.3 o superior)
- Estamos trabajando con Pycharm la versión comunitaria
- Se deben instalar las librerías requests, Pillow y selenium
- pip install requests Pillow selenium
- geckodriver (más adelante revisamos las instrucciones)
- El navegador Mozilla Firefox
- Tener una conexión de internet
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Pasos para un Web Scraping sencillo
¿Tiene todo instalado y listo? Excelente. Revisaremos lo que hace cada uno de los ingredientes a medida que avanzamos en el desarrollo de código.
Lo primero que utilizaremos es el webdriver de Selenium combinado con geckodriver para abrir una ventana del navegador que hace el trabajo por nosotros. Para empezar, crear un proyecto en Pycharm, descargue la versión más reciente de geckodriver para su sistema operativo, abra el archivo comprimido y copie el archivo geckodriver.exe en la carpeta de su proyecto. Geckodriver es básicamente lo que le permite a Selenium obtener el control de Firefox, por lo que se requiere en la carpeta de nuestro proyecto para poder utilizar el navegador.
Lo siguiente que queremos hacer es importar realmente el controlador web desde Selenium a nuestro código y conectarnos a la URL que queremos. Así, tenemos lo siguiente:
1 2 3 4 5 6 7 8 | from selenium import webdriver # La URL que queremos navegar url = "https://unsplash.com" # Utilizando el driver web de Selenium para abrir la página driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url) |
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Hasta aquí, sencillo. Si lo ha hecho correctamente, ya pasamos la parte difícil y debería ver una ventana del navegador web con la página.
A continuación, debemos desplazarnos hacia abajo para poder carga más imágenes antes de poder descargarlas. También queremos esperar por unos segundos, solo en caso de que la conexión sea lenta y las imágenes no se hayan cargado por completo. Como Unsplash esta construido con React, esperar 5 segundos es un tiempo adecuado. También queremos utilizar un código JavaScript para desplazarnos por la página, utilizaremos windows.scrollTo() para esto. El código debería terminar de la siguiente forma:
1 2 3 4 5 6 7 8 9 10 11 | import time from selenium import webdriver url = "https://unsplash.com" driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url) # Scroll de la página y espera de 5 segundos driver.execute_script("window.scrollTo(0,1000);") time.sleep(5) |
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Después de comprobar el código anterior, debería ver que el navegador se desplaza un poco hacia abajo en la página. Lo siguiente que debemos hacer es encontrar las imágenes que queremos bajar del sitio. Después de revisar el código generado por React, observamos que podemos utilizar un selector de CSS para enfocar específicamente las imágenes en la galería de la página. El diseño y el código específicos de la página pueden cambiar en el futuro, pero al momento de realizar este programa se podría utilizar el selector #gridMulti img para obtener todos los elementos <img> que aparecían en el navegador.
Podemos obtener una lista de estos elementos utilizando find_elements_by_css_selector(), pero lo que queremos es el atributo src de cada elemento. Entonces, podemos iterar sobre la lista y tomar esos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import time from selenium import webdriver url = "https://unsplash.com" driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url) driver.execute_script("window.scrollTo(0,1000);") time.sleep(5) # Seleccionar los elementos de imagen e imprimier las URL image_elements = driver.find_elements_by_css_selector("#gridMulti img") for image_element in image_elements: image_url = image_element.get_attribute("src") print(image_url) |
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]Ahora, para obtener realmente las imágenes que encontramos utilizaremos requests y partes del paquete PIL, a saber el objeto Image. También queremos utilizar BytesIO de io para escribir las imágenes en el folder ./images/ que crearemos dentro de nuestra carpeta de proyectos. Entonces, para unir todo esto, debemos enviar una solicitud HTTP GET a la URL de cada imagen y luego, usando Image y BytesIO, almacenamos la imagen que obtenemos en la respuesta. Aquí hay una manera de hacer esto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import requests import time from selenium import webdriver from PIL import Image from io import BytesIO url = "https://unsplash.com" driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url) driver.execute_script("window.scrollTo(0,1000);") time.sleep(5) image_elements = driver.find_elements_by_css_selector("#gridMulti img") i = 0 for image_element in image_elements: image_url = image_element.get_attribute("src") # Envío del request HTTP GET y guardar las imágenes de las respuestas image_object = requests.get(image_url) image = Image.open(BytesIO(image_object.content)) image.save("./images/image" + str(i) + "." + image.format, image.format) i += 1 |
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Limitaciones, consideraciones y mejoras futuras
Este ejercicio es una prueba de concepto muy simple para ver como se puede realizar web scraping con Python, lo que significa que hay muchas cosas que se pueden hacer para mejorar esta pequeña herramienta:
- Geckodriver no debe colocarse en la carpeta del proyecto, sino que debe instalarse globalmente y ser parte de la variable del sistema PATH.
- La funcionalidad de búsqueda podría extenderse fácilmente para incluir múltiples consultas, de modo que se simplifique el proceso de descarga de muchas imágenes.
- El navegador predeterminado podría cambiarse de Firefox a Chrome o incluso PhantomJS, lo que sería mucho mejor para este proyecto.
Información adicional del artículo:
- Articulo original 30-minute Python Web Scraper
- Código fuente con mejoras de Unscrape en GitHub
- Nuestra versión de unscrape en GitHub
[/vc_column_text][/vc_column][/vc_row]
Selenium is a great library in web scraping.
Thanks for the article.