File size: 6,558 Bytes
7d5bdaa
 
79a852d
7d5bdaa
4289557
79a852d
bb6c7f2
 
9b27228
bb6c7f2
 
9b27228
 
7d5bdaa
9b27228
 
 
 
 
 
 
 
bb6c7f2
9b27228
 
 
 
bb6c7f2
f70cf4c
bb6c7f2
 
 
40ee9ec
 
 
 
24e94d9
3f22a7b
3c9b5a0
 
ea51efd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60e5756
 
ea51efd
 
3c9b5a0
 
60e5756
 
 
 
 
 
 
 
5b21307
60e5756
 
 
3f22a7b
cfb1ea2
40ee9ec
cfb1ea2
ea35f8f
bb6c7f2
4289557
 
 
bb6c7f2
 
cfb1ea2
 
24e94d9
4289557
 
 
 
4d3864d
c2901ed
bb6c7f2
7d5bdaa
 
ea35f8f
bb6c7f2
 
4289557
 
 
3f22a7b
 
 
4289557
3f22a7b
40ee9ec
 
e34bc90
4289557
3f22a7b
e34bc90
3c9b5a0
d820ddc
4289557
60e5756
 
 
 
 
 
 
 
5b21307
7d5bdaa
e3fa749
f15173b
 
7198abe
5b21307
 
7d5bdaa
bb6c7f2
3c9b5a0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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()