Scraper de SERPs y URL con Python

Script Python para Scrapear contenido de las SERPs de Google

Ayer, 7 de Marzo de 2023, Edu Laborda me invitó a su directo para hablar un poco de Inteligencia artificial y Python, como prometí en ese directo, compartiría el script explicado paso por paso y aquí estamos, cumpliendo como un campeón. Empecemos.

¿Qué hace este código?

  • Este código tiene 2 funcionalidades + 1 extra para el plagio y similitud de textos a nivel de Procesamiento del Lenguaje natural.
    • Con la opción 1, puedes coger una URL de internet (funcionará normalmente bien si es de un WordPress), pasarla por el script y este le sacará el texto de dicha URL y además le pedirá a OpenAI que en base a ese contenido, te genere uno nuevo con un lenguaje que una persona mayor entienda.
    • Con la opción 2, podrás indicar una palabra clave como por ejemplo «que es bitcoin», de nuevo marcarás opción 1 para scrapear SERPs de google.es y 2 para google.co.uk, acto seguido este script cogerá los primeros resultados de la SERP, les extraerá el contenido, los mostrará por la consola de comandos y generará un csv donde guardará dichos contenidos.

¿Qué otras ideas podría desarrollar con los conocimientos de este Script?

Pues mira, no sé si tú que estás leyendo este texto tienes mucha experiencia con programación o con Python en sí mismo pero, a partir de este ejemplo puedes desarrollar cosas como por ejemplo:

  • Hacer un scraper de contenidos de Google a nivel mundial, sacando los resultados de una palabra clave (traduciéndola a cada idioma), sacar sus títulos, descriptions, urls y el contenido en sí mismo. Luego ya con todo ese contenido puedes hacer lo que se te ocurra como por ejemplo desarrollar un algoritmo que vaya deshaciéndose de aquella información que sea redundante y crear un PDF cuya información sea la más completa de internet.
  • Si eres un SEO Black Hat y te gusta hacer automáticas, podrás dejar de hacer basura de contenido inventado sin sentido que pronto caducará y hacer contenido con información real, con contexto, también te digo que a mi no me gusta automatizarlo todo todo, a sabiendas de que el resultado puede ser una basura porque se escapa a tu control si lo dejas todo a una IA pero, no es difícil hacer un script que te genere contenidos automáticamente y mejor que las herramientas que se ven en twitter.
  • Puedes analizar una SERP para ver como de plagiados están los contenidos de la SERP y ver con tus propios ojos que eso que siempre se ha dicho de que para posicionar en Google tu contenido debe ser mínimo un 75% original es una mentira como un templo de grande.
  • Puedes comprobar fácilmente si tus URLs (y las de tus competidores) están indexadas o no cuando lanzas un comando site: en el buscador.
  • Puedes ver las métricas de Core Web Vitals de cualquier sitio que te plazca analizar pero, de cada URL me refiero para ver cuales son las mejores y las peores.
  • Ecommercetools no es la que utilizo yo para acceder al Knowledge Graph de Google pero, también si te las buscas puedes ver el árbol de conocimiento de Google para sacar entidades y trabajarlas en tu contenido.

Bueno, pues si estudias las librerías utilizadas en el script y estás tan loco por la tecnología como yo, seguro que se te ocurren mil ideas más para sacar provecho a todas las librerías que se están usando (y a lo mejor solo he mencionado unas cuantas cosas que puedes desarrollar con una sola de las librerías, hay mucho más).

Recomendaciones para su uso

  • Este python script tiene algunas librerías que podrían dar problemas de incompatibilidad por tema de versiones, yo uso actualmente la versión 3.10.0 de Python.
  • Crea un entorno virtual y instala todos los recursos necesarios en él, es tan fácil como abrir un terminal en tu pc, crear una carpeta y ejecutar el comando python -m venv nombre_entorno_virtual
  • Cuando ya lo tienes creado, tienes que acceder a la carpeta que te genera donde estarán todos los archivos que necesitas para que funcione el mencionado entorno.
  • Para activar el entorno, debes una vez dentro de su carpeta, ejecutar el siguiente comando ./Scripts/activate y te darás cuenta que está funcionando cuando veas en la línea de comandos que aparece el nombre del entorno en verde y entre paréntesis.
contratar seo jorge hudson

Librerías necesarias para que funcione el script

Habrá algunas librerías que tengas instaladas ya de base cuando instalas Python pero, las que se usan y como se instalan son las siguientes:

LibreríaComando de instalación
openaipip install openai
osViene instalada de serie
pandaspip install pandas
googletranspip install googletrans
difflibViene instalada de serie
trafilaturapip install trafilatura
sklearnpip install sklearn
ecommercetoolspip install ecommercetools

Script Python

# Librerías que necesitas importar
import openai # Para las peticiones de openai 
import os # Para lanzar comandos en tu equipo
import pandas as pd # Sirve para crear DataFrames y generar CSVs (También permite otros archivos)
from googletrans import Translator # Traductor de Google
from difflib import SequenceMatcher # Con esta mediremos el plagio a nivel de escritura
from trafilatura import extract, fetch_url # Librería para scrapear fácilmente una web (Aunque no cualquiera)
from key import CLAVE # Importo mi clave API para que no me hagáis gasto.
from sklearn.metrics.pairwise import cosine_similarity # Mediremos la similitud a nivel contextual de un texto con otro utilizando el coseno.
from sklearn.feature_extraction.text import TfidfVectorizer # Convertimos un texto en vectores numéricos que usa la técnica TF-IDF
from ecommercetools import seo # Librería para scrapear Google, extraer sitemaps entre otras cosas, muy fácil de usar.

# Funciones
def similarity_nlp(texto1="vacio",texto2="Vacio"):
    #TF-IDF - Calculamos Similarity COSENO
    if (texto1 == "") or (texto2==""):
        similarity_nlp_data = "--"
    else:
        vectorizer = TfidfVectorizer()
        X = vectorizer.fit_transform([texto1,texto2])
        similarity_matrix = cosine_similarity(X,X)
        similarity_nlp_data = int((similarity_matrix.item(0,1))*100)
    return similarity_nlp_data

def scrape_url_and_openai():
    url = input("Introduce una URL para scrapear: ")
    req = fetch_url(url) # Accede a la URL que le indiques por consola
    contenido = extract(req, include_tables=None, include_links=None, include_comments=None, include_images=None) # Extrae el texto plano sin tablas, links, imagenes o comentarios.
    
    os.system("cls") # Lanzamos un comando para limpiar la pantalla
    
    # A continuación mostramos el contenido que hemos sacado de la URL
    print(f"""
    \n======= CONTENIDO SCRAPEADO =======
    {contenido}
    ===================================
    """)
    
    MODEL = "gpt-3.5-turbo" # Este es el modelo con el que usaremos OpenAI.
    openai.api_key = CLAVE # Tenemos que instanciar openai con nuestra clave API
    # Construimos la petición a OpenAI, indicándole modelo, premisa, el contenido que le pasaremos y la temperatura
    response = openai.ChatCompletion.create(
        model=MODEL,
        messages=[
            #Aquí va el prompt
            {"role": "system", "content": "Resume este contenido de forma que pueda utilizarlo para Google Business Profile"},
            {"role": "user", "content": str(contenido)} # Le pasamos el contenido que debe reescribir.
        ],
        temperature=0.3, # Cuanto más alta la temperatura, mayor capacidad de inventiva tiene 
    )

    salida = response['choices'][0]['message']['content'] # La respuesta de OpenAI
    total_tokens = response['usage']['total_tokens'] # Total de tokens gastados
    similitud = similarity_nlp(str(contenido), str(salida)) # Llamada a la función de comparación de similitud entre contenido y respuesta
    plagio = SequenceMatcher(False, contenido, salida).ratio() # Comparación del plagio de la respuesta contra el contenido
    PRECIO = total_tokens/1000 * 0.02 # Precio de tokens

    print(salida)

    print(f"\nLa similitud entre los textos introducidos es de {similitud} % | NLP")
    print(f"\n El plagio entre los textos introducidos es de {plagio*100}% | DiffLib\n")
    print("Tokens Gastados: "+ str(total_tokens)+"\n"+"Costo: "+str(PRECIO)+"€")

def scraper_serps_and_extract_content():
    translator = Translator()
    keyword = input("Introduce la keyword que quieras: ") # Keyword a buscar en la SERP
    pais = int(input("¿Dónde quieres buscar? 1. Google.es 2. Google.co.uk : ")) # Pedir un número. 

    if pais == 1:
        serps = seo.get_serps(keyword, domain="google.es")
        urls = []
        contenidos = []
        region = []
        print(serps)
        print("\n ======== CONTENIDOS ========")
        for url in serps['link']:
            try:
                req = fetch_url(url)
                contenido = extract(req, include_tables=None, include_links=None, include_comments=None, include_images=None)
                if contenido:
                    print(f"""
                    URL -> {url}
                    Contenido:\n
                    {contenido}
                    """)
                    urls.append(url)
                    contenidos.append(contenido)
                    region.append("España")
                    print("\n")
                else:
                    print("No se pudo obtener el contenido")
            except:
                print(f"Error al obtener el contenido de url: {url}")

        pd.DataFrame(list(zip(urls, contenidos, region)), columns=["URL", "Contenido", "Región SERP"]).to_csv(f"./contenidos_{keyword}.csv", index=False)
    
    elif pais == 2:
        serps = seo.get_serps(keyword, domain="google.co.uk")
        urls = []
        contenidos = []
        region = []
        print(serps)
        print("\n ======== CONTENIDOS ========")
        for url in serps['link']:
            try:
                req = fetch_url(url)
                contenido = extract(req, include_tables=None, include_links=None, include_comments=None, include_images=None)
                if contenido:
                    print(f"""
                    URL -> {url}
                    Contenido:\n
                    {translator.translate(contenido, dest="es").text}
                    """)
                    urls.append(url)
                    contenidos.append(translator.translate(contenido, dest="es").text)
                    region.append("Reino Unido")
                    print("\n")
                else:
                    print("No se pudo obtener el contenido")
            except:
                print(f"Error al obtener el contenido de url: {url}")

        pd.DataFrame(list(zip(urls, contenidos, region)), columns=["URL", "Contenido", "Región SERP"]).to_csv(f"./contenidos_{keyword}.csv", index=False)

print("""
=== BIENVENIDO AL SCRIPT DE JORGE HUDSON ===
Introduce alguna opción de las siguientes:
    1. Scrapear un contenido a partir de una URL y generar un nuevo contenido.
    2. Scrapear SERPs de España o Reino Unido y extraer los contenidos.
""")

respuesta = input("¿Cuál de las opciones escoges?: ")

match respuesta:
    case "1":
        scrape_url_and_openai()
    case "2":
        scraper_serps_and_extract_content()