Njap-png commited on
Commit
da22edc
·
1 Parent(s): ac8f558

Fix Bing redirect decoding for web crawlers

Browse files
Files changed (1) hide show
  1. app.py +36 -12
app.py CHANGED
@@ -412,23 +412,47 @@ def learn_dictionary():
412
  TRAIN_LOCK.release()
413
 
414
 
415
- def duckduckgo_search(query, max_results=5):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
  try:
417
- r = requests.get("https://html.duckduckgo.com/html/", params={"q": query}, headers={"User-Agent": "Mozilla/5.0"}, timeout=20)
418
  soup = BeautifulSoup(r.text, "html.parser")
419
  out = []
420
- for res in soup.select(".result"):
421
- a = res.select_one("a.result__a")
422
- if not a:
423
- continue
424
- link = a.get("href", "")
425
- title = a.get_text(strip=True)
426
- sn = res.select_one(".result__snippet")
427
- snippet = sn.get_text(strip=True) if sn else ""
428
- if link:
 
 
429
  out.append({"title": title, "url": link, "snippet": snippet})
430
  if len(out) >= max_results:
431
  break
 
 
 
 
 
 
 
 
432
  return out
433
  except Exception as e:
434
  training_state["last"] = f"search error: {str(e)[:100]}"
@@ -456,7 +480,7 @@ def learn_web(topic):
456
  training_state["running"] = True
457
  training_state["last"] = f"searching web: {topic}"
458
  try:
459
- results = duckduckgo_search(topic, 5)
460
  if not results:
461
  raise RuntimeError("no search results")
462
  lines = []
 
412
  TRAIN_LOCK.release()
413
 
414
 
415
+ import base64 as _b64
416
+
417
+ def _decode_bing(url):
418
+ try:
419
+ import urllib.parse
420
+ qs = urllib.parse.parse_qs(urllib.parse.urlparse(url).query)
421
+ u = qs.get("u", [""])[0]
422
+ if u.startswith("a1"):
423
+ u = u[2:]
424
+ pad = "=" * (-len(u) % 4)
425
+ return _b64.b64decode(u + pad).decode()
426
+ except Exception:
427
+ return url
428
+
429
+ def web_search(query, max_results=5):
430
  try:
431
+ r = requests.get("https://www.bing.com/search", params={"q": query}, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}, timeout=20)
432
  soup = BeautifulSoup(r.text, "html.parser")
433
  out = []
434
+ for h in soup.select("h2 a"):
435
+ title = h.get_text(strip=True)
436
+ raw = h.get("href", "")
437
+ link = _decode_bing(raw) if "bing.com/ck/a" in raw else raw
438
+ parent = h.find_parent("li") or h.find_parent("div")
439
+ snippet = ""
440
+ if parent:
441
+ p = parent.select_one("p, .b_caption p, .snippet")
442
+ if p:
443
+ snippet = p.get_text(strip=True)
444
+ if link and title:
445
  out.append({"title": title, "url": link, "snippet": snippet})
446
  if len(out) >= max_results:
447
  break
448
+ if not out:
449
+ try:
450
+ dr = requests.get("https://api.duckduckgo.com/", params={"q": query, "format": "json", "no_html": "1"}, timeout=20)
451
+ dd = dr.json()
452
+ if dd.get("Abstract"):
453
+ out.append({"title": dd.get("Heading", query), "url": dd.get("AbstractURL", ""), "snippet": dd.get("Abstract", "")})
454
+ except Exception:
455
+ pass
456
  return out
457
  except Exception as e:
458
  training_state["last"] = f"search error: {str(e)[:100]}"
 
480
  training_state["running"] = True
481
  training_state["last"] = f"searching web: {topic}"
482
  try:
483
+ results = web_search(topic, 5)
484
  if not results:
485
  raise RuntimeError("no search results")
486
  lines = []