Scrapping - mas README.md
This commit is contained in:
parent
3b8fff8caa
commit
892852835f
|
@ -5,6 +5,7 @@ from models.NetworkingScanner import NetworkScanner
|
||||||
from models.Sniffer import packet_callback, sniff
|
from models.Sniffer import packet_callback, sniff
|
||||||
from models.MusicPlayer import MusicPlayerModel
|
from models.MusicPlayer import MusicPlayerModel
|
||||||
from models.GamblingGameModel import GamblingGameModel
|
from models.GamblingGameModel import GamblingGameModel
|
||||||
|
from models.ScraperModel import ScraperModel
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -21,6 +22,9 @@ class MainController:
|
||||||
self.game_model = GamblingGameModel()
|
self.game_model = GamblingGameModel()
|
||||||
self.roulette_running = False
|
self.roulette_running = False
|
||||||
self.roulette_thread = None
|
self.roulette_thread = None
|
||||||
|
|
||||||
|
self.model = ScraperModel() # Modelo para gestionar el scraping
|
||||||
|
self.scraper_running = False
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
"""Conecta los eventos de la vista con las funciones del controlador."""
|
"""Conecta los eventos de la vista con las funciones del controlador."""
|
||||||
|
@ -37,6 +41,54 @@ class MainController:
|
||||||
self.view.button_start_roulette.config(command=self.start_roulette)
|
self.view.button_start_roulette.config(command=self.start_roulette)
|
||||||
self.view.button_stop_roulette.config(command=self.stop_roulette)
|
self.view.button_stop_roulette.config(command=self.stop_roulette)
|
||||||
|
|
||||||
|
"""Conecta los eventos de la vista con las funciones del controlador."""
|
||||||
|
self.view.button_start_scraper.config(command=self.start_scraper_thread)
|
||||||
|
self.view.button_stop_scraper.config(command=self.stop_scraper)
|
||||||
|
|
||||||
|
|
||||||
|
def start_scraper_thread(self):
|
||||||
|
"""Inicia el scraping en un hilo separado."""
|
||||||
|
start_url = self.view.entry_scraper_url.get().strip()
|
||||||
|
if not start_url:
|
||||||
|
self.view.text_scraper_output.insert("end", "Por favor, introduce una URL válida.\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.model.add_url(start_url) # Añadir URL inicial al modelo
|
||||||
|
self.scraper_running = True
|
||||||
|
self.view.button_start_scraper.config(state="disabled")
|
||||||
|
self.view.button_stop_scraper.config(state="normal")
|
||||||
|
|
||||||
|
# Iniciar hilo para el scraping
|
||||||
|
threading.Thread(target=self.run_scraper, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
def stop_scraper(self):
|
||||||
|
"""Detiene el scraping."""
|
||||||
|
self.scraper_running = False
|
||||||
|
self.view.button_start_scraper.config(state="normal")
|
||||||
|
self.view.button_stop_scraper.config(state="disabled")
|
||||||
|
self.view.text_scraper_output.insert("end", "Scraper detenido.\n")
|
||||||
|
|
||||||
|
|
||||||
|
def run_scraper(self):
|
||||||
|
"""Ejecuta el scraping y actualiza la interfaz con los resultados."""
|
||||||
|
while self.scraper_running and self.model.has_pending_urls():
|
||||||
|
current_url, result = self.model.scrape_next_url()
|
||||||
|
|
||||||
|
if isinstance(result, str): # Error
|
||||||
|
self.view.text_scraper_output.insert("end", f"{result}\n")
|
||||||
|
else: # Éxito
|
||||||
|
self.view.text_scraper_output.insert("end", f"Explorando: {current_url}\n")
|
||||||
|
for link in result:
|
||||||
|
self.view.text_scraper_output.insert("end", f" - {link}\n")
|
||||||
|
|
||||||
|
self.view.text_scraper_output.see("end")
|
||||||
|
time.sleep(1) # Retardo para evitar sobrecarga
|
||||||
|
|
||||||
|
self.scraper_running = False
|
||||||
|
self.view.text_scraper_output.insert("end", "Scraping completado.\n")
|
||||||
|
self.view.button_start_scraper.config(state="normal")
|
||||||
|
self.view.button_stop_scraper.config(state="disabled")
|
||||||
|
|
||||||
def start_sniffer_thread(self):
|
def start_sniffer_thread(self):
|
||||||
"""Inicia el sniffer en un hilo separado."""
|
"""Inicia el sniffer en un hilo separado."""
|
||||||
|
|
26
MainView.py
26
MainView.py
|
@ -38,6 +38,8 @@ class MainView:
|
||||||
self.create_status_bar()
|
self.create_status_bar()
|
||||||
|
|
||||||
self.create_music_player()
|
self.create_music_player()
|
||||||
|
|
||||||
|
self.create_scraper_ui()
|
||||||
|
|
||||||
def create_tabs(self):
|
def create_tabs(self):
|
||||||
"""Crea las solapas dentro del notebook."""
|
"""Crea las solapas dentro del notebook."""
|
||||||
|
@ -189,3 +191,27 @@ class MainView:
|
||||||
self.result_label = ttk.Label(tab, text="", font=("Arial", 12), foreground="blue")
|
self.result_label = ttk.Label(tab, text="", font=("Arial", 12), foreground="blue")
|
||||||
self.result_label.pack(pady=10)
|
self.result_label.pack(pady=10)
|
||||||
|
|
||||||
|
|
||||||
|
def create_scraper_ui(self):
|
||||||
|
"""
|
||||||
|
Crea la interfaz para el scraping:
|
||||||
|
- Input y botones en el frame_left.
|
||||||
|
- TextArea de resultados en la Solapa 5.
|
||||||
|
"""
|
||||||
|
# --- Input y botones en frame_left ---
|
||||||
|
tk.Label(self.frame_left, text="URL del Scraper:", bg="lightblue", font=("Arial", 10)).pack(pady=5)
|
||||||
|
self.entry_scraper_url = tk.Entry(self.frame_left, width=25, font=("Arial", 10))
|
||||||
|
self.entry_scraper_url.pack(pady=5)
|
||||||
|
|
||||||
|
self.button_start_scraper = tk.Button(self.frame_left, text="Iniciar Scraper", font=("Arial", 10))
|
||||||
|
self.button_start_scraper.pack(pady=5)
|
||||||
|
|
||||||
|
self.button_stop_scraper = tk.Button(self.frame_left, text="Detener Scraper", font=("Arial", 10), state="disabled")
|
||||||
|
self.button_stop_scraper.pack(pady=5)
|
||||||
|
|
||||||
|
# --- TextArea en Solapa 5 ---
|
||||||
|
tab5 = self.notebook.nametowidget(self.notebook.tabs()[4]) # Obtener la solapa 5
|
||||||
|
tk.Label(tab5, text="Resultados del Scraper", font=("Arial", 12)).pack(pady=5)
|
||||||
|
self.text_scraper_output = scrolledtext.ScrolledText(tab5, wrap=tk.WORD, height=20, width=80)
|
||||||
|
self.text_scraper_output.pack(pady=10, padx=10, fill="both", expand=True)
|
||||||
|
|
||||||
|
|
54
README.md
54
README.md
|
@ -75,6 +75,49 @@ El objetivo principal de este proyecto es implementar tareas distribuidas en dif
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 📝 Explicación de las principales funcionalidades
|
||||||
|
|
||||||
|
### Solapas (Tabs)
|
||||||
|
|
||||||
|
1. **IP Tracker**
|
||||||
|
- Permite rastrear información sobre una dirección IP, como ubicación, tipo, y más, utilizando la API de ipwhois.io.
|
||||||
|
- Los resultados se muestran en un área de texto con scroll.
|
||||||
|
|
||||||
|
2. **Escaneo de Red**
|
||||||
|
- Realiza un escaneo de dispositivos conectados a la red local usando la biblioteca `python-nmap`.
|
||||||
|
- Lista dispositivos encontrados con sus respectivas direcciones IP y MAC.
|
||||||
|
|
||||||
|
3. **Sniffer**
|
||||||
|
- Captura y analiza paquetes de red en tiempo real utilizando `Scapy`.
|
||||||
|
- Muestra información relevante del paquete, como origen, destino, protocolo y puertos.
|
||||||
|
- Incluye funcionalidad para iniciar y detener el análisis.
|
||||||
|
|
||||||
|
4. **Juego de Azar (Ruleta)**
|
||||||
|
- Un mini-juego de ruleta donde el usuario puede apostar seleccionando un número del 1 al 10.
|
||||||
|
- Calcula si el jugador gana o pierde y actualiza el saldo en la interfaz.
|
||||||
|
|
||||||
|
5. **Scraper**
|
||||||
|
- Permite explorar una URL inicial y extraer enlaces relacionados usando `BeautifulSoup`.
|
||||||
|
- Los resultados se almacenan en una base de datos MongoDB y se muestran en la interfaz en tiempo real.
|
||||||
|
|
||||||
|
### Frame Izquierdo
|
||||||
|
- **Gestión del Scraper:**
|
||||||
|
- Entrada para la URL inicial del scraping.
|
||||||
|
- Botones para iniciar y detener la operación.
|
||||||
|
|
||||||
|
### Frame Derecho
|
||||||
|
- **Reproductor de Música:**
|
||||||
|
- Lista canciones disponibles en una carpeta local.
|
||||||
|
- Botones para reproducir, detener y actualizar la lista de canciones.
|
||||||
|
|
||||||
|
### Barra Inferior (Estado)
|
||||||
|
- **Indicadores del sistema:**
|
||||||
|
- Uso de CPU y RAM en tiempo real.
|
||||||
|
- Velocidad de subida y descarga de red.
|
||||||
|
- Fecha y hora actualizadas dinámicamente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🌍 Contribuciones
|
## 🌍 Contribuciones
|
||||||
|
|
||||||
Si deseas contribuir a este proyecto:
|
Si deseas contribuir a este proyecto:
|
||||||
|
@ -90,12 +133,5 @@ Si deseas contribuir a este proyecto:
|
||||||
|
|
||||||
## 🎮 Autor
|
## 🎮 Autor
|
||||||
|
|
||||||
**Kevin Developer**\
|
**Kevin Developer**
|
||||||
[GitHub](https://github.com/KevinOlarte1)
|
[GitHub](https://github.com/KevinOlarte1)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Tutorial
|
|
||||||
|
|
||||||
(En este apartado podrás incluir un tutorial detallado para que los usuarios aprendan a utilizar tu proyecto paso a paso.)
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,63 @@
|
||||||
|
import requests
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
from pymongo import MongoClient
|
||||||
|
|
||||||
|
|
||||||
|
class ScraperModel:
|
||||||
|
def __init__(self):
|
||||||
|
self.to_visit = []
|
||||||
|
self.visited = set()
|
||||||
|
|
||||||
|
# Conexión a MongoDB
|
||||||
|
self.client = MongoClient("mongodb://localhost:27017/")
|
||||||
|
self.db = self.client["scraping"]
|
||||||
|
self.collection = self.db["visited_links"]
|
||||||
|
|
||||||
|
# Crear índice único para evitar duplicados
|
||||||
|
self.collection.create_index("url", unique=True)
|
||||||
|
|
||||||
|
def add_url(self, url):
|
||||||
|
"""Añade una URL a la lista de pendientes."""
|
||||||
|
if url not in self.visited and url not in self.to_visit:
|
||||||
|
self.to_visit.append(url)
|
||||||
|
|
||||||
|
def scrape_next_url(self):
|
||||||
|
"""Scrapea la siguiente URL."""
|
||||||
|
if not self.to_visit:
|
||||||
|
return None, []
|
||||||
|
|
||||||
|
current_url = self.to_visit.pop(0)
|
||||||
|
self.visited.add(current_url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Solicitar la URL
|
||||||
|
response = requests.get(current_url, timeout=10)
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.RequestException as e:
|
||||||
|
return current_url, f"Error al acceder a {current_url}: {e}"
|
||||||
|
|
||||||
|
# Procesar los enlaces encontrados
|
||||||
|
soup = BeautifulSoup(response.text, 'html.parser')
|
||||||
|
found_links = []
|
||||||
|
|
||||||
|
for link in soup.find_all('a', href=True):
|
||||||
|
full_url = urljoin(current_url, link['href'])
|
||||||
|
if full_url not in self.visited and full_url not in self.to_visit:
|
||||||
|
self.to_visit.append(full_url)
|
||||||
|
found_links.append(full_url)
|
||||||
|
|
||||||
|
# Guardar URL visitada en MongoDB
|
||||||
|
self.save_to_database(current_url)
|
||||||
|
return current_url, found_links
|
||||||
|
|
||||||
|
def save_to_database(self, url):
|
||||||
|
"""Guarda la URL visitada en la base de datos."""
|
||||||
|
try:
|
||||||
|
self.collection.insert_one({"url": url})
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error al guardar en la base de datos: {e}")
|
||||||
|
|
||||||
|
def has_pending_urls(self):
|
||||||
|
"""Verifica si hay URLs pendientes."""
|
||||||
|
return bool(self.to_visit)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
215
pruebas.py
215
pruebas.py
|
@ -1,123 +1,150 @@
|
||||||
import tkinter as tk
|
import requests
|
||||||
from tkinter import messagebox
|
from bs4 import BeautifulSoup
|
||||||
import threading
|
from urllib.parse import urljoin
|
||||||
import random
|
from pymongo import MongoClient
|
||||||
import time
|
import time
|
||||||
|
import tkinter as tk
|
||||||
|
from tkinter import scrolledtext
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
class GamblingGameWithThreads:
|
def setup_database():
|
||||||
|
"""
|
||||||
|
Configura la conexión a la base de datos MongoDB y retorna la colección.
|
||||||
|
"""
|
||||||
|
client = MongoClient("mongodb://localhost:27017/") # Conectar a MongoDB
|
||||||
|
db = client["scraping"] # Base de datos llamada 'scraping'
|
||||||
|
collection = db["visited_links"] # Colección llamada 'visited_links'
|
||||||
|
|
||||||
|
# Crear índice único para evitar duplicados
|
||||||
|
collection.create_index("url", unique=True)
|
||||||
|
|
||||||
|
return collection
|
||||||
|
|
||||||
|
|
||||||
|
def insert_visited_link(collection, url):
|
||||||
|
"""
|
||||||
|
Inserta una URL visitada en la base de datos.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
collection.insert_one({"url": url})
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error al insertar la URL visitada {url}: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
class ScraperApp:
|
||||||
def __init__(self, root):
|
def __init__(self, root):
|
||||||
self.root = root
|
self.root = root
|
||||||
self.root.title("Juego de Azar - Ruleta con Hilos")
|
self.root.title("Scraper de Enlaces con Hilos")
|
||||||
self.root.geometry("400x400")
|
self.root.geometry("800x500")
|
||||||
|
|
||||||
# Variables del juego
|
# Base de datos MongoDB
|
||||||
self.balance = 100
|
self.collection = setup_database()
|
||||||
self.roulette_number = None
|
|
||||||
self.roulette_running = False
|
|
||||||
self.roulette_thread = None
|
|
||||||
|
|
||||||
# Etiqueta de saldo
|
# Variable para detener el scraping
|
||||||
self.balance_label = tk.Label(self.root, text=f"Saldo: $ {self.balance}", font=("Arial", 14))
|
self.running = False
|
||||||
self.balance_label.pack(pady=10)
|
|
||||||
|
|
||||||
# Entrada para la apuesta
|
# Frame para la URL y botón
|
||||||
tk.Label(self.root, text="Tu Apuesta ($):", font=("Arial", 12)).pack()
|
frame_top = tk.Frame(self.root)
|
||||||
self.bet_entry = tk.Entry(self.root, width=10, font=("Arial", 12))
|
frame_top.pack(pady=10)
|
||||||
self.bet_entry.pack(pady=5)
|
|
||||||
|
|
||||||
# Entrada para elegir número
|
tk.Label(frame_top, text="Introduce la URL inicial:", font=("Arial", 12)).pack(side=tk.LEFT, padx=5)
|
||||||
tk.Label(self.root, text="Elige un número (1-10):", font=("Arial", 12)).pack()
|
self.url_entry = tk.Entry(frame_top, width=50, font=("Arial", 12))
|
||||||
self.number_entry = tk.Entry(self.root, width=10, font=("Arial", 12))
|
self.url_entry.pack(side=tk.LEFT, padx=5)
|
||||||
self.number_entry.pack(pady=5)
|
self.start_button = tk.Button(frame_top, text="Iniciar Scraping", font=("Arial", 12), command=self.start_scraping)
|
||||||
|
self.start_button.pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
# Botones de control
|
self.stop_button = tk.Button(frame_top, text="Detener Scraping", font=("Arial", 12), command=self.stop_scraping, state="disabled")
|
||||||
self.start_button = tk.Button(self.root, text="Iniciar Ruleta", font=("Arial", 12), command=self.start_roulette)
|
self.stop_button.pack(side=tk.LEFT, padx=5)
|
||||||
self.start_button.pack(pady=10)
|
|
||||||
|
|
||||||
self.stop_button = tk.Button(self.root, text="Detener Ruleta", font=("Arial", 12), state="disabled", command=self.stop_roulette)
|
# TextArea para los resultados
|
||||||
self.stop_button.pack(pady=5)
|
self.result_area = scrolledtext.ScrolledText(self.root, wrap=tk.WORD, font=("Arial", 12), height=20, width=90)
|
||||||
|
self.result_area.pack(pady=10)
|
||||||
|
|
||||||
# Resultado del juego
|
def start_scraping(self):
|
||||||
self.result_label = tk.Label(self.root, text="", font=("Arial", 12), fg="blue")
|
"""
|
||||||
self.result_label.pack(pady=10)
|
Inicia el scraping en un hilo separado.
|
||||||
|
"""
|
||||||
# Número de la ruleta en tiempo real
|
start_url = self.url_entry.get().strip()
|
||||||
self.roulette_label = tk.Label(self.root, text="Ruleta: ---", font=("Arial", 16), fg="red")
|
if not start_url:
|
||||||
self.roulette_label.pack(pady=10)
|
self.result_area.insert(tk.END, "Por favor, introduce una URL válida.\n")
|
||||||
|
|
||||||
def start_roulette(self):
|
|
||||||
"""Inicia el giro de la ruleta en un hilo."""
|
|
||||||
if self.roulette_running:
|
|
||||||
messagebox.showwarning("Advertencia", "La ruleta ya está girando.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
self.result_area.insert(tk.END, f"Iniciando scraping desde: {start_url}\n")
|
||||||
bet = int(self.bet_entry.get())
|
self.result_area.see(tk.END)
|
||||||
chosen_number = int(self.number_entry.get())
|
|
||||||
except ValueError:
|
|
||||||
messagebox.showerror("Error", "Por favor, ingresa valores numéricos válidos.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if bet <= 0 or chosen_number < 1 or chosen_number > 10:
|
self.running = True
|
||||||
messagebox.showwarning("Advertencia", "La apuesta debe ser mayor a $0 y elige un número entre 1 y 10.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if bet > self.balance:
|
|
||||||
messagebox.showwarning("Advertencia", "No tienes suficiente saldo para esta apuesta.")
|
|
||||||
return
|
|
||||||
|
|
||||||
self.bet = bet
|
|
||||||
self.chosen_number = chosen_number
|
|
||||||
self.roulette_running = True
|
|
||||||
self.start_button.config(state="disabled")
|
self.start_button.config(state="disabled")
|
||||||
self.stop_button.config(state="normal")
|
self.stop_button.config(state="normal")
|
||||||
|
|
||||||
# Crear y arrancar el hilo de la ruleta
|
# Iniciar un hilo para el scraping
|
||||||
self.roulette_thread = threading.Thread(target=self.spin_roulette)
|
self.scraping_thread = threading.Thread(target=self.scrape_links_forever, args=(start_url,))
|
||||||
self.roulette_thread.start()
|
self.scraping_thread.daemon = True # Hilo se detiene cuando la app se cierra
|
||||||
|
self.scraping_thread.start()
|
||||||
|
|
||||||
def spin_roulette(self):
|
def stop_scraping(self):
|
||||||
"""Simula el giro continuo de la ruleta."""
|
"""
|
||||||
while self.roulette_running:
|
Detiene el scraping.
|
||||||
self.roulette_number = random.randint(1, 10)
|
"""
|
||||||
self.roulette_label.config(text=f"Ruleta: {self.roulette_number}")
|
self.running = False
|
||||||
time.sleep(0.1)
|
self.result_area.insert(tk.END, "Deteniendo scraping...\n")
|
||||||
|
self.result_area.see(tk.END)
|
||||||
def stop_roulette(self):
|
|
||||||
"""Detiene la ruleta y evalúa el resultado del juego."""
|
|
||||||
if not self.roulette_running:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.roulette_running = False
|
|
||||||
self.start_button.config(state="normal")
|
self.start_button.config(state="normal")
|
||||||
self.stop_button.config(state="disabled")
|
self.stop_button.config(state="disabled")
|
||||||
|
|
||||||
# Evaluar resultado
|
def scrape_links_forever(self, start_url):
|
||||||
if self.chosen_number == self.roulette_number:
|
"""
|
||||||
winnings = self.bet * 2
|
Scrapea enlaces indefinidamente y guarda solo los visitados en MongoDB.
|
||||||
self.balance += winnings
|
Se ejecuta en un hilo separado.
|
||||||
self.result_label.config(
|
|
||||||
text=f"¡Ganaste! El número fue {self.roulette_number}. Ganaste $ {winnings}.",
|
Args:
|
||||||
fg="green",
|
start_url (str): URL inicial para comenzar el scraping.
|
||||||
)
|
"""
|
||||||
else:
|
to_visit = [start_url] # Lista de URLs por visitar
|
||||||
self.balance -= self.bet
|
visited = set() # Conjunto para evitar bucles
|
||||||
self.result_label.config(
|
|
||||||
text=f"Perdiste. El número fue {self.roulette_number}. Perdiste $ {self.bet}.",
|
|
||||||
fg="red",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Actualizar saldo
|
while to_visit and self.running:
|
||||||
self.balance_label.config(text=f"Saldo: $ {self.balance}")
|
current_url = to_visit.pop(0) # Tomar la URL actual de la lista
|
||||||
|
|
||||||
# Revisar si el jugador se quedó sin saldo
|
if current_url in visited:
|
||||||
if self.balance <= 0:
|
continue
|
||||||
messagebox.showinfo("Juego Terminado", "¡Te quedaste sin saldo! Gracias por jugar.")
|
|
||||||
|
self.result_area.insert(tk.END, f"Explorando: {current_url}\n")
|
||||||
|
self.result_area.see(tk.END)
|
||||||
|
visited.add(current_url) # Marcar como visitada
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Realizar la solicitud HTTP
|
||||||
|
response = requests.get(current_url, timeout=10)
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.RequestException as e:
|
||||||
|
self.result_area.insert(tk.END, f"Error al acceder a {current_url}: {e}\n")
|
||||||
|
self.result_area.see(tk.END)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Parsear el contenido HTML
|
||||||
|
soup = BeautifulSoup(response.text, 'html.parser')
|
||||||
|
|
||||||
|
# Encontrar y procesar los enlaces
|
||||||
|
for link in soup.find_all('a', href=True):
|
||||||
|
full_url = urljoin(current_url, link['href'])
|
||||||
|
if full_url not in visited and full_url not in to_visit:
|
||||||
|
to_visit.append(full_url)
|
||||||
|
|
||||||
|
# Insertar la URL visitada en la base de datos
|
||||||
|
insert_visited_link(self.collection, current_url)
|
||||||
|
|
||||||
|
# Retardo para evitar sobrecargar el servidor
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Finalización del scraping
|
||||||
|
self.result_area.insert(tk.END, "Scraping finalizado.\n")
|
||||||
|
self.result_area.see(tk.END)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
self.stop_button.config(state="disabled")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
app = GamblingGameWithThreads(root)
|
app = ScraperApp(root)
|
||||||
root.mainloop()
|
root.mainloop()
|
||||||
|
|
Loading…
Reference in New Issue