Herramientas de usuario

Herramientas del sitio


ia:desinformadores

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
ia:desinformadores [2025/01/26 17:17]
anonimo
ia:desinformadores [2025/02/01 03:57] (actual)
anonimo
Línea 1: Línea 1:
 +1º Tomar como base los principales desinformadores de España, que son los que proporcionan una información más heterogenea en datos\\ ​
 +2º Extraer los títulos de los vídeos,​shorts y directos de youtube mediante web scrapping\\ ​
 +3º Limpiarlos de caracteres extraños, tildes, artículos y preposiciones que no sirven para el propósito mediante el editor de textos sed\\ 
 +4º Hacer pruebas midiendo el grado de similitud ideológica de diferentes usuarios/​seguidores respecto a dichos desinformadores\\ ​
 +
 +
 +**Extraemos los títulos de los vídeos, shorts y directos mediante web scrapping**
 <code python> <code python>
 """​ """​
Línea 29: Línea 36:
 import time import time
  
-def obtener_videos_con_scroll(url_canal): +def manejar_mensaje_cookies(driver): 
-    # Inicializa ​el navegador (asegúrate ​de tener el driver ​de Chrome o Firefox) +    #Maneja ​el mensaje ​de cookies en YouTube. 
-    driver = webdriver.Chrome()  # O webdriver.Firefox(), dependiendo ​de tu elección+    try: 
 +        # Espera hasta que el botón ​de cookies sea visible 
 +        ​boton_cookies = WebDriverWait(driver, 10).until( 
 +            EC.element_to_be_clickable((By.XPATH,​ '//​button[.//​span[text()="​Aceptar todo"​]]'​)) 
 +        ) 
 +        boton_cookies.click()  # Haz clic en el botón 
 +        print("​Mensaje de cookies cerrado."​) 
 +    except Exception as e: 
 +        print(f"​No se encontró el mensaje ​de cookies o hubo un error: {e}")
  
-    ​Navega a la página del canal+def iniciar_driver():​ 
 +    """​Inicializa el navegador de Selenium."""​ 
 +    options = webdriver.ChromeOptions() 
 +    options.add_argument('​--headless'​)  ​Modo sin interfaz gráfica (opcional) 
 +    options.add_argument('​--disable-gpu'​) 
 +    options.add_argument('​--no-sandbox'​) 
 +    options.add_argument('​--disable-dev-shm-usage'​) 
 +    return webdriver.Chrome(options=options) 
 + 
 +def obtener_videos_con_scroll(url_canal):​ 
 +    driver = iniciar_driver()
     driver.get(url_canal)     driver.get(url_canal)
-    time.sleep(5) ​ # Espera un poco más para que la página cargue completamente+    time.sleep(5) ​ # Espera un poco para que la página cargue completamente
  
-    # Simula ​el scroll hacia abajo para cargar más videos +    # Manejar ​el mensaje de cookies 
-    SCROLL_PAUSE_TIME = 4  # Aumenta el tiempo de pausa+    manejar_mensaje_cookies(driver) 
 + 
 +    SCROLL_PAUSE_TIME = 4
     last_height = driver.execute_script("​return document.documentElement.scrollHeight"​)     last_height = driver.execute_script("​return document.documentElement.scrollHeight"​)
-    ​ +    videos_cargados = set()
-    ​videos_cargados = set()  # Usamos un conjunto para evitar duplicados+
  
     while True:     while True:
-        # Desplaza hacia abajo 
         driver.execute_script("​window.scrollTo(0,​ document.documentElement.scrollHeight);"​)         driver.execute_script("​window.scrollTo(0,​ document.documentElement.scrollHeight);"​)
         time.sleep(SCROLL_PAUSE_TIME)         time.sleep(SCROLL_PAUSE_TIME)
- 
-        # Calcula la nueva altura de la página y compara con la anterior 
-        new_height = driver.execute_script("​return document.documentElement.scrollHeight"​) 
-        ​ 
-        # Recoge los videos visibles usando el nuevo selector 
         videos = driver.find_elements(By.XPATH,​ '//​ytd-rich-grid-media//​yt-formatted-string[@id="​video-title"​]'​)         videos = driver.find_elements(By.XPATH,​ '//​ytd-rich-grid-media//​yt-formatted-string[@id="​video-title"​]'​)
-        ​ 
-        # Depurar: Imprimir cuántos videos se encontraron en esta iteración 
         print(f"​Videos encontrados en esta iteración: {len(videos)}"​)         print(f"​Videos encontrados en esta iteración: {len(videos)}"​)
-        ​+
         for video in videos:         for video in videos:
-            title = video.text ​ # Usar .text para obtener el título visible +            ​try: 
-            link = video.find_element(By.XPATH,​ '​./​ancestor::​ytd-rich-grid-media//​a'​).get_attribute('​href'​) ​ # Obtener el enlace +                ​title = video.text 
-            # Añade a un conjunto para evitar duplicados +                link = video.find_element(By.XPATH,​ '​./​ancestor::​ytd-rich-grid-media//​a'​).get_attribute('​href'​) 
-            ​videos_cargados.add((title,​ link))+                videos_cargados.add((title,​ link)
 +            except Exception as e: 
 +                print(f"​Error al extraer un video: {e}")
  
-        ​# Si la altura no cambia, hemos llegado al final+        ​new_height = driver.execute_script("​return document.documentElement.scrollHeight"​)
         if new_height == last_height:​         if new_height == last_height:​
             break             break
-        ​ 
         last_height = new_height         last_height = new_height
  
     driver.quit()     driver.quit()
-    ​ 
-    # Convertir el conjunto a lista de diccionarios 
     lista_videos = [{'​titulo':​ title, '​link':​ link} for title, link in videos_cargados]     lista_videos = [{'​titulo':​ title, '​link':​ link} for title, link in videos_cargados]
-    ​ 
-    # Depurar: imprimir la cantidad total de videos recogidos 
     print(f"​Total de videos recogidos: {len(lista_videos)}"​)     print(f"​Total de videos recogidos: {len(lista_videos)}"​)
-    ​ 
     return lista_videos     return lista_videos
  
 def obtener_shorts_con_scroll(url_canal):​ def obtener_shorts_con_scroll(url_canal):​
-    ​# Inicializa el navegador (asegúrate de tener el driver de Chrome o Firefox) +    driver = iniciar_driver()
-    ​driver = webdriver.Chrome() ​ # O webdriver.Firefox(), dependiendo de tu elección +
- +
-    # Navega a la página de Shorts del canal+
     driver.get(url_canal)     driver.get(url_canal)
-    time.sleep(5) ​ Espera un poco para que la página cargue completamente+    time.sleep(5) 
 + 
 +    ​Manejar el mensaje de cookies 
 +    manejar_mensaje_cookies(driver)
  
-    # Simula el scroll hacia abajo para cargar más shorts 
     SCROLL_PAUSE_TIME = 3     SCROLL_PAUSE_TIME = 3
     last_height = driver.execute_script("​return document.documentElement.scrollHeight"​)     last_height = driver.execute_script("​return document.documentElement.scrollHeight"​)
-    ​ +    shorts_cargados = set()
-    ​shorts_cargados = set()  # Usamos un conjunto para evitar duplicados+
  
     while True:     while True:
-        # Desplaza hacia abajo 
         driver.execute_script("​window.scrollTo(0,​ document.documentElement.scrollHeight);"​)         driver.execute_script("​window.scrollTo(0,​ document.documentElement.scrollHeight);"​)
         time.sleep(SCROLL_PAUSE_TIME)         time.sleep(SCROLL_PAUSE_TIME)
- +        ​shorts = driver.find_elements(By.XPATH, '//​a[contains(@class,​ "​shortsLockupViewModelHostEndpoint"​)]'​)
-        # Esperar explícitamente hasta que los elementos de shorts estén presentes +
-        ​shorts = WebDriverWait(driver, 10).until( +
-            EC.presence_of_all_elements_located((By.XPATH, '//​a[contains(@class,​ "​shortsLockupViewModelHostEndpoint"​)]'​)+
-        ) +
- +
-        # Depurar: Imprimir cuántos shorts se encontraron en esta iteración+
         print(f"​Shorts encontrados en esta iteración: {len(shorts)}"​)         print(f"​Shorts encontrados en esta iteración: {len(shorts)}"​)
  
         for short in shorts:         for short in shorts:
             try:             try:
-                # Extraer título y enlace de cada short 
                 title = short.get_attribute('​title'​)                 title = short.get_attribute('​title'​)
                 link = "​https://​www.youtube.com"​ + short.get_attribute('​href'​)                 link = "​https://​www.youtube.com"​ + short.get_attribute('​href'​)
-                # Añadir al conjunto 
                 shorts_cargados.add((title,​ link))                 shorts_cargados.add((title,​ link))
             except Exception as e:             except Exception as e:
                 print(f"​Error al extraer un short: {e}")                 print(f"​Error al extraer un short: {e}")
  
-        # Calcular la nueva altura y compararla con la anterior 
         new_height = driver.execute_script("​return document.documentElement.scrollHeight"​)         new_height = driver.execute_script("​return document.documentElement.scrollHeight"​)
         if new_height == last_height:​         if new_height == last_height:​
Línea 123: Línea 125:
  
     driver.quit()     driver.quit()
-    ​ 
-    # Convertir el conjunto a lista de diccionarios 
     lista_shorts = [{'​titulo':​ title, '​link':​ link} for title, link in shorts_cargados]     lista_shorts = [{'​titulo':​ title, '​link':​ link} for title, link in shorts_cargados]
-    ​ 
-    # Depurar: imprimir la cantidad total de shorts recogidos 
     print(f"​Total de shorts recogidos: {len(lista_shorts)}"​)     print(f"​Total de shorts recogidos: {len(lista_shorts)}"​)
-    ​ 
     return lista_shorts     return lista_shorts
- 
- 
- 
  
 def obtener_streams_con_scroll(url_canal):​ def obtener_streams_con_scroll(url_canal):​
-    ​# Inicializa el navegador (asegúrate de tener el driver de Chrome o Firefox) +    driver = iniciar_driver()
-    ​driver = webdriver.Chrome() ​ # O webdriver.Firefox(), dependiendo de tu elección +
- +
-    # Navega a la página de Streams del canal+
     driver.get(url_canal)     driver.get(url_canal)
-    time.sleep(4 # Espera un poco más para que la página cargue completamente+    time.sleep(5)
  
-    # Simula ​el scroll hacia abajo para cargar más streams +    # Manejar ​el mensaje de cookies 
-    SCROLL_PAUSE_TIME = 3  # Aumenta el tiempo de pausa+    manejar_mensaje_cookies(driver) 
 + 
 +    SCROLL_PAUSE_TIME = 3
     last_height = driver.execute_script("​return document.documentElement.scrollHeight"​)     last_height = driver.execute_script("​return document.documentElement.scrollHeight"​)
-    ​ +    streams_cargados = set()
-    ​streams_cargados = set()  # Usamos un conjunto para evitar duplicados+
  
     while True:     while True:
-        # Desplaza hacia abajo 
         driver.execute_script("​window.scrollTo(0,​ document.documentElement.scrollHeight);"​)         driver.execute_script("​window.scrollTo(0,​ document.documentElement.scrollHeight);"​)
         time.sleep(SCROLL_PAUSE_TIME)         time.sleep(SCROLL_PAUSE_TIME)
- 
-        # Calcula la nueva altura de la página y compara con la anterior 
-        new_height = driver.execute_script("​return document.documentElement.scrollHeight"​) 
-        ​ 
-        # Recoge los streams visibles usando el nuevo selector 
         streams = driver.find_elements(By.XPATH,​ '//​a[@id="​video-title-link"​]'​)         streams = driver.find_elements(By.XPATH,​ '//​a[@id="​video-title-link"​]'​)
-        ​ 
-        # Depurar: Imprimir cuántos streams se encontraron en esta iteración 
         print(f"​Streams encontrados en esta iteración: {len(streams)}"​)         print(f"​Streams encontrados en esta iteración: {len(streams)}"​)
-        ​+
         for stream in streams:         for stream in streams:
-            title = stream.get_attribute('​title'​) ​ # Obtener el título +            ​try: 
-            link = "​https://​www.youtube.com"​ + stream.get_attribute('​href'​) ​ # Obtener el enlace completo +                ​title = stream.get_attribute('​title'​) 
-            # Añade a un conjunto para evitar duplicados +                link = "​https://​www.youtube.com"​ + stream.get_attribute('​href'​) 
-            ​streams_cargados.add((title,​ link))+                streams_cargados.add((title,​ link)
 +            except Exception as e: 
 +                print(f"​Error al extraer un stream: {e}")
  
-        ​# Si la altura no cambia, hemos llegado al final+        ​new_height = driver.execute_script("​return document.documentElement.scrollHeight"​)
         if new_height == last_height:​         if new_height == last_height:​
             break             break
-        ​ 
         last_height = new_height         last_height = new_height
  
     driver.quit()     driver.quit()
-    ​ 
-    # Convertir el conjunto a lista de diccionarios 
     lista_streams = [{'​titulo':​ title, '​link':​ link} for title, link in streams_cargados]     lista_streams = [{'​titulo':​ title, '​link':​ link} for title, link in streams_cargados]
-    ​ 
-    # Depurar: imprimir la cantidad total de streams recogidos 
     print(f"​Total de streams recogidos: {len(lista_streams)}"​)     print(f"​Total de streams recogidos: {len(lista_streams)}"​)
-    ​ 
     return lista_streams     return lista_streams
  
-URL del canal (videos, shorts, streams)+URLs de ejemplo
 url_videos = "​https://​www.youtube.com/​@geoestratego_oficial/​videos"​ url_videos = "​https://​www.youtube.com/​@geoestratego_oficial/​videos"​
 url_shorts = "​https://​www.youtube.com/​@geoestratego_oficial/​shorts"​ url_shorts = "​https://​www.youtube.com/​@geoestratego_oficial/​shorts"​
 url_streams = "​https://​www.youtube.com/​@geoestratego_oficial/​streams"​ url_streams = "​https://​www.youtube.com/​@geoestratego_oficial/​streams"​
  
-# Obtener videos, shorts y streams 
-titulos_shorts = obtener_shorts_con_scroll(url_shorts) 
 titulos_videos = obtener_videos_con_scroll(url_videos) titulos_videos = obtener_videos_con_scroll(url_videos)
 +titulos_shorts = obtener_shorts_con_scroll(url_shorts)
 titulos_streams = obtener_streams_con_scroll(url_streams) titulos_streams = obtener_streams_con_scroll(url_streams)
  
-# Combinar resultados +for titulo in titulos_videos + titulos_shorts + titulos_streams:​
-titulos_totales = titulos_videos + titulos_shorts + titulos_streams +
- +
-# Imprimir los títulos y enlaces de los videos, shorts y streams +
-for titulo in titulos_totales:+
     print(f"​Título:​ {titulo['​titulo'​]},​ Enlace: {titulo['​link'​]}"​)     print(f"​Título:​ {titulo['​titulo'​]},​ Enlace: {titulo['​link'​]}"​)
 +
     ​     ​
 python3 raspado.py > geoestratego.txt python3 raspado.py > geoestratego.txt
 </​code>​ </​code>​
 +El resultado está en éste archivo {{ :​ia:​desinformadores.gz |}}\\ 
  
 +**El .txt hay que prepararlo y no lo está, ésto contienen las 4 primeras líneas**
 <code bash> <code bash>
-cat geoestratego.txt | grep Título | sed '/​^Título:​ ,/​d;​s/​^Título:​ //g;s/, Enlace: .*$//​g;​s/​[A-Z]/​\L&/​g;​y/​áéíóú/​aeiou/;​s/​[^a-zñ0-9 ]/ /g;s/  \+/ /g' | perl -ple '​s/​[^a-zñÑ0-9 ]//gi' | perl -ple '​$_=lc'​ | sed 's/ \+/ /g;s/^ //g'+cat geoestratego.txt | sed -n '​1,​4p'​ 
 +Shorts encontrados en esta iteración: 192 
 +Shorts encontrados en esta iteración: 288 
 +Shorts encontrados en esta iteración: 384 
 +Shorts encontrados en esta iteración: 480 
 +</​code>​ 
 +**Limpiamos,​ sólo quedamos lo que sirve, los títulos, sin caracteres raros, acentos y con minúsculas todo** 
 +<code bash> 
 +cat geoestratego.txt | grep Título | sed '/​^Título:​ ,/​d;​s/​^Título:​ //g;s/, Enlace: .*$//​g;​s/​[A-Z]/​\L&/​g;​y/​áéíóú/​aeiou/;​s/​[^a-zñ0-9 ]/ /g;s/  \+/ /g' | perl -ple '​s/​[^a-zñÑ0-9 ]//gi' | perl -ple '​$_=lc'​ | sed 's/ \+/ /g;s/^ //​g' ​> geoestratego_.txt 
 +</​code>​ 
 +**volvemos a limpiar**\\  
 +<code bash> 
 +sed -Ei 's/ de / /g;s/ la / /g;s/ los / /g;s/ las / /g;s/ y / /g;s/ el / /g;s/ del / /g;s/ al / /g;s/ a / /g;s/^el |^la |^los |^las //g;s/^lo //g;s/ en / /g;s/ un / /g;s/^ //g;' geoestratego_.txt 
 +</​code>​ 
 + **El .txt ya está preparado, éstas son las 4 primeras líneas** 
 +<code bash> 
 +cat geoestratego_.txt | sed -n '​1,​4p'​ 
 +plan final biden para desestabilizar mundo 
 +marcha militar coronel pedro baños 
 +pedro baños geopolitica 2 3  
 +medios comunicacion pierden control 
 + 
 + 
 +cat geoestratego_.txt | wc -l 
 +781 
 +</​code>​ 
 +Los 781 vídeos que tiene publicados\\  
 + 
 +**Preparación de los datos**\\  
 +<code python>​ 
 +"""​ 
 +MIT License 
 +  
 +Copyright (c) 2025 wiki.acosadores.net 
 +  
 +Permission is hereby granted, free of charge, to any person obtaining a copy 
 +of this software and associated documentation files (the "​Software"​),​ to deal 
 +in the Software without restriction,​ including without limitation the rights 
 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 +copies of the Software, and to permit persons to whom the Software is 
 +furnished to do so, subject to the following conditions:​ 
 +  
 +The above copyright notice and this permission notice shall be included in all 
 +copies or substantial portions of the Software. 
 +  
 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,​ 
 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 +SOFTWARE. 
 +"""​ 
 +from sklearn.feature_extraction.text import TfidfVectorizer 
 +from sklearn.metrics.pairwise import cosine_similarity 
 + 
 +# 1. Leer los archivos .txt 
 +with open("​usuario.txt",​ "​r",​ encoding="​utf-8"​) as f1, open("​geoestratego_.txt",​ "​r",​ encoding="​utf-8"​) as f2: 
 +    frases1 = f1.readlines() ​ # Frases de usuario.txt 
 +    frases2 = f2.readlines() ​ # Frases de geoestratego.txt 
 + 
 +# 2. Vectorizar las frases de ambos ficheros con TF-IDF 
 +vectorizer = TfidfVectorizer() 
 +tfidf_matrix1 = vectorizer.fit_transform(frases1) ​ # Matriz TF-IDF para fichero1 
 +tfidf_matrix2 = vectorizer.transform(frases2) ​     # Transformamos fichero2 con el mismo modelo 
 + 
 +# 3. Calcular la similitud coseno entre frases de fichero1 y fichero2 
 +cosine_sim = cosine_similarity(tfidf_matrix1,​ tfidf_matrix2) 
 + 
 +# 4. Mostrar los resultados 
 +print("​Similitudes Coseno entre las frases de usuario.txt y geoestratego_.txt:"​) 
 +for i in range(len(frases1)):​ 
 +    for j in range(len(frases2)):​ 
 +        print(f"​Similitud entre frase {i + 1} de usuario y frase {j + 1} de geoestratego_:​ {cosine_sim[i,​ j]:​.2f}"​)
 </​code>​ </​code>​
-{{ :​ia:​desinformadores.gz |}} 
ia/desinformadores.1737908237.txt.gz · Última modificación: 2025/01/26 17:17 por anonimo