62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
"""SearXNG 搜索源 — 自托管元搜索引擎"""
|
|
|
|
import time
|
|
import requests
|
|
from providers.base import BaseProvider, SearchResult
|
|
|
|
|
|
class SearXNGProvider(BaseProvider):
|
|
name = 'searxng'
|
|
display_name = 'SearXNG'
|
|
needs_api_key = False
|
|
enabled = True
|
|
priority = 30
|
|
|
|
def __init__(self, config: dict):
|
|
super().__init__(config)
|
|
sc = config.get('searxng', {})
|
|
self.base_url = (sc.get('base_url') or 'http://localhost:8888').rstrip('/')
|
|
|
|
def is_available(self) -> bool:
|
|
return True
|
|
|
|
def search(self, query: str, max_results: int = 10) -> list:
|
|
url = f'{self.base_url}/search'
|
|
params = {
|
|
'q': query,
|
|
'format': 'json',
|
|
'language': 'zh-CN',
|
|
'categories': 'general',
|
|
'pageno': 1,
|
|
}
|
|
|
|
try:
|
|
resp = requests.get(url, params=params, timeout=15,
|
|
headers={'User-Agent': 'SearchHub/1.0',
|
|
'Accept': 'application/json'})
|
|
if resp.status_code != 200:
|
|
return []
|
|
|
|
data = resp.json()
|
|
results = []
|
|
for item in data.get('results', []):
|
|
published = item.get('publishedDate', '')
|
|
if published:
|
|
try:
|
|
published = published.replace('T', ' ').split('+')[0].split('Z')[0]
|
|
except Exception:
|
|
pass
|
|
|
|
results.append(SearchResult(
|
|
title=item.get('title', ''),
|
|
url=item.get('url', ''),
|
|
content=item.get('content', ''),
|
|
score=item.get('score', 0.5),
|
|
source=self.name,
|
|
published_date=published,
|
|
))
|
|
return results[:max_results]
|
|
|
|
except requests.exceptions.RequestException:
|
|
return []
|