Día a día trabajamos con Google, ya no nos imaginamos la vida sin este buscador. Por ello hoy vamos a ver cómo crear nuestro buscador de Google a través de Python. En menos de 100 líneas se puede conseguir, y el resultado que obtendremos será Título de la página y su enlace.
¿Que necesitamos?
Python 3 con la librería requests y BeautifulSoup.
¿Cómo se ejecutará el buscador?
Nosotros solo tendremos que agregar a la llama algunos argumentos:
Alternativas o cambios en el script que pueden interesar
Como siempre se dice, el límite es tu imaginación, pero por destacar algunos puntos.
¿Cómo se ha implementado?
La idea con la que se ha llevado a cabo el script es el siguiente: hacemos una búsqueda en Google con “google.com/search?q=”, en ella a través de la librería beautifulsoup buscamos los elementos, a nosotros nos interesan los enlaces que se encuentran dentro de un h3 con clase “r”, de ahí obtenemos los títulos y los enlaces (esto puede variar si cambia el html de Google, la última modificación nos hace buscar un div con clase "jfp3ef").
Para agregar la paginación, se buscan los elementos a con clase “fl” y sacamos su valor del href, para hacer la petición, se debe saber que es una ruta relativa y necesitamos agregar la parte de google.com.
Por si no queda claro a que me refiero con la paginación de Google, lo que busco es los números que se ven en la figura 3.
Cuando obtenemos los enlaces, podemos ver que nos encontramos al inicio con “/url?q=” y en ocasiones al final con “&sa=….”, por ello antes de guardar los enlaces, se hace una limpia del enlace.
Y todo esto es utilizado en una función que se encarga de hacer el trabajo, no es muy larga, se muestra en la figura 5.
Quedaría por ver la parte en la que se recogen los argumentos (librería argparse) y la comprobación de guardar los resultados en un fichero, ya que no aportan valor. Para ejecutar el script, bastaría con las siguientes 2 líneas:
gs = GoogleSearch()
results = gs.request_data(args.search, pages=args.pages, pause=args.time)
Con esta explicación a alto nivel se puede entender el funcionamiento y/o crear nuestro propio script.
Prueba de concepto
A continuación, para que se pueda ver en funcionamiento, dejo un vídeo probando el script.
Algunas limitaciones
Puede llegar el momento en el que Google nos tache de robot y no nos deje trabajar bien, hasta el momento no he tenido el problema. Pero si llega el caso, siempre se puede tirar de Selenium.
Referencias a librería existentes
Existen algunas librerías creadas, para Python puedes probar la siguiente: https://github.com/MarioVilas/googlesearch
Por último, puedes comprobar cómo aplicamos en nuestro Business card reader esta búsqueda para sacar Curriculums de Google, en este post de elladodelmal. Realizar este script no lleva mucho tiempo, y nos da el poder de hacer lo que queramos. ¡Hasta pronto!
¿Que necesitamos?
Python 3 con la librería requests y BeautifulSoup.
¿Cómo se ejecutará el buscador?
Nosotros solo tendremos que agregar a la llama algunos argumentos:
- La búsqueda (único obligatorio)
- La paginación máxima (por defecto solo se consulta la primera página, los 10 primeros resultados)
- El tiempo entre petición para Google (por defecto 2 segundos).
- Fichero donde guardar el resultado (por defecto se muestra por pantalla)
Alternativas o cambios en el script que pueden interesar
Como siempre se dice, el límite es tu imaginación, pero por destacar algunos puntos.
- En lugar de realizar una sola búsqueda, podemos automatizar la búsqueda de varias consultas.
- Mostrar también la descripción que da Google.
- Obtener los enlaces vídeos de youtube que se muestran en resultados.
¿Cómo se ha implementado?
La idea con la que se ha llevado a cabo el script es el siguiente: hacemos una búsqueda en Google con “google.com/search?q=
![]() |
Figura 1: Petición a Google |
![]() |
Figura 2: Aplicando paginación |
![]() |
Figura 3: Paginación de Google |
![]() |
Figura 4: Limpiando las URLs |
![]() |
Figura 5: Función para tratar las búsquedas en Google |
results = gs.request_data(args.search, pages=args.pages, pause=args.time)
Algunas limitaciones
Puede llegar el momento en el que Google nos tache de robot y no nos deje trabajar bien, hasta el momento no he tenido el problema. Pero si llega el caso, siempre se puede tirar de Selenium.
Referencias a librería existentes
Existen algunas librerías creadas, para Python puedes probar la siguiente: https://github.com/MarioVilas/googlesearch
Por último, puedes comprobar cómo aplicamos en nuestro Business card reader esta búsqueda para sacar Curriculums de Google, en este post de elladodelmal. Realizar este script no lleva mucho tiempo, y nos da el poder de hacer lo que queramos. ¡Hasta pronto!
Saludos, Josué.
ResponderEliminarSe presentó este problema al momento de compilar el código:
Traceback (most recent call last):
File "busquedas.py", line 59, in
results = gs.request_data("Exploiting site:boomernix.com", 2, 2)
File "busquedas.py", line 40, in request_data
soup, results = self.__request(url)
File "busquedas.py", line 11, in __request
soup = BeautifulSoup(response.text, features="html.parser")
TypeError: 'module' object is not callable
Y por otra parte, la variable de clase domain en que momento le das valor o la inicializas como cadena vacía?
Saludos.
Ya conteste en el otro comentario lo del error, pero lo del domain le doy el valor en el __init__ al igual que haces en el script del otro comentario, sorry! que se me paso ponerlo en el post.
Eliminarimport requests
ResponderEliminarimport BeautifulSoup
import argparse
class GoogleSearch:
def __init__(self):
self.domain = "https://www.google.com/"
def __request(self, url):
response = requests.get(url)
print response
soup = BeautifulSoup(response.text, 'html.parser')
data = soup.find_all("h3", {"class":"r"})
results = []
if data:
for d in data:
a = d.findChildren("a")[0]
link = self.__parse_url(a.get("href"))
title = a.getText()
if "/search?ie" in link:
link = self.domain + link
results.append({title:link})
return soup, results
def __pagination(self, soup, page):
try:
link = self.domain + self.__parse_url(soup.find_all("a",{"class":"fl"})[page].get("href"))
except:
link = None
return link
def __parse_ulr(self, url):
try:
return url.replace("/url?p=","").split("&sa=")[0]
except:
return url
def request_data(self, search, pages = 1, pause = 2):
print("Buscando...")
print("Maxima paginacion: {}".format(pages))
results = []
url = self.domain + '/search?q=' + search
soup, results = self.__request(url)
total_results = soup.find(id="resultStats").getText()
print("Resultados encontrados en google: {}".format(total_results))
for i in range(1, pages):
sleep(pause)
url = self.__pagination(soup, i)
if url is None:
break
s, r = self.__request(url)
results.extend(r)
print("Total de resultados: {}".format(len(results)))
return results
gs = GoogleSearch()
results = gs.request_data("Exploiting site:redes neuronales", 2, 2)
Agradecería mucho si me pudieras explicar en donde está mi error, gracias!!!!
Me aparece este error:
Buscando...
Maxima paginacion: 2
Traceback (most recent call last):
File "busquedas.py", line 60, in
results = gs.request_data("Exploiting site:redes neuronales", 2, 2)
File "busquedas.py", line 44, in request_data
soup, results = self.__request(url)
File "busquedas.py", line 12, in __request
soup = BeautifulSoup(response.text)
TypeError: 'module' object is not callable
A simple vista (teniendo en cuenta Python3), el problema viene del import de BeautifulSoup, cambialo por el siguiente "from bs4 import BeautifulSoup". Te falta también un import >> "from time import sleep".
EliminarLa siguiente línea te va a producir un error si find no devuelve resultados: "total_results = soup.find(id="resultStats").getText()". Usa primero el find y comprueba si hay algo antes de usar getText.
Luego al ser un script para scraping, si cambian los elementos de la web, se necesita ir actualizando la búsqueda, con Google ya me ha pasado en 2 ocasiones.
Perdón por tardar en contestar, agosto es un mes muy malo.
Un saludo
Hola Josué. Gracias por el post. Estoy intentando hacerlo. Hago la misma búsqueda que haces en el vídeo. "Exploiting site:boomernix.com". A ti te devuelve 146 resultados. Si busco directamente en Gloogle hoy me devuelve 149. Pero cuando ejecuto el programa no me devuelve ningún resultado. ¿Que estoy haciendo mal? Te pego el código. Creo que es el mismo que el que has puesto en el post, excepto que controlo si no me devuelve resultados para que no rompa el programa. Muchas gracias por tu ayuda.
ResponderEliminarimport requests
from bs4 import BeautifulSoup
from time import sleep
import argparse
class GoogleSearch:
def __init__(self):
self.domain = "https://www.google.com/"
def __request(self, url):
response = requests.get(url)
print (response)
soup = BeautifulSoup(response.text, 'html.parser')
data = soup.find_all("h3", {"class":"r"})
results = []
if data:
for d in data:
a = d.findChildren("a")[0]
link = self.__parse_url(a.get("href"))
title = a.getText()
if "/search?ie" in link:
link = self.domain + link
results.append({title:link})
return soup, results
def __pagination(self, soup, page):
try:
link = self.domain + self.__parse_url(soup.find_all("a",{"class":"fl"})[page].get("href"))
except:
link = None
return link
def __parse_ulr(self, url):
try:
return url.replace("/url?q=","").split("&sa=")[0]
except:
return url
def request_data(self, search, pages = 1, pause = 2):
print("Buscando...")
print("Maxima paginacion: {}".format(pages))
results = []
url = self.domain + '/search?q=' + search
soup, results = self.__request(url)
total_results = soup.find(id="resultStats")
if total_results == None:
print ("No hay resultados para esta palabra")
else:
total_results_text = total_results.getText()
print("Resultados encontrados en google: {}".format(total_results_text))
for i in range(1, pages):
sleep(pause)
url = self.__pagination(soup, i)
if url is None:
break
s, r = self.__request(url)
results.extend(r)
print("Total de resultados: {}".format(len(results)))
return results
gs = GoogleSearch()
results = gs.request_data("Exploiting site:boomermix.com", 2, 2)
Referente a mi comentario anterior. La variable soup si tiene datos pero cuando ejecuto esta línea:
ResponderEliminardata = soup.find_all('h3', {'class':'r'})
parece que no encuentra nada y data esta vacío.
Por cierto, en el código que he pegado en el comentario anterior la url estaba mal era "Exploiting site:boomernix.com" y no "Exploiting site:boomermix.com"
Hola Emilio, al ser un scraping a las búsquedas de Google, el código de la web cambia, y por ello es posible que la línea en que se busca h3 con clase r se vea afectada.Puedes hacer una pequeña búsqueda del código que devuelve en el interprete de Python:
Eliminarimport requests
r = requests.get("https://www.google.com/search?q=github")
r.text
Y finalmente actualizas las partes de find en el código.
Un saludo
Cual sera el limite de búsquedas para que Google nos tache de robot?
ResponderEliminarNo te sabría decir un límite, nunca le he llevado al máximo, todo es probar. Lo que si puedo decirte, es que si suprimes el tiempo de espera que haces entre petición, no tardará mucho en detectarte.
EliminarHola. Tiene algun ejemplo de script que busca en google una palabra hasta encontrar un sitio web determinado y navegue determinado tiempo? Gracias.
ResponderEliminar