from flask import Flask, request, jsonify, render_template import requests from bs4 import BeautifulSoup from urllib.parse import urlparse, parse_qs, unquote app = Flask(__name__) def duckduckgo_search(query): url = 'https://duckduckgo.com/html/' params = {'q': query} headers = {'User-Agent': 'Mozilla/5.0'} response = requests.get(url, params=params, headers=headers) if response.status_code != 200: return [] soup = BeautifulSoup(response.text, 'html.parser') results = [] for result in soup.find_all('div', class_='result'): title_tag = result.find('a', class_='result__a') if not title_tag: continue title = title_tag.get_text() link = title_tag['href'] # Decode the actual URL from the DuckDuckGo redirect link parsed_link = urlparse(link) query_params = parse_qs(parsed_link.query) actual_url = unquote(query_params.get('uddg', [''])[0]) description_tag = result.find('a', class_='result__snippet') description = description_tag.get_text() if description_tag else 'No description available' # Attempt to fetch the favicon icon = 'No icon available' if actual_url: parsed_actual_url = urlparse(actual_url) favicon_url = f"{parsed_actual_url.scheme}://{parsed_actual_url.netloc}/favicon.ico" favicon_response = requests.get(favicon_url, headers=headers) if favicon_response.status_code == 200: icon = favicon_url results.append({ 'title': title, 'link': actual_url, 'description': description, 'icon': icon }) return results @app.route('/') def index(): return render_template('index.html') @app.route('/search', methods=['GET']) def search(): query = request.args.get('query') if not query: return jsonify({'error': 'No query provided'}), 400 results = duckduckgo_search(query) return jsonify(results) if __name__ == '__main__': app.run(host="0.0.0.0", port=7860)