La paradoja del acceso a la información en Internet - Scrapea lo que sea con Python
Uno de los problemas más absurdos con los que me encuentro al diseñar programas que recopilen información en internet es la paradoja que paso a desarrollar en el siguiente artículo.
¿Nos regalan la información?
Cuando entramos a un sitio web, nuestro ordenador accede a toda la información desplegada. La inercia hace pensar que nosotros estamos accediendo a un lugar externo, cuando es el lugar externo el que nos envía a nosotros toda la información.
Imagínate que en lugar de entrar en Google y escribir Steemit
, le enviaras una carta a Google que dijera "¡Eh Google, mándame la información que tienes relacionada con Steemit
!" y a los tres días viniera una revista a tu casa, con un montón de Códigos QR con enlaces a las páginas relacionadas a esta red social, junto a algunos anuncios. Todo ello también podría correr sobre el protocolo de IP sobre palomas mensajeras.
Este soy yo creyendo navegar por Internet
Parece absurdo pero esto es lo que realizan todas las páginas web. Nos envía la información a nuestra dirección IP y el navegador la lee y la muestra en nuestra pantalla.
Lo interesante es que en la sociedad cala mucho eso de la piratería y el derecho de propiedad, pero las páginas web son también contenido digital, ¿no? ¿Y la información? ¿Dónde entra esta categoría? Si yo pongo un sensor en mi barrio y luego quiero vender esta información, ¿cómo la protejo de saber que no será revendida?
Imposible de parar
Esta paradoja llega a niveles absurdos. Veamos un ejemplo: Google tiene un servicio de búsquedas automatizadas mediante una API. Para los que no sabeis de desarrollo, quiere decir que podemos adquirir información de Google sin pasar por el navegador. El servicio provee una capa de 100 consultas gratuitas al día, sin embargo a partir de estas cuesta 5$ por cada 1000 consultas adicionales hasta un máximo de 10000 consultas al día (50$).
Pero podemos diseñar algo parecido muy fácilmente (20 líneas de código con Python):
import re
from bs4 import BeautifulSoup # pip3 install bs4
import requests # pip3 install requests
from pprint import pprint
QUERY = "steemit"
START = 0
URL = "https://www.google.com/search?source=hp&q=%s&start=%d" % (QUERY, START)
content = requests.get(URL).text
soup = BeautifulSoup(content, "lxml")
responses = []
for container in soup.find_all("h3"):
title = container.text
href_cont = container.find("a")["href"]
regex = re.search(r"(?<=/url\?q=)(.+)(?=&sa=U&ved)", href_cont)
link = regex.group(0)
responses.append(dict(title=title, link=link))
print("\n\tInformación obtenida de la búsqueda: %s\n" % URL)
pprint(responses)
.
Es probable esta forma de scraping no pasara desapercibida por Google si fuera realizada masivamente desde una IP, pero existen otras formas de las que hablaremos más adelante. Lo paradójico aquí es que la gigante empresa se dedica a hacer lo mismo para ganar dinero con su publicidad: scraping en cantidades masivas a múltiples páginas web para indexar el contenido y servir de redirección a sus usuarios.
Sin embargo otras empresas como Facebook o el buscador Bing si permiten la libre extracción de información y proveen heramientas para ello. Esta gente de Google se merece un meme basado en hechos reales:
Lo siento, esta no es la ventanilla de quejas por el olor de Youtube
Scraping dinámico
Otro ejemplo: hace poco he creado un scraper para la web de milanuncios.com. No le he dado utilidad, simplemente me pareció un proyecto interesante debido a que ellos tienen una protección contra robots. Si intentamos obtener sus webs con la biblioteca requests
de Python nos devolverá un mensaje tipo: "oye campeón, creo que estás intentando acceder a la web sin navegador o con alguna clase de sistema que anula la ejecución del Javascript de la página, sospecho que eres un robot". Además, no veremos el HTML ya que todo el código se carga mediante Javascript.
La solución pasa por esto, es decir, scraping dinámico:
from pyvirtualdisplay import Display # pip3 install pyvirtualdisplay
from selenium import webdriver # pip3 install selenium
from bs4 import BeautifulSoup
import time
url = "https://www.milanuncios.com/anuncios/masajes-relajantes-en-jerez.htm"
display = Display(visible=0, size=(800, 600))
display.start()
browser = webdriver.Firefox() # Necesitas geckodriver y Mozilla Firefox
browser.get(url)
time.sleep(.8)
soup = BeautifulSoup(browser.page_source, "html.parser")
print(soup.find(class_="aditem-detail-title"))
browser.quit()
.
Mediante esta técnica abrimos un navegador con un entorno de pruebas para aplicaciones web como selenium
, esperamos a ejecutar el Javascript de la página y obtenemos el código fuente. Gracias a la biblioteca pyvirtualdisplay
(la cual usa Xvfb), virtualizamos la navegación y parece que no se abre ningún navegador, dando la sensación de que estamos realizando puro scraping.
Existen muchas otras técnicas y herramientas para realizar esto y también protecciones para evitarlo en tus sitios web, pero vayamos al caso más extremo y terminemos la práctica de una vez por todas.
Simulando la interacción humana
Si te pasas por este archivo, verás una clase de Python para obtener el control de tu ordenador gracias a un mouse que simula los fallos de movimiento de una persona real. Se puede configurar para tener más o menos tolerancia al movimiento herrático.
Ponte en la situación de tener que extraer información de un sitio web pero no hay manera. Si has intentado todo lo anterior y no ha dado resultado puedes intentar descagar y parsear la web en PDF o en otro formato. Pero si no puedes usar la virtualización de un sistema con Docker u otra herramienta e interactuar con el ratón a lo Rambo.
Puedes usar otras herramientas como autopy para obtener bits de la pantalla y cosas así para no perderte. Además puedes usar Reconociento óptico de caracteres con pytesseract si la web está escrita a prueba de bombas nucleares.
Si todo lo anterior falla puedes contratar esclavos para automatizar el proceso
No hace falta decir que también podemos ejecutar tareas con el ratón. ¡Se te acabó pulsar todos los anuncios de Neobux diariamente!
Los negocios basados en click
Esto me hace pensar que los anuncios basados en la interacción del usuario con una interfaz gráfica de usuario son tan accesibles por robots como las APIs, así que lo único que realizan los webmasters al no proveer interfaces de programación de aplicaciones es un pequeño acertijo práctico de recordatorio del DOM a los desarrolladores backend, así no perderemos trabajos.
La inmensa paradoja es que poca gente conoce esta realidad que sólo reside en las cabezas de los freaks, pero los gigantes del mercado lo usan constantemente, proporcionándoles una inmensa ventaja contra los competidores de tamaño mediano. ¿A quién le interesa que las compañías musicales puedan estar levantando máquinas virtuales a destajo y votando por sus propios vídeos de Youtube? ¿A quién le importó cuando en otrora compraran sus propios discos el mismo día de salida al mercado?
Es decir, que tu tiempo delante de la pantalla recibiendo información de Google es oro para ellos, como nos recuerdan los desarrolladores del proyecto BasicAttentionToken. ¿Será esta revalorización del tiempo que pasamos delante de las pantallas uno de los pilares de la obsolescencia del trabajo?
Es más, ¿cómo sabe una empresa que estoy utilizando sus datos si ni siquiera pueden detener ni el compartimiento de archivos pesados? Simplemente es un secreto a voces porque el público mainstream no lo utiliza, pero, ¿si saliera un gran software que realizara estas tareas, por pensar, de forma descentralizada en una blockchain (estilo Golem) que acabaríamos haciendo?