FreshPixels commited on
Commit
979e7d7
·
verified ·
1 Parent(s): 84d7fdb

Delete server/internet_agent.py

Browse files
Files changed (1) hide show
  1. server/internet_agent.py +0 -259
server/internet_agent.py DELETED
@@ -1,259 +0,0 @@
1
- """Бесплатный интернет-агент с минимум 3 способами поиска"""
2
-
3
- import re
4
- import requests
5
- import hashlib
6
- from datetime import datetime, timedelta
7
- from typing import Dict, List, Tuple, Any, Optional
8
- from collections import Counter
9
-
10
- class FreeInternetAgent:
11
- """Интернет-агент с бесплатными поисковыми системами (минимум 3 способа)"""
12
-
13
- def __init__(self, cache_ttl: int = 3600):
14
- self.session = requests.Session()
15
- self.session.headers.update({
16
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
17
- })
18
- self.cache: Dict[str, Tuple[Any, datetime]] = {}
19
- self.cache_ttl = cache_ttl
20
- self._has_bs4 = False
21
- try:
22
- import bs4
23
- self._has_bs4 = True
24
- except ImportError:
25
- pass
26
-
27
- # SearXNG инстансы
28
- self.searxng_instances = [
29
- "https://searx.be",
30
- "https://search.bus-hit.me",
31
- "https://searx.nixnet.xyz",
32
- "https://searx.tuxcloud.net",
33
- "https://searx.moe",
34
- ]
35
-
36
- def _get_cache_key(self, *args, **kwargs) -> str:
37
- key = f"{args}_{sorted(kwargs.items())}"
38
- return hashlib.md5(key.encode()).hexdigest()
39
-
40
- def _get_from_cache(self, key: str) -> Optional[Any]:
41
- if key in self.cache:
42
- data, timestamp = self.cache[key]
43
- if datetime.now() - timestamp < timedelta(seconds=self.cache_ttl):
44
- return data
45
- else:
46
- del self.cache[key]
47
- return None
48
-
49
- def _save_to_cache(self, key: str, data: Any) -> None:
50
- self.cache[key] = (data, datetime.now())
51
-
52
- def search_web(self, query: str, num_results: int = 5) -> List[Dict[str, str]]:
53
- """Умный поиск с несколькими источниками (минимум 3 способа)"""
54
- cache_key = self._get_cache_key('search', query, num_results)
55
- cached = self._get_from_cache(cache_key)
56
- if cached is not None:
57
- return cached
58
-
59
- results = []
60
-
61
- # Способ 1: SearXNG (мета-поиск)
62
- results = self._search_searxng(query, num_results)
63
-
64
- # Способ 2: DuckDuckGo API
65
- if not results:
66
- results = self._search_duckduckgo(query, num_results)
67
-
68
- # Способ 3: Google (парсинг)
69
- if not results:
70
- results = self._search_google(query, num_results)
71
-
72
- # Способ 4: Яндекс (для русского) — опционально
73
- if not results and any(ord(c) > 1024 for c in query):
74
- results = self._search_yandex(query, num_results)
75
-
76
- self._save_to_cache(cache_key, results)
77
- return results
78
-
79
- def _search_searxng(self, query: str, num_results: int) -> List[Dict[str, str]]:
80
- results = []
81
- for instance in self.searxng_instances:
82
- try:
83
- url = f"{instance}/search"
84
- params = {
85
- "q": query,
86
- "format": "json",
87
- "categories": "general",
88
- "engines": "google,bing,duckduckgo,startpage",
89
- "language": "en",
90
- "pageno": 1
91
- }
92
- response = self.session.get(url, params=params, timeout=20)
93
- response.raise_for_status()
94
- data = response.json()
95
-
96
- if 'results' in data:
97
- for item in data['results'][:num_results]:
98
- results.append({
99
- 'title': item.get('title', '')[:100],
100
- 'url': item.get('url', ''),
101
- 'snippet': item.get('content', '')[:200],
102
- 'source': 'searxng',
103
- 'engine': item.get('engine', '')
104
- })
105
- if results:
106
- print(f"🔍 SearXNG: {len(results)} результатов")
107
- break
108
- except Exception as e:
109
- continue
110
- return results
111
-
112
- def _search_duckduckgo(self, query: str, num_results: int) -> List[Dict[str, str]]:
113
- results = []
114
- try:
115
- url = f"https://api.duckduckgo.com/?q={query}&format=json&no_html=1&skip_disambig=1"
116
- response = self.session.get(url, timeout=15)
117
- data = response.json()
118
-
119
- if 'RelatedTopics' in data:
120
- for item in data['RelatedTopics'][:num_results]:
121
- if 'Text' in item and 'FirstURL' in item:
122
- results.append({
123
- 'title': item['Text'][:100],
124
- 'url': item['FirstURL'],
125
- 'snippet': item.get('Text', '')[:200],
126
- 'source': 'duckduckgo'
127
- })
128
- print(f"🦆 DuckDuckGo: {len(results)} результатов")
129
- except Exception as e:
130
- print(f"⚠️ DuckDuckGo ошибка: {e}")
131
- return results
132
-
133
- def _search_google(self, query: str, num_results: int) -> List[Dict[str, str]]:
134
- results = []
135
- if not self._has_bs4:
136
- return results
137
- try:
138
- from bs4 import BeautifulSoup
139
- url = f"https://www.google.com/search?q={query}&num={num_results * 2}"
140
- response = self.session.get(url, timeout=20)
141
- soup = BeautifulSoup(response.text, 'html.parser')
142
-
143
- for g in soup.find_all('div', class_='g'):
144
- title_elem = g.find('h3')
145
- link_elem = g.find('a')
146
- snippet_elem = g.find('div', class_='VwiC3b')
147
-
148
- if title_elem and link_elem:
149
- title = title_elem.get_text()
150
- link = link_elem.get('href', '')
151
- snippet = snippet_elem.get_text() if snippet_elem else ''
152
- if link.startswith('/url?q='):
153
- link = link.split('/url?q=')[1].split('&')[0]
154
- if link.startswith('http'):
155
- results.append({
156
- 'title': title[:100],
157
- 'url': link,
158
- 'snippet': snippet[:200],
159
- 'source': 'google'
160
- })
161
- if len(results) >= num_results:
162
- break
163
- print(f"🔍 Google: {len(results)} результатов")
164
- except Exception as e:
165
- print(f"⚠️ Google ошибка: {e}")
166
- return results
167
-
168
- def _search_yandex(self, query: str, num_results: int) -> List[Dict[str, str]]:
169
- results = []
170
- if not self._has_bs4:
171
- return results
172
- try:
173
- from bs4 import BeautifulSoup
174
- url = f"https://yandex.ru/search/?text={query}&numdoc={num_results}"
175
- response = self.session.get(url, timeout=20)
176
- soup = BeautifulSoup(response.text, 'html.parser')
177
-
178
- for item in soup.find_all('li', class_='serp-item'):
179
- link_elem = item.find('a', class_='link')
180
- snippet_elem = item.find('div', class_='text-container')
181
- if link_elem:
182
- title = link_elem.get_text()
183
- link = link_elem.get('href', '')
184
- snippet = snippet_elem.get_text() if snippet_elem else ''
185
- if link.startswith('http'):
186
- results.append({
187
- 'title': title[:100],
188
- 'url': link,
189
- 'snippet': snippet[:200],
190
- 'source': 'yandex'
191
- })
192
- if len(results) >= num_results:
193
- break
194
- print(f"🔍 Яндекс: {len(results)} результатов")
195
- except Exception as e:
196
- print(f"⚠️ Яндекс ошибка: {e}")
197
- return results
198
-
199
- def fetch_page(self, url: str, max_size: int = 50000) -> Dict[str, Any]:
200
- try:
201
- response = self.session.get(url, timeout=30)
202
- response.raise_for_status()
203
- content = response.text[:max_size]
204
- return {
205
- "url": url,
206
- "status": response.status_code,
207
- "content": content,
208
- "length": len(content),
209
- "headers": dict(response.headers)
210
- }
211
- except Exception as e:
212
- return {"url": url, "error": str(e)}
213
-
214
- def analyze_website(self, url: str) -> Dict[str, Any]:
215
- page = self.fetch_page(url)
216
- if "error" in page:
217
- return page
218
- content = page.get("content", "")
219
- return {
220
- "url": url,
221
- "title": content.split("<title>")[1].split("</title>")[0] if "<title>" in content else "N/A",
222
- "has_forms": "form" in content.lower(),
223
- "has_scripts": "<script" in content.lower(),
224
- "links_count": content.count("<a "),
225
- "size": len(content)
226
- }
227
-
228
- def fetch_multiple(self, urls: List[str], max_total: int = 50000) -> List[Dict[str, Any]]:
229
- results = []
230
- total = 0
231
- for url in urls:
232
- page = self.fetch_page(url, max_size=min(10000, max_total - total))
233
- if "content" in page:
234
- total += len(page["content"])
235
- results.append(page)
236
- if total >= max_total:
237
- break
238
- return results
239
-
240
- def clear_cache(self) -> str:
241
- count = len(self.cache)
242
- self.cache.clear()
243
- return f"🗑️ Кэш очищен ({count} записей)"
244
-
245
- def get_cache_stats(self) -> str:
246
- return f"📊 Кэш: {len(self.cache)} записей, TTL: {self.cache_ttl} секунд"
247
-
248
- def _extract_keywords(self, content: str) -> List[str]:
249
- words = re.findall(r'\b[a-zA-Z]{4,}\b', content.lower())
250
- return [w for w, _ in Counter(words).most_common(10)]
251
-
252
- def _detect_language(self, content: str) -> str:
253
- ru_chars = len(re.findall(r'[а-яА-Я]', content))
254
- en_chars = len(re.findall(r'[a-zA-Z]', content))
255
- if ru_chars > en_chars * 0.5:
256
- return "ru"
257
- return "en"
258
-
259
- INTERNET_AGENT = FreeInternetAgent(cache_ttl=3600)