tx3bas's picture
Update app.py
4d3864d verified
import gradio as gr
import requests
from bs4 import BeautifulSoup
from urllib.parse import quote
from itertools import combinations
# Paleta de colores
color_palette = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#bcbd22', '#17becf', '#ff6666', '#4dff4d', '#6666ff', '#ffcc00', '#993399', '#00cc99', '#ff5050', '#33adff', '#ff9966']
def buscar_google(query, hl='es', num_results=10):
all_results = []
for start in range(0, num_results, 10):
url = f"https://www.google.com/search?q={quote(query)}&hl={hl}&start={start}"
headers = {
"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"
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
search_results = soup.find_all('div', attrs={'class': 'tF2Cxc'})
all_results.extend(search_results)
serp_data = []
for i, result in enumerate(all_results[:num_results]):
header = result.find('h3')
header = header.text if header else "Sin título"
link = result.find('a', href=True)['href']
link_clean = link.split('&')[0].split('=')[1] if 'url?q=' in link else link
serp_data.append({"Posición": i + 1, "URL": link_clean})
return serp_data
def identificar_urls_comunes(serps):
all_urls = [url for serp in serps for url in serp]
urls_comunes = {url for url in all_urls if all_urls.count(url) > 1}
return urls_comunes
def calcular_porcentajes_similaridad(serp_results, min_length):
porcentajes = {}
for combo in combinations(serp_results.keys(), 2):
urls_serp1 = [entry["URL"] for entry in serp_results[combo[0]][:min_length]]
urls_serp2 = [entry["URL"] for entry in serp_results[combo[1]][:min_length]]
set_urls_serp1 = set(urls_serp1)
set_urls_serp2 = set(urls_serp2)
intersection = len(set_urls_serp1 & set_urls_serp2)
union = len(set_urls_serp1 | set_urls_serp2)
porcentaje_base = (intersection / union) * 100 if union > 0 else 0
bonificacion = 0
if urls_serp1[:2] == urls_serp2[:2]:
bonificacion += 20
if any(url in urls_serp2[:3] for url in urls_serp1[:3]):
bonificacion += 15
porcentaje_final = min(100, porcentaje_base + bonificacion)
# Redondear al múltiplo de 10 más cercano
porcentaje_final = round(porcentaje_final / 10) * 10
porcentajes[combo] = porcentaje_final
return porcentajes
def obtener_color_porcentaje(porcentaje):
if porcentaje >= 80:
return 'red'
elif porcentaje >= 60:
return '#FFA07A' # Rojo anaranjado
elif porcentaje >= 40:
return '#F0E68C' # Amarillo anaranjado
elif porcentaje >= 20:
return '#85e985' # Verdoso
else:
return 'green'
def generar_html_con_colores(serp_results, urls_comunes, min_length):
url_color_map = {url: color_palette[i % len(color_palette)] for i, url in enumerate(urls_comunes)}
html_table = "<details style='padding: 10px; background: #f3f3f3; border: solid 0; border-radius: 8px; margin-top: 10px;'><summary>Ver Resultados</summary><table border='1'><tr><th>Posición</th>"
keywords = list(serp_results.keys())
for keyword in keywords:
html_table += f"<th>{keyword}</th>"
html_table += "</tr>"
# Usar min_length para limitar el número de filas en la tabla
for i in range(min_length):
html_table += f"<tr><td>{i + 1}</td>"
for keyword in keywords:
if i < len(serp_results[keyword]):
entry = serp_results[keyword][i]
url = entry["URL"]
display_url = f"<a href='{url}' target='_blank' style='color:{url_color_map.get(url, '#c3c3c3')}'>{url}</a>"
html_table += f"<td>{display_url}</td>"
else:
html_table += "<td></td>"
html_table += "</tr>"
html_table += "</table></detais>"
return html_table
def analyze_keywords(keywords):
keywords_list = [keyword.strip() for keyword in keywords.split(',')]
serp_results = {keyword: buscar_google(keyword) for keyword in keywords_list}
# Determinar el mínimo número de resultados devueltos entre todas las búsquedas
min_length = min(len(serp) for serp in serp_results.values())
urls_por_keyword = [[entry["URL"] for entry in serp][:min_length] for serp in serp_results.values()]
urls_comunes = identificar_urls_comunes(urls_por_keyword)
html_table = generar_html_con_colores(serp_results, urls_comunes, min_length)
porcentajes_similaridad = calcular_porcentajes_similaridad(serp_results, min_length)
similaridad_html = generar_html_similaridad(porcentajes_similaridad) # Utilizar la función para generar HTML de similaridad
return similaridad_html , html_table
def generar_html_similaridad(porcentajes_similaridad):
similaridad_html = "<div><strong>Porcentajes de Similaridad:</strong><br>"
for combo, porcentaje in porcentajes_similaridad.items():
color = obtener_color_porcentaje(porcentaje)
similaridad_html += f"{combo[0]} & {combo[1]}: <span style='color:{color};'>{porcentaje}%</span><br>"
similaridad_html += "</div>"
return similaridad_html
iface = gr.Interface(
fn=analyze_keywords,
inputs="text",
outputs=["html", "html"],
title="<div style='margin:0 auto;text-align:center'><div style='margin:0 auto;text-align:center'><img style='width:100px;display: inline-table;margin-bottom:-10px' src='https://artxeweb.com/media/files/intencion-de-busqueda.jpg'><p>Similaridad de búsquedas</p></div>",
description="<p style='margin-bottom:10px;text-align:center;background: #ffffff; padding: 8px; border-radius: 8px; border-width: 1px; border: solid 1px #e5e7eb;'>Introduce las keywords separadas por comas para encontrar coincidencias en los resultados de búsqueda de Google. Las URLs comunes entre las búsquedas se resaltarán en colores únicos y se mostrará el porcentaje de similaridad.</p>",
article="<div style='margin-top:10px'><p style='text-align: center !important; background: #ffffff; padding: 5px 30px; border-radius: 8px; border-width: 1px; border: solid 1px #e5e7eb; width: fit-content; margin: auto;'>Desarrollada por <a style='text-decoration: none !important; color: #e12a31 !important;' href='https://artxeweb.com/'>© Artxe Web</a></p></div>"
)
iface.launch()