Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import requests
|
| 4 |
+
from bs4 import BeautifulSoup
|
| 5 |
+
import re
|
| 6 |
+
from IPython.core.display import display, HTML
|
| 7 |
+
from urllib.parse import urlparse
|
| 8 |
+
|
| 9 |
+
def limpiar_dominio(dominio):
|
| 10 |
+
dominio_limpio = re.sub(r"https?://", "", dominio)
|
| 11 |
+
dominio_limpio = re.sub(r"^www\.", "", dominio_limpio)
|
| 12 |
+
dominio_limpio = dominio_limpio.split(".")[-2] if len(dominio_limpio.split(".")) > 1 else dominio_limpio
|
| 13 |
+
dominio_limpio = re.sub(r"\.[a-zA-Z]{2,}$", "", dominio_limpio)
|
| 14 |
+
dominio_limpio = dominio_limpio.capitalize()
|
| 15 |
+
return dominio_limpio
|
| 16 |
+
|
| 17 |
+
def buscar_google(query, dominio, hl='es', num_results=100):
|
| 18 |
+
all_results = []
|
| 19 |
+
posiciones_dominio = []
|
| 20 |
+
posiciones_dominio_exacto = []
|
| 21 |
+
url_objetivo = dominio
|
| 22 |
+
dominio_objetivo = urlparse(url_objetivo).netloc
|
| 23 |
+
|
| 24 |
+
table_html = "<table border='1'><tr><th>Posici贸n</th><th>T铆tulo</th><th>URL</th></tr>"
|
| 25 |
+
|
| 26 |
+
estilo = "font-size:19px; color: #ed4b4b;"
|
| 27 |
+
|
| 28 |
+
for start in range(0, num_results, 10):
|
| 29 |
+
url = f"https://www.google.com/search?q={query}&hl={hl}&start={start}"
|
| 30 |
+
headers = {
|
| 31 |
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.3"
|
| 32 |
+
}
|
| 33 |
+
response = requests.get(url, headers=headers)
|
| 34 |
+
soup = BeautifulSoup(response.text, 'html.parser')
|
| 35 |
+
search_results = soup.find_all('div', attrs={'class': 'tF2Cxc'})
|
| 36 |
+
all_results.extend(search_results)
|
| 37 |
+
|
| 38 |
+
for i, result in enumerate(all_results[:num_results]):
|
| 39 |
+
header = result.find('h3')
|
| 40 |
+
header = header.text if header else "Sin t铆tulo"
|
| 41 |
+
link = result.find('a', href=True)['href']
|
| 42 |
+
link_clean = re.search("(?P<url>https?://[^\s]+)", link).group("url")
|
| 43 |
+
dominio_resultado = urlparse(link_clean).netloc
|
| 44 |
+
|
| 45 |
+
estilo_dominio = ""
|
| 46 |
+
if dominio_objetivo in dominio_resultado:
|
| 47 |
+
posiciones_dominio.append(i + 1)
|
| 48 |
+
if link_clean == url_objetivo:
|
| 49 |
+
posiciones_dominio_exacto.append(i + 1)
|
| 50 |
+
estilo_dominio = estilo
|
| 51 |
+
|
| 52 |
+
table_html += f"<tr><td>{i+1}</td><td>{header}</td><td><span style='{estilo_dominio}'>{link_clean}</span></td></tr>"
|
| 53 |
+
|
| 54 |
+
table_html += "</table>"
|
| 55 |
+
|
| 56 |
+
if len(posiciones_dominio) > 1 and 1 in posiciones_dominio:
|
| 57 |
+
mensaje = f"Parasitaci贸n SEO: {url_objetivo} se encuentra en las posiciones {posiciones_dominio} 馃"
|
| 58 |
+
estilo = "font-size:19px; color: #ffd700;"
|
| 59 |
+
elif len(posiciones_dominio) > 1:
|
| 60 |
+
mensaje = f"Canibalizaci贸n: {url_objetivo} se encuentra en las posiciones {posiciones_dominio} 馃槙"
|
| 61 |
+
estilo = "font-size:19px; color: #ed4b4b;"
|
| 62 |
+
elif len(posiciones_dominio) == 1 and len(posiciones_dominio_exacto) == 0:
|
| 63 |
+
mensaje = f"Canibalizaci贸n: URL diferente del dominio en la posici贸n {posiciones_dominio[0]} 馃槙"
|
| 64 |
+
elif len(posiciones_dominio) == 1:
|
| 65 |
+
mensaje = f"Sin canibalizaci贸n: {url_objetivo} se encuentra en la posici贸n {posiciones_dominio[0]} 馃槙"
|
| 66 |
+
estilo = "font-size:19px; color: #26d52d;"
|
| 67 |
+
else:
|
| 68 |
+
mensaje = f"{url_objetivo} no se encuentra en el top 100 馃槙"
|
| 69 |
+
estilo = "font-size:19px; color: #ed4b4b;"
|
| 70 |
+
|
| 71 |
+
return mensaje, table_html
|
| 72 |
+
|
| 73 |
+
def canibalizacion_interface(url, keyword):
|
| 74 |
+
mensaje, tabla = buscar_google(keyword, url)
|
| 75 |
+
return mensaje, tabla
|
| 76 |
+
|
| 77 |
+
iface = gr.Interface(
|
| 78 |
+
fn=canibalizacion_interface,
|
| 79 |
+
inputs=["text", "text"],
|
| 80 |
+
outputs=["text", "html"],
|
| 81 |
+
title="Buscador de Canibalizaciones en Google",
|
| 82 |
+
description="Encuentra posibles canibalizaciones y parasitaciones en Google a partir de una URL y una palabra clave.",
|
| 83 |
+
article="Ingrese la URL y la palabra clave para buscar canibalizaciones.",
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
iface.launch()
|