import gradio as gr
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
import os
def build_session():
session = requests.Session()
retries = Retry(
total=2,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
)
adapter = HTTPAdapter(max_retries=retries)
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
def extract_images(url):
session = build_session()
try:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "es-ES,es;q=0.9,en-US;q=0.8,en;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
}
# Timeout separado: (conexión, lectura). Antes era un único valor de 50s,
# lo que dejaba la UI colgada mucho tiempo si el sitio nunca respondía.
response = session.get(url, headers=headers, timeout=(10, 20))
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
base_url = f"{urlparse(url).scheme}://{urlparse(url).netloc}"
images = []
seen = set()
# Buscar imágenes en
for img in soup.find_all("img"):
src = img.get("src") or img.get("data-src") or img.get("data-original")
if not src:
continue
# Convertir URLs relativas a absolutas
img_url = urljoin(base_url, src)
# Filtrar duplicados y URLs inválidas
if img_url in seen or not img_url.startswith(("http://", "https://")):
continue
seen.add(img_url)
# Obtener nombre del archivo
parsed = urlparse(img_url)
filename = os.path.basename(parsed.path) or "imagen.jpg"
if not any(filename.lower().endswith(ext) for ext in [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".bmp"]):
filename += ".jpg"
images.append({
"image": img_url,
"caption": filename
})
# Buscar imágenes de fondo en