====== Web Scraping ====== ===== Módulo Webbrowser ===== El módulo **webbrowser** sólo abre la dirección de internet que se especifique en una nueva pestaña del navegador configurado por defecto. # Abrir dirección en google maps import webbrowser, sys, pyperclip if len(sys.argv)>1: # Comprobamos si hay parámetros de entrada direccion = '+'.join(sys.argv[1:]) else: # Si no hay parámetros de entrada toma los datos del portapapeles direccion = pyperclip.paste() # calle salsipuedes, 2, Madrid webbrowser.open("https://www.google.es/maps/place/" + direccion) ===== Módulo requests ===== Con este módulo es posible descargar archivos de la web de forma sencilla. \\ No viene por defecto instalado con python, por lo que habría que ejecutar: pip install --user requests Python dispone de la librería ulllib2 para este cometido, pero es complicada de manejar. Para descargar una página web, o un archivo, basta con especificar la URL en la fución .get() import requests res = requests.get('https://automatetheboringstuff.com/files/rj.txt') # Descargamos Romeo y Julieta en txt type(res) # Tipo request.models.Response res.status_code == requests.codes.ok # 200 len(res.txt) # Nº de caracteres del txt print(rest.text[:250]) # Se muestran los primeros 250 carateres type(res) # Tipo request.models.Response res.status_code == requests.codes.ok # 200 len(res.txt) # Nº de caracteres del txt print(rest.text[:250]) # Se muestran los primeros 250 carateres ==== Chequeo de errores ==== requests dispone del atributo **status_code**, para ver la respuesta que devuelve a la petición, que si todo va bien será 200 (**requests.codes.ok**). \\ Podemos usar el método **res.raise_for_status()** (no lleva parámetros) para lanzar una excepción si se produce un error. Si no queremos ser tan radicales y queremos que se siga ejecutando el programa manejando lo que se hace, podemos y usar la sentencia //try//: import requests res = requests.get('https://inventwithpython.com/page_that_does_not_exist') try: res.raise_for_status() except Exception as exc: print('Hubo un probema: %s' %(exc)) print ("\nEl programa continúa") ==== Guardar archivos en el disco duro ==== Para guardar el archivo descargado, usamos las funciones **open()** y **write()** habituales. \\ Sólo tenemos que tener en cuenta un par de cosas: * Deben de abrirse (open) en formato 'wb' (escritura binaria) independientemente del tipo de archivo (para mantener la codificación unicode del texto). * Usar el método **ither_content(**número de bytes**)**, que divide el archivo en porciones del número de bytes especificado, que va guardando. En resumen: - Llamada a requests.get() para descargar el archivo. - Llamada a open() con 'wb' para crear un nuevo archivo que se escribirá en modo binario. - Bucle con el método iter_content(). - Llamar a write en cada iteración del bucle para escribir (guardar) el contenido. - Cerrar el archivo con close(). import requests res = requests.get('https://automatetheboringstuff.com/files/rj.txt') res.raise_for_status() playFile = open('RomeoAndJuliet.txt', 'wb') for chunk in res.iter_content(100000): playFile.write(chunk) ===== Módulo bs4 ===== El módulo //Beautiful Soup version 4// tampoco forma parte de python, y puede instalarse con: pip install --user beautifulsoup4 import bs4 El módulo **bs4** sirve para parsear código HTML. \\ **Parsear**: Analizar e identificar partes de algo.\\ De este modo, la idea es poder identificar los elementos HTML que nos interese y recuperarlos para extraer información. \\ Para poder trabajar de este modo, necesitamos convertir la información del HTML en un objeto tipo //BeautifulSoup//, para lo que usamos el método **bs4.BeautifulSoup()**. El método **bs4.BeautifulSoup()** necesita un string con el texto del HTML que será parseado, el cual es posible obtenerlo con la función requests.get() que vimos anteriormente, y extraerlo con el atributo .text \\ import requests, bs4 res = requests.get('https://nostarch.com') res.raise_for_status() noStarchSoup = bs4.BeautifulSoup(res.text, 'html.parser') # El "parseador" html.parser viene integrado en Python type(noStarchSoup) # También es posible pasar un documento HTML que se encuentre en local con la función open() exampleFile = open('example.html') exampleSoup = bs4.BeautifulSoup(exampleFile, 'html.parser') type(exampleSoup) # También puede usarse el parseador 'lxml', más rápido que el que viene integrado en python. PAra ello hay que instalar el módulo lxml con el comando //pip install --user lxml//. ==== Encontrar elementos ==== Para identificar los elementos que interesen en el HTML, usaremos los selectores CSS. \\ Para obtener estos elementos usaremos el método **.select()**\\ {{ :python:selectores_bs4.png?500 |}} Se pueden utilizar varios patrones de selectores para realizar búsquedas más sofisticadas, por ejemplo: //soup.select('p #author')// \\ El método **.select** devuelve una lista de objetos tipo //tag//, que es como BeautifulSoup representa los elementos HTML. Pueden ser pasados a string sin problemas con la función str(). \\ Los elementos tipo "tag", además tienen un atributo **.attrs**, que muestra los atributos HTML del elemento como un variable tipo diccionario.\\ También es posible obtener el texto que se encuentra asociado a un elemento HTML (el que aparece en la web) a través del método **.getText()**. Suponemos el siguiente código HTML The Website Title

Download my Python book from my website.

Learn Python the easy way!

By Al Sweigart

Podemos buscar elementos del siguiente modo, directamente en la terminal de python: >>> import bs4 >>> exampleFile = open('example.html') >>> exampleSoup = bs4.BeautifulSoup(exampleFile.read(), 'html.parser') >>> elems = exampleSoup.select('#author') >>> type(elems) # elems is a list of Tag objects. >>> len(elems) 1 >>> type(elems[0]) >>> str(elems[0]) # The Tag object as a string. 'Al Sweigart' >>> elems[0].getText() 'Al Sweigart' >>> elems[0].attrs {'id': 'author'} >>> pElems = exampleSoup.select('p') >>> str(pElems[0]) '

Download my Python book from my website.

' >>> pElems[0].getText() 'Download my Python book from my website.' >>> str(pElems[1]) '

Learn Python the easy way!

' >>> pElems[1].getText() 'Learn Python the easy way!' >>> str(pElems[2]) '

By Al Sweigart

' >>> pElems[2].getText() 'By Al Sweigart'
==== Obtener datos de atributos de elementos ==== Para obtener fácilmente los valores de los atributos de un elemento (objeto tipo tag), podemos usar el método **get()**. Se le pasa el string del nombre de un atributo, y devuelve su valor. Vemos un ejemplo en la consola de Python: >>> import bs4 >>> soup = bs4.BeautifulSoup(open('example.html'), 'html.parser') >>> spanElem = soup.select('span')[0] >>> str(spanElem) 'Al Sweigart' >>> spanElem.get('id') 'author' >>> spanElem.get('some_nonexistent_addr') == None True >>> spanElem.attrs {'id': 'author'} ===== Módulo selenium =====