File size: 14,829 Bytes
79a852d
e1ec972
a7641dd
1c41a7e
6a7eabc
c8fa91e
 
 
 
df3503c
 
 
 
cfbd1f3
 
f4f4d70
cfbd1f3
 
 
df3503c
cfbd1f3
 
 
 
 
 
9d0475e
b42bcaf
 
 
 
 
 
 
 
8294e97
9d0475e
b42bcaf
 
 
 
 
 
 
 
 
9d0475e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2cb8fc4
a99cb1d
 
 
 
 
 
 
 
c8fa91e
a99cb1d
c8fa91e
 
916ba86
62efa1b
2cb8fc4
 
a99cb1d
9863bd9
 
 
 
 
bec5ee3
 
9863bd9
0a3fc58
df3503c
8294e97
cfbd1f3
0a3fc58
 
 
8294e97
0a3fc58
 
 
cfbd1f3
8294e97
 
 
 
9d0475e
9863bd9
 
c8fa91e
a99cb1d
cfbd1f3
 
 
9863bd9
9d0475e
f121a85
9863bd9
c8fa91e
748227d
 
 
cfbd1f3
 
 
9863bd9
9d0475e
f121a85
9863bd9
 
a99cb1d
cfbd1f3
 
 
9863bd9
9d0475e
f121a85
9863bd9
 
a99cb1d
cfbd1f3
 
 
a99cb1d
9d0475e
5e74413
 
 
 
cfbd1f3
 
 
5e74413
9d0475e
b42bcaf
 
 
 
cfbd1f3
 
 
 
8294e97
cfbd1f3
a99cb1d
62efa1b
 
 
 
 
 
 
f7c15e6
a99cb1d
cfbd1f3
 
 
f7c15e6
 
 
 
 
 
62efa1b
a99cb1d
62efa1b
a99cb1d
 
cfbd1f3
62efa1b
cfbd1f3
62efa1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cfbd1f3
62efa1b
a99cb1d
 
79a852d
62efa1b
5e74413
62efa1b
79a852d
8397de5
 
62efa1b
 
f4f4d70
79a852d
 
c8fa91e
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
import gradio as gr
import requests
import urllib.parse
import re
import xmltodict
from collections import Counter
import unicodedata
# Funci贸n para normalizar palabras clave (elimina tildes y convierte a min煤sculas)
def normalize_keyword(keyword):
    if isinstance(keyword, str):  # Comprobamos si es una cadena de texto
        return ''.join(c for c in unicodedata.normalize('NFD', keyword.lower()) if unicodedata.category(c) != 'Mn')
    return keyword  # Si no es una cadena, devolvemos el valor tal como est谩
# Funci贸n para obtener sugerencias de Google con un client espec铆fico (firefox, chrome, android, desktop, opera)
def fetch_google_suggestions(query, lang_code="es", client="firefox"):
    encoded_query = urllib.parse.quote(query)
    url = f"http://suggestqueries.google.com/complete/search?client={client}&hl={lang_code}&gl={lang_code}&q={encoded_query}"
    response = requests.get(url)
    if response.status_code == 200:
        try:
            return [normalize_keyword(suggestion) for suggestion in response.json()[1] if isinstance(suggestion, str)]
        except ValueError:
            print("Error decodificando JSON de Google")
            return []
    else:
        return []

# Funci贸n para obtener sugerencias de Brave
def fetch_brave_suggestions(query, lang_code="es"):
    encoded_query = urllib.parse.quote(query)
    url = f"https://search.brave.com/api/suggest?q={encoded_query}"
    response = requests.get(url)
    if response.status_code == 200:
        try:
            data = response.json()
            if len(data) > 1 and isinstance(data[1], list):
                # Reducir repeticiones en un 65%
                return [normalize_keyword(item) for item in data[1] for _ in range(int(0.35 * 5))]
            else:
                print("No se encontraron sugerencias en el formato esperado (Brave).")
                return []
        except ValueError:
            print("Error decodificando JSON de Brave")
            return []
    else:
        return []

# Funci贸n para obtener sugerencias de Qwant
def fetch_qwant_suggestions(query, lang_code="es"):
    encoded_query = urllib.parse.quote(query)
    url = f"https://api.qwant.com/api/suggest/?client=opensearch&q={encoded_query}"
    response = requests.get(url)
    if response.status_code == 200:
        try:
            data = response.json()
            if len(data) > 1 and isinstance(data[1], list):
                return [normalize_keyword(item) for item in data[1]]
            else:
                print("No se encontraron sugerencias en el formato esperado (Qwant).")
                return []
        except ValueError:
            print("Error decodificando JSON de Qwant")
            return []
    else:
        return []

# Funci贸n para obtener sugerencias de DuckDuckGo
def fetch_duckduckgo_suggestions(query, lang_code="es"):
    encoded_query = urllib.parse.quote(query)
    url = f"https://duckduckgo.com/ac/?q={encoded_query}&kl={lang_code}"
    response = requests.get(url)
    if response.status_code == 200:
        try:
            data = response.json()
            return [normalize_keyword(item['phrase']) for item in data]
        except ValueError:
            print("Error decodificando JSON de DuckDuckGo")
            return []
    else:
        return []

# Funci贸n para obtener sugerencias de YouTube usando la API anterior
def fetch_youtube_suggestions(query, lang_code="es"):
    encoded_query = urllib.parse.quote(query)
    url = f"http://suggestqueries.google.com/complete/search?client=youtube&hl={lang_code}&q={encoded_query}"
    response = requests.get(url)
    if response.status_code == 200:
        try:
            match = re.search(r'window\.google\.ac\.h\(\["[^"]*",\[(.*?)\],', response.text)
            if match:
                suggestions_data = match.group(1)
                return [normalize_keyword(suggestion) for suggestion in re.findall(r'\["([^"]+)"', suggestions_data)]
            else:
                print("No se encontraron sugerencias en el formato esperado (YouTube antiguo).")
                return []
        except Exception as e:
            print(f"Error procesando la respuesta de YouTube (antiguo): {e}")
            return []
    else:
        return []

# Funci贸n para obtener sugerencias de YouTube usando la nueva API
def fetch_youtube_suggestions_new(query, lang_code="es"):
    encoded_query = urllib.parse.quote(query)
    url = f"https://suggestqueries-clients6.youtube.com/complete/search?client=youtube&ds=yt&q={encoded_query}&hl={lang_code}"
    response = requests.get(url)
    if response.status_code == 200:
        try:
            match = re.search(r'window\.google\.ac\.h\(\["[^"]*",\[(.*?)\],', response.text)
            if match:
                suggestions_data = match.group(1)
                return [normalize_keyword(suggestion) for suggestion in re.findall(r'\["([^"]+)"', suggestions_data)]
            else:
                print("No se encontraron sugerencias en el formato esperado (nueva API de YouTube).")
                return []
        except Exception as e:
            print(f"Error procesando la respuesta de la nueva API de YouTube: {e}")
            return []
    else:
        return []

# Funci贸n para obtener sugerencias de Bing
def fetch_bing_suggestions(query, market="en-US"):
    url = "https://api.bing.com/qsml.aspx"
    params = {"Market": market, "query": query}
    headers = {"User-agent": "Mozilla/5.0"}
    response = requests.get(url, params=params, headers=headers)
    if response.status_code == 200:
        try:
            obj = xmltodict.parse(response.content)
            suggestions = obj['SearchSuggestion']['Section']['Item']
            if isinstance(suggestions, list):
                return [normalize_keyword(s['Text']) for s in suggestions]
            elif isinstance(suggestions, dict):
                return [normalize_keyword(suggestions['Text'])]
        except Exception as e:
            print(f"Error procesando la respuesta de Bing: {e}")
            return []
    else:
        return []

# Funci贸n para obtener sugerencias de Amazon
def fetch_amazon_suggestions(query, market_id="ATVPDKIKX0DER", alias="aps"):
    url = "https://completion.amazon.com/api/2017/suggestions"
    params = {"mid": market_id, "alias": alias, "prefix": query}
    response = requests.get(url, params=params)
    if response.status_code == 200:
        try:
            data = response.json()
            return [normalize_keyword(item['value']) for item in data.get('suggestions', [])]
        except ValueError:
            print("Error decodificando JSON de Amazon")
            return []
    else:
        return []

# Funci贸n para expandir la palabra clave
def expand_keyword(keyword):
    expanded_keywords = [keyword]
    for letter in 'abcdefghijklmnopqrstuvwxyz*_':
        expanded_keywords.append(keyword + " " + letter)
        expanded_keywords.append(letter + " " + keyword)
    return expanded_keywords

# Funci贸n para contar y obtener las top N sugerencias m谩s repetidas
def get_top_suggestions(suggestions, top_n=10):
    suggestion_counter = Counter(suggestions)
    return suggestion_counter.most_common(top_n)

# Funci贸n principal que muestra el top 10 combinado, top 3 de cada plataforma y una tabla completa
def main(keyword):
    expanded_keywords = expand_keyword(keyword)
    all_suggestions = {}
    google_suggestions_all = []
    duckduckgo_suggestions_all = []
    youtube_suggestions_all = []
    bing_suggestions_all = []
    amazon_suggestions_all = []
    qwant_suggestions_all = []
    brave_suggestions_all = []

    # Obtener sugerencias de Google con diferentes clients
    google_clients = ["firefox", "chrome", "android", "desktop", "opera", "safari"]
    google_combined = Counter()  # Contador combinado para sumar todas las sugerencias de Google
    for exp_keyword in expanded_keywords:
        for client in google_clients:
            google_suggestions = fetch_google_suggestions(exp_keyword, client=client)
            google_suggestions_all.extend(google_suggestions)
            google_combined.update(google_suggestions)  # Sumar las repeticiones de cada cliente de Google
            for suggestion in google_suggestions:
                all_suggestions.setdefault(suggestion, {"count": 0, "sources": set()})
                all_suggestions[suggestion]["sources"].add(f"Google ({client})")

    # Al final de todas las consultas a Google, combinamos las repeticiones en una 煤nica fuente de Google
    for suggestion, count in google_combined.items():
        all_suggestions[suggestion]["count"] += count

    # Obtener sugerencias de DuckDuckGo
    for exp_keyword in expanded_keywords:
        suggestions = fetch_duckduckgo_suggestions(exp_keyword)
        duckduckgo_suggestions_all.extend(suggestions)
        for suggestion in suggestions:
            all_suggestions.setdefault(suggestion, {"count": 0, "sources": set()})
            all_suggestions[suggestion]["count"] += 1
            all_suggestions[suggestion]["sources"].add('DuckDuckGo')

    # Obtener sugerencias de YouTube (API anterior y nueva)
    for exp_keyword in expanded_keywords:
        suggestions = fetch_youtube_suggestions(exp_keyword)
        youtube_suggestions_all.extend(suggestions)
        new_suggestions = fetch_youtube_suggestions_new(exp_keyword)
        youtube_suggestions_all.extend(new_suggestions)
        for suggestion in suggestions + new_suggestions:
            all_suggestions.setdefault(suggestion, {"count": 0, "sources": set()})
            all_suggestions[suggestion]["count"] += 1
            all_suggestions[suggestion]["sources"].add('YouTube')

    # Obtener sugerencias de Bing
    for exp_keyword in expanded_keywords:
        suggestions = fetch_bing_suggestions(exp_keyword)
        bing_suggestions_all.extend(suggestions)
        for suggestion in suggestions:
            all_suggestions.setdefault(suggestion, {"count": 0, "sources": set()})
            all_suggestions[suggestion]["count"] += 1
            all_suggestions[suggestion]["sources"].add('Bing')

    # Obtener sugerencias de Amazon
    for exp_keyword in expanded_keywords:
        suggestions = fetch_amazon_suggestions(exp_keyword)
        amazon_suggestions_all.extend(suggestions)
        for suggestion in suggestions:
            all_suggestions.setdefault(suggestion, {"count": 0, "sources": set()})
            all_suggestions[suggestion]["count"] += 1
            all_suggestions[suggestion]["sources"].add('Amazon')

    # Obtener sugerencias de Qwant
    for exp_keyword in expanded_keywords:
        suggestions = fetch_qwant_suggestions(exp_keyword)
        qwant_suggestions_all.extend(suggestions)
        for suggestion in suggestions:
            all_suggestions.setdefault(suggestion, {"count": 0, "sources": set()})
            all_suggestions[suggestion]["count"] += 1
            all_suggestions[suggestion]["sources"].add('Qwant')

    # Obtener sugerencias de Brave
    for exp_keyword in expanded_keywords:
        suggestions = fetch_brave_suggestions(exp_keyword)
        brave_suggestions_all.extend(suggestions)
        for suggestion in suggestions:
            all_suggestions.setdefault(suggestion, {"count": 0, "sources": set()})
            all_suggestions[suggestion]["count"] += 1
            all_suggestions[suggestion]["sources"].add('Brave')

    # Calcular relevancia combinada: basado en cu谩ntos buscadores mencionan una palabra y cu谩ntas veces se repite
    combined_suggestions = sorted(all_suggestions.items(), key=lambda item: (len(item[1]["sources"]), item[1]["count"]), reverse=True)

    # Obtener las top 3 de cada plataforma
    google_top_3 = get_top_suggestions(google_suggestions_all, top_n=3)
    duckduckgo_top_3 = get_top_suggestions(duckduckgo_suggestions_all, top_n=3)
    youtube_top_3 = get_top_suggestions(youtube_suggestions_all, top_n=3)
    bing_top_3 = get_top_suggestions(bing_suggestions_all, top_n=3)
    amazon_top_3 = get_top_suggestions(amazon_suggestions_all, top_n=3)
    qwant_top_3 = get_top_suggestions(qwant_suggestions_all, top_n=3)
    brave_top_3 = [(sug, int(freq * 0.4)) for sug, freq in get_top_suggestions(brave_suggestions_all, top_n=3)]

    # Crear una tabla con todas las sugerencias, su relevancia y el n煤mero de buscadores
    all_suggestions_str = "<table><tr><th>Keyword</th><th>Buscadores</th><th>Relevancia (Total)</th></tr>"
    for suggestion, data in combined_suggestions:
        # Aplicar la reducci贸n solo si la sugerencia viene de Brave
        if 'Brave' in data['sources']:
            count = int(data['count'] * 0.4)  # Reducir el conteo un 60% para Brave
        else:
            count = data['count']
        all_suggestions_str += f"<tr><td>{suggestion}</td><td>{', '.join(data['sources'])}</td><td>{count}</td></tr>"
    all_suggestions_str += "</table>"

    # Crear el HTML de salida
    html_output = f"""
    <div>
        <h3>Top 10 combinadas (basado en la cantidad de buscadores y repeticiones):</h3>
        <ul>
            {''.join([f'<li>{sug} (en {len(data["sources"])} buscadores, {data["count"]} repeticiones)</li>' for sug, data in combined_suggestions[:10]])}
        </ul>

        <h4>Top 3 Sugerencias de Google:</h4>
        <ul>
            {''.join([f'<li>{sug} ({freq})</li>' for sug, freq in google_top_3])}
        </ul>

        <h4>Top 3 Sugerencias de DuckDuckGo:</h4>
        <ul>
            {''.join([f'<li>{sug} ({freq})</li>' for sug, freq in duckduckgo_top_3])}
        </ul>

        <h4>Top 3 Sugerencias de YouTube:</h4>
        <ul>
            {''.join([f'<li>{sug} ({freq})</li>' for sug, freq in youtube_top_3])}
        </ul>

        <h4>Top 3 Sugerencias de Bing:</h4>
        <ul>
            {''.join([f'<li>{sug} ({freq})</li>' for sug, freq in bing_top_3])}
        </ul>

        <h4>Top 3 Sugerencias de Amazon:</h4>
        <ul>
            {''.join([f'<li>{sug} ({freq})</li>' for sug, freq in amazon_top_3])}
        </ul>

        <h4>Top 3 Sugerencias de Qwant:</h4>
        <ul>
            {''.join([f'<li>{sug} ({freq})</li>' for sug, freq in qwant_top_3])}
        </ul>

        <h4>Top 3 Sugerencias de Brave:</h4>
        <ul>
            {''.join([f'<li>{sug} ({freq})</li>' for sug, freq in brave_top_3])}
        </ul>

        <h4>Tabla completa de palabras clave y su relevancia:</h4>
        {all_suggestions_str}
    </div>
    """

    return html_output

# Interfaz de Gradio
iface = gr.Interface(
    fn=main,
    inputs="text",
    outputs=gr.HTML(),
    title="Sugerencias Combinadas de M煤ltiples Motores de B煤squeda",
    description="Ingrese una palabra clave para obtener sugerencias de b煤squeda relacionadas de Google (Firefox, Chrome, Android, Desktop, Opera, Safari), DuckDuckGo, YouTube, Bing, Amazon, Qwant y Brave.",
)

iface.launch()