Files
svr/usr/bin/search-duckduck
T

96 lines
2.3 KiB
Python
Raw Normal View History

2026-03-29 13:58:18 +00:00
#!/usr/bin/env python
2026-03-29 14:04:59 +00:00
2026-03-29 14:01:35 +00:00
import sys
import subprocess
2026-03-29 17:10:56 +00:00
import time
import random
2026-03-29 14:01:35 +00:00
2026-03-29 14:04:59 +00:00
def ensure_package(pkg):
try:
__import__(pkg)
except ImportError:
subprocess.check_call([sys.executable, "-m", "pip", "install", pkg])
2026-03-29 17:10:56 +00:00
for pkg in ("bs4", "requests"):
ensure_package(pkg)
2026-03-29 13:58:18 +00:00
2026-03-29 14:04:59 +00:00
from bs4 import BeautifulSoup
2026-03-29 13:58:18 +00:00
import requests
2026-03-29 14:01:35 +00:00
import argparse
2026-03-29 13:58:18 +00:00
2026-03-29 17:10:56 +00:00
def create_session():
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0"
})
return session
def fetch(session, method, url, **kwargs):
for _ in range(3):
try:
response = session.request(method, url, timeout=10, **kwargs)
if response.status_code == 200:
return response
time.sleep(5)
except requests.RequestException:
time.sleep(5)
return None
def recherche_duckduckgo(session, query, n):
2026-03-29 13:58:18 +00:00
url = "https://html.duckduckgo.com/html/"
2026-03-29 17:10:56 +00:00
response = fetch(session, "POST", url, data={"q": query})
if not response:
return []
2026-03-29 13:58:18 +00:00
soup = BeautifulSoup(response.text, "html.parser")
results = []
2026-03-29 17:10:56 +00:00
for result in soup.select("a.result__a")[:n]:
title = result.get_text(strip=True)
2026-03-29 13:58:18 +00:00
link = result.get("href")
2026-03-29 17:10:56 +00:00
if link:
results.append((title, link))
2026-03-29 13:58:18 +00:00
2026-03-29 17:10:56 +00:00
time.sleep(random.uniform(1.5, 3.5))
2026-03-29 13:58:18 +00:00
return results
2026-03-29 17:10:56 +00:00
def extract_text(session, url, max_chars):
response = fetch(session, "GET", url)
2026-03-29 14:04:59 +00:00
2026-03-29 17:10:56 +00:00
if not response:
return "[Erreur: accès impossible]"
2026-03-29 14:04:59 +00:00
2026-03-29 17:10:56 +00:00
soup = BeautifulSoup(response.text, "html.parser")
text = soup.get_text(separator=" ", strip=True)
2026-03-29 14:04:59 +00:00
2026-03-29 17:10:56 +00:00
return (text[:max_chars] + "...") if len(text) > max_chars else text
2026-03-29 14:04:59 +00:00
2026-03-29 17:10:56 +00:00
def main(argc, argv):
2026-03-29 14:04:59 +00:00
parser = argparse.ArgumentParser(description="Recherche + extraction de texte")
2026-03-29 17:10:56 +00:00
parser.add_argument("query", type=str)
parser.add_argument("-n", "--number", type=int, default=5)
parser.add_argument("--chars", type=int, default=1000)
2026-03-29 14:01:35 +00:00
2026-03-29 17:10:56 +00:00
args = parser.parse_args(argv[1:])
2026-03-29 13:58:18 +00:00
2026-03-29 17:10:56 +00:00
session = create_session()
results = recherche_duckduckgo(session, args.query, args.number)
2026-03-29 13:58:18 +00:00
for i, (title, link) in enumerate(results, 1):
2026-03-29 14:04:59 +00:00
print(f"\n{i}. {title}")
print(f"URL: {link}")
2026-03-29 17:10:56 +00:00
snippet = extract_text(session, link, args.chars)
2026-03-29 14:04:59 +00:00
print(f"Extrait: {snippet}")
2026-03-29 14:01:35 +00:00
if __name__ == "__main__":
2026-03-29 17:10:56 +00:00
main(len(sys.argv), sys.argv)