Juanoto2012 commited on
Commit
ae5ce8c
·
verified ·
1 Parent(s): f3fa02a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -9
app.py CHANGED
@@ -4,8 +4,9 @@ import requests
4
  from bs4 import BeautifulSoup
5
  import uvicorn
6
  import urllib.parse
 
7
 
8
- app = FastAPI(title="Glimpse Scraping API", description="API de Scraping directo para buscadores")
9
 
10
  app.add_middleware(
11
  CORSMiddleware,
@@ -15,14 +16,15 @@ app.add_middleware(
15
  allow_headers=["*"],
16
  )
17
 
18
- # User-Agent de un navegador real para evitar bloqueos
19
  HEADERS = {
20
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
21
  "Accept-Language": "es-ES,es;q=0.9,en;q=0.8"
22
  }
23
 
 
 
24
  def scrape_duckduckgo(query: str):
25
- # Usamos la versión HTML plana de DDG que es más fácil de scrapear
26
  url = f"https://html.duckduckgo.com/html/?q={urllib.parse.quote(query)}"
27
  resp = requests.get(url, headers=HEADERS, timeout=10)
28
  resp.raise_for_status()
@@ -34,7 +36,6 @@ def scrape_duckduckgo(query: str):
34
  snippet_tag = result.select_one('.result__snippet')
35
 
36
  if title_tag:
37
- # Limpiar la URL de redirección de DDG
38
  raw_url = title_tag.get('href', '')
39
  clean_url = urllib.parse.unquote(raw_url.replace('//duckduckgo.com/l/?uddg=', '').split('&')[0])
40
 
@@ -65,7 +66,6 @@ def scrape_mojeek(query: str):
65
  return results
66
 
67
  def scrape_qwant(query: str):
68
- # Usamos Qwant Lite que no requiere renderizado de JavaScript
69
  url = f"https://lite.qwant.com/?q={urllib.parse.quote(query)}"
70
  resp = requests.get(url, headers=HEADERS, timeout=10)
71
  resp.raise_for_status()
@@ -104,9 +104,11 @@ def scrape_brave(query: str):
104
  })
105
  return results
106
 
 
 
107
  @app.get("/")
108
  def read_root():
109
- return {"status": "Glimpse Scraping API is running!"}
110
 
111
  @app.get("/search")
112
  def search(
@@ -126,20 +128,42 @@ def search(
126
  elif engine == "brave":
127
  results = scrape_brave(q)
128
  elif engine == "startpage":
129
- # Startpage bloquea el scraping crudo agresivamente (usa tokens).
130
- # Redirigimos silenciosamente a DuckDuckGo como fallback
131
  results = scrape_duckduckgo(q)
132
  else:
133
  results = scrape_duckduckgo(q)
134
 
135
  except requests.exceptions.HTTPError as e:
136
  if e.response.status_code == 403:
137
- raise HTTPException(status_code=403, detail=f"El motor {engine} nos bloqueó (Protección Anti-Bot/CORS).")
138
  raise HTTPException(status_code=500, detail=str(e))
139
  except Exception as e:
140
  raise HTTPException(status_code=500, detail=f"Error al procesar el HTML de {engine}: {str(e)}")
141
 
142
  return {"results": results}
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  if __name__ == "__main__":
145
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
4
  from bs4 import BeautifulSoup
5
  import uvicorn
6
  import urllib.parse
7
+ from duckduckgo_search import DDGS # <- Nueva importación para imágenes
8
 
9
+ app = FastAPI(title="Glimpse Scraping API", description="API de Scraping directo e Imágenes para buscadores")
10
 
11
  app.add_middleware(
12
  CORSMiddleware,
 
16
  allow_headers=["*"],
17
  )
18
 
19
+ # User-Agent de un navegador real para evitar bloqueos en texto
20
  HEADERS = {
21
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
22
  "Accept-Language": "es-ES,es;q=0.9,en;q=0.8"
23
  }
24
 
25
+ # --- FUNCIONES DE SCRAPING DE TEXTO (WEB) ---
26
+
27
  def scrape_duckduckgo(query: str):
 
28
  url = f"https://html.duckduckgo.com/html/?q={urllib.parse.quote(query)}"
29
  resp = requests.get(url, headers=HEADERS, timeout=10)
30
  resp.raise_for_status()
 
36
  snippet_tag = result.select_one('.result__snippet')
37
 
38
  if title_tag:
 
39
  raw_url = title_tag.get('href', '')
40
  clean_url = urllib.parse.unquote(raw_url.replace('//duckduckgo.com/l/?uddg=', '').split('&')[0])
41
 
 
66
  return results
67
 
68
  def scrape_qwant(query: str):
 
69
  url = f"https://lite.qwant.com/?q={urllib.parse.quote(query)}"
70
  resp = requests.get(url, headers=HEADERS, timeout=10)
71
  resp.raise_for_status()
 
104
  })
105
  return results
106
 
107
+ # --- ENDPOINTS DE LA API ---
108
+
109
  @app.get("/")
110
  def read_root():
111
+ return {"status": "Glimpse API is running! Endpoints: /search, /images"}
112
 
113
  @app.get("/search")
114
  def search(
 
128
  elif engine == "brave":
129
  results = scrape_brave(q)
130
  elif engine == "startpage":
 
 
131
  results = scrape_duckduckgo(q)
132
  else:
133
  results = scrape_duckduckgo(q)
134
 
135
  except requests.exceptions.HTTPError as e:
136
  if e.response.status_code == 403:
137
+ raise HTTPException(status_code=403, detail=f"El motor {engine} nos bloqueó.")
138
  raise HTTPException(status_code=500, detail=str(e))
139
  except Exception as e:
140
  raise HTTPException(status_code=500, detail=f"Error al procesar el HTML de {engine}: {str(e)}")
141
 
142
  return {"results": results}
143
 
144
+ # --- NUEVO ENDPOINT PARA IMÁGENES ---
145
+
146
+ @app.get("/images")
147
+ def search_images(
148
+ q: str = Query(..., description="Término de búsqueda para imágenes"),
149
+ max_results: int = Query(30, description="Cantidad máxima de imágenes a devolver")
150
+ ):
151
+ try:
152
+ results = []
153
+ with DDGS() as ddgs:
154
+ # duckduckgo-search tiene una función nativa robusta para esto
155
+ ddg_images = list(ddgs.images(q, max_results=max_results))
156
+ for img in ddg_images:
157
+ results.append({
158
+ "title": img.get("title", ""),
159
+ "image_url": img.get("image", ""), # URL de la imagen en alta resolución
160
+ "thumbnail_url": img.get("thumbnail", ""), # URL de la miniatura (carga rápida)
161
+ "source_url": img.get("url", ""), # URL de la página web donde está la imagen
162
+ "source_name": img.get("source", "") # Nombre del sitio web
163
+ })
164
+ return {"results": results}
165
+ except Exception as e:
166
+ raise HTTPException(status_code=500, detail=f"Error al buscar imágenes: {str(e)}")
167
+
168
  if __name__ == "__main__":
169
  uvicorn.run(app, host="0.0.0.0", port=7860)