webscout 8.2.2__py3-none-any.whl → 8.2.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webscout might be problematic. Click here for more details.

Files changed (306) hide show
  1. webscout/AIauto.py +112 -22
  2. webscout/AIbase.py +144 -7
  3. webscout/AIutel.py +249 -131
  4. webscout/Bard.py +579 -206
  5. webscout/DWEBS.py +78 -35
  6. webscout/__init__.py +0 -1
  7. webscout/cli.py +256 -0
  8. webscout/conversation.py +307 -436
  9. webscout/exceptions.py +23 -0
  10. webscout/prompt_manager.py +56 -42
  11. webscout/version.py +1 -1
  12. webscout/webscout_search.py +65 -47
  13. webscout/webscout_search_async.py +81 -126
  14. webscout/yep_search.py +93 -43
  15. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info}/METADATA +172 -52
  16. webscout-8.2.7.dist-info/RECORD +26 -0
  17. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info}/WHEEL +1 -1
  18. webscout-8.2.7.dist-info/entry_points.txt +3 -0
  19. webscout-8.2.7.dist-info/top_level.txt +1 -0
  20. inferno/__init__.py +0 -6
  21. inferno/__main__.py +0 -9
  22. inferno/cli.py +0 -6
  23. webscout/Extra/GitToolkit/__init__.py +0 -10
  24. webscout/Extra/GitToolkit/gitapi/__init__.py +0 -12
  25. webscout/Extra/GitToolkit/gitapi/repository.py +0 -195
  26. webscout/Extra/GitToolkit/gitapi/user.py +0 -96
  27. webscout/Extra/GitToolkit/gitapi/utils.py +0 -62
  28. webscout/Extra/YTToolkit/YTdownloader.py +0 -957
  29. webscout/Extra/YTToolkit/__init__.py +0 -3
  30. webscout/Extra/YTToolkit/transcriber.py +0 -476
  31. webscout/Extra/YTToolkit/ytapi/__init__.py +0 -6
  32. webscout/Extra/YTToolkit/ytapi/channel.py +0 -307
  33. webscout/Extra/YTToolkit/ytapi/errors.py +0 -13
  34. webscout/Extra/YTToolkit/ytapi/extras.py +0 -45
  35. webscout/Extra/YTToolkit/ytapi/https.py +0 -88
  36. webscout/Extra/YTToolkit/ytapi/patterns.py +0 -61
  37. webscout/Extra/YTToolkit/ytapi/playlist.py +0 -59
  38. webscout/Extra/YTToolkit/ytapi/pool.py +0 -8
  39. webscout/Extra/YTToolkit/ytapi/query.py +0 -40
  40. webscout/Extra/YTToolkit/ytapi/stream.py +0 -63
  41. webscout/Extra/YTToolkit/ytapi/utils.py +0 -62
  42. webscout/Extra/YTToolkit/ytapi/video.py +0 -232
  43. webscout/Extra/__init__.py +0 -7
  44. webscout/Extra/autocoder/__init__.py +0 -9
  45. webscout/Extra/autocoder/autocoder.py +0 -849
  46. webscout/Extra/autocoder/autocoder_utiles.py +0 -332
  47. webscout/Extra/gguf.py +0 -682
  48. webscout/Extra/tempmail/__init__.py +0 -28
  49. webscout/Extra/tempmail/async_utils.py +0 -141
  50. webscout/Extra/tempmail/base.py +0 -161
  51. webscout/Extra/tempmail/cli.py +0 -187
  52. webscout/Extra/tempmail/emailnator.py +0 -84
  53. webscout/Extra/tempmail/mail_tm.py +0 -361
  54. webscout/Extra/tempmail/temp_mail_io.py +0 -292
  55. webscout/Extra/weather.py +0 -194
  56. webscout/Extra/weather_ascii.py +0 -76
  57. webscout/LLM.py +0 -442
  58. webscout/Litlogger/__init__.py +0 -67
  59. webscout/Litlogger/core/__init__.py +0 -6
  60. webscout/Litlogger/core/level.py +0 -23
  61. webscout/Litlogger/core/logger.py +0 -165
  62. webscout/Litlogger/handlers/__init__.py +0 -12
  63. webscout/Litlogger/handlers/console.py +0 -33
  64. webscout/Litlogger/handlers/file.py +0 -143
  65. webscout/Litlogger/handlers/network.py +0 -173
  66. webscout/Litlogger/styles/__init__.py +0 -7
  67. webscout/Litlogger/styles/colors.py +0 -249
  68. webscout/Litlogger/styles/formats.py +0 -458
  69. webscout/Litlogger/styles/text.py +0 -87
  70. webscout/Litlogger/utils/__init__.py +0 -6
  71. webscout/Litlogger/utils/detectors.py +0 -153
  72. webscout/Litlogger/utils/formatters.py +0 -200
  73. webscout/Local/__init__.py +0 -12
  74. webscout/Local/__main__.py +0 -9
  75. webscout/Local/api.py +0 -576
  76. webscout/Local/cli.py +0 -516
  77. webscout/Local/config.py +0 -75
  78. webscout/Local/llm.py +0 -287
  79. webscout/Local/model_manager.py +0 -253
  80. webscout/Local/server.py +0 -721
  81. webscout/Local/utils.py +0 -93
  82. webscout/Provider/AI21.py +0 -177
  83. webscout/Provider/AISEARCH/DeepFind.py +0 -250
  84. webscout/Provider/AISEARCH/ISou.py +0 -256
  85. webscout/Provider/AISEARCH/Perplexity.py +0 -359
  86. webscout/Provider/AISEARCH/__init__.py +0 -10
  87. webscout/Provider/AISEARCH/felo_search.py +0 -228
  88. webscout/Provider/AISEARCH/genspark_search.py +0 -208
  89. webscout/Provider/AISEARCH/hika_search.py +0 -194
  90. webscout/Provider/AISEARCH/iask_search.py +0 -436
  91. webscout/Provider/AISEARCH/monica_search.py +0 -246
  92. webscout/Provider/AISEARCH/scira_search.py +0 -324
  93. webscout/Provider/AISEARCH/webpilotai_search.py +0 -281
  94. webscout/Provider/Aitopia.py +0 -292
  95. webscout/Provider/AllenAI.py +0 -413
  96. webscout/Provider/Andi.py +0 -228
  97. webscout/Provider/Blackboxai.py +0 -229
  98. webscout/Provider/C4ai.py +0 -432
  99. webscout/Provider/ChatGPTClone.py +0 -226
  100. webscout/Provider/ChatGPTES.py +0 -237
  101. webscout/Provider/ChatGPTGratis.py +0 -194
  102. webscout/Provider/Chatify.py +0 -175
  103. webscout/Provider/Cloudflare.py +0 -273
  104. webscout/Provider/Cohere.py +0 -208
  105. webscout/Provider/DeepSeek.py +0 -196
  106. webscout/Provider/Deepinfra.py +0 -297
  107. webscout/Provider/ElectronHub.py +0 -709
  108. webscout/Provider/ExaAI.py +0 -261
  109. webscout/Provider/ExaChat.py +0 -342
  110. webscout/Provider/Free2GPT.py +0 -241
  111. webscout/Provider/GPTWeb.py +0 -193
  112. webscout/Provider/Gemini.py +0 -169
  113. webscout/Provider/GithubChat.py +0 -367
  114. webscout/Provider/Glider.py +0 -211
  115. webscout/Provider/Groq.py +0 -670
  116. webscout/Provider/HF_space/__init__.py +0 -0
  117. webscout/Provider/HF_space/qwen_qwen2.py +0 -206
  118. webscout/Provider/HeckAI.py +0 -233
  119. webscout/Provider/HuggingFaceChat.py +0 -462
  120. webscout/Provider/Hunyuan.py +0 -272
  121. webscout/Provider/Jadve.py +0 -266
  122. webscout/Provider/Koboldai.py +0 -381
  123. webscout/Provider/LambdaChat.py +0 -392
  124. webscout/Provider/Llama.py +0 -200
  125. webscout/Provider/Llama3.py +0 -204
  126. webscout/Provider/Marcus.py +0 -148
  127. webscout/Provider/Netwrck.py +0 -228
  128. webscout/Provider/OLLAMA.py +0 -396
  129. webscout/Provider/OPENAI/__init__.py +0 -25
  130. webscout/Provider/OPENAI/base.py +0 -46
  131. webscout/Provider/OPENAI/c4ai.py +0 -367
  132. webscout/Provider/OPENAI/chatgpt.py +0 -549
  133. webscout/Provider/OPENAI/chatgptclone.py +0 -460
  134. webscout/Provider/OPENAI/deepinfra.py +0 -272
  135. webscout/Provider/OPENAI/e2b.py +0 -1350
  136. webscout/Provider/OPENAI/exaai.py +0 -404
  137. webscout/Provider/OPENAI/exachat.py +0 -433
  138. webscout/Provider/OPENAI/freeaichat.py +0 -352
  139. webscout/Provider/OPENAI/glider.py +0 -316
  140. webscout/Provider/OPENAI/heckai.py +0 -337
  141. webscout/Provider/OPENAI/llmchatco.py +0 -327
  142. webscout/Provider/OPENAI/netwrck.py +0 -348
  143. webscout/Provider/OPENAI/opkfc.py +0 -488
  144. webscout/Provider/OPENAI/scirachat.py +0 -463
  145. webscout/Provider/OPENAI/sonus.py +0 -294
  146. webscout/Provider/OPENAI/standardinput.py +0 -425
  147. webscout/Provider/OPENAI/textpollinations.py +0 -285
  148. webscout/Provider/OPENAI/toolbaz.py +0 -405
  149. webscout/Provider/OPENAI/typegpt.py +0 -346
  150. webscout/Provider/OPENAI/uncovrAI.py +0 -455
  151. webscout/Provider/OPENAI/utils.py +0 -211
  152. webscout/Provider/OPENAI/venice.py +0 -413
  153. webscout/Provider/OPENAI/wisecat.py +0 -381
  154. webscout/Provider/OPENAI/writecream.py +0 -156
  155. webscout/Provider/OPENAI/x0gpt.py +0 -371
  156. webscout/Provider/OPENAI/yep.py +0 -327
  157. webscout/Provider/OpenGPT.py +0 -199
  158. webscout/Provider/Openai.py +0 -496
  159. webscout/Provider/PI.py +0 -344
  160. webscout/Provider/Perplexitylabs.py +0 -415
  161. webscout/Provider/Phind.py +0 -535
  162. webscout/Provider/PizzaGPT.py +0 -198
  163. webscout/Provider/QwenLM.py +0 -254
  164. webscout/Provider/Reka.py +0 -214
  165. webscout/Provider/StandardInput.py +0 -278
  166. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  167. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  168. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  169. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  170. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  171. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  172. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  173. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  174. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  175. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  176. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  177. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  178. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  179. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  180. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  181. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  182. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  183. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  184. webscout/Provider/TTI/__init__.py +0 -12
  185. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  186. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  187. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  188. webscout/Provider/TTI/artbit/__init__.py +0 -22
  189. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  190. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  191. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  192. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  193. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  194. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  195. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  196. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  197. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  198. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  199. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  200. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  201. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  202. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  203. webscout/Provider/TTI/talkai/__init__.py +0 -4
  204. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  205. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  206. webscout/Provider/TTS/__init__.py +0 -7
  207. webscout/Provider/TTS/deepgram.py +0 -156
  208. webscout/Provider/TTS/elevenlabs.py +0 -111
  209. webscout/Provider/TTS/gesserit.py +0 -127
  210. webscout/Provider/TTS/murfai.py +0 -113
  211. webscout/Provider/TTS/parler.py +0 -111
  212. webscout/Provider/TTS/speechma.py +0 -180
  213. webscout/Provider/TTS/streamElements.py +0 -333
  214. webscout/Provider/TTS/utils.py +0 -280
  215. webscout/Provider/TeachAnything.py +0 -187
  216. webscout/Provider/TextPollinationsAI.py +0 -231
  217. webscout/Provider/TwoAI.py +0 -199
  218. webscout/Provider/Venice.py +0 -219
  219. webscout/Provider/VercelAI.py +0 -234
  220. webscout/Provider/WebSim.py +0 -228
  221. webscout/Provider/WiseCat.py +0 -196
  222. webscout/Provider/Writecream.py +0 -211
  223. webscout/Provider/WritingMate.py +0 -197
  224. webscout/Provider/Youchat.py +0 -330
  225. webscout/Provider/__init__.py +0 -198
  226. webscout/Provider/ai4chat.py +0 -202
  227. webscout/Provider/aimathgpt.py +0 -189
  228. webscout/Provider/akashgpt.py +0 -342
  229. webscout/Provider/askmyai.py +0 -158
  230. webscout/Provider/asksteve.py +0 -203
  231. webscout/Provider/bagoodex.py +0 -145
  232. webscout/Provider/cerebras.py +0 -242
  233. webscout/Provider/chatglm.py +0 -205
  234. webscout/Provider/cleeai.py +0 -213
  235. webscout/Provider/copilot.py +0 -428
  236. webscout/Provider/elmo.py +0 -234
  237. webscout/Provider/freeaichat.py +0 -271
  238. webscout/Provider/gaurish.py +0 -244
  239. webscout/Provider/geminiapi.py +0 -208
  240. webscout/Provider/geminiprorealtime.py +0 -160
  241. webscout/Provider/granite.py +0 -187
  242. webscout/Provider/hermes.py +0 -219
  243. webscout/Provider/julius.py +0 -223
  244. webscout/Provider/koala.py +0 -268
  245. webscout/Provider/labyrinth.py +0 -340
  246. webscout/Provider/learnfastai.py +0 -266
  247. webscout/Provider/lepton.py +0 -194
  248. webscout/Provider/llama3mitril.py +0 -180
  249. webscout/Provider/llamatutor.py +0 -192
  250. webscout/Provider/llmchat.py +0 -213
  251. webscout/Provider/llmchatco.py +0 -311
  252. webscout/Provider/meta.py +0 -794
  253. webscout/Provider/multichat.py +0 -325
  254. webscout/Provider/promptrefine.py +0 -193
  255. webscout/Provider/scira_chat.py +0 -277
  256. webscout/Provider/scnet.py +0 -187
  257. webscout/Provider/searchchat.py +0 -293
  258. webscout/Provider/sonus.py +0 -208
  259. webscout/Provider/talkai.py +0 -194
  260. webscout/Provider/toolbaz.py +0 -320
  261. webscout/Provider/turboseek.py +0 -219
  262. webscout/Provider/tutorai.py +0 -252
  263. webscout/Provider/typefully.py +0 -280
  264. webscout/Provider/typegpt.py +0 -232
  265. webscout/Provider/uncovr.py +0 -312
  266. webscout/Provider/x0gpt.py +0 -256
  267. webscout/Provider/yep.py +0 -376
  268. webscout/litagent/__init__.py +0 -29
  269. webscout/litagent/agent.py +0 -455
  270. webscout/litagent/constants.py +0 -60
  271. webscout/litprinter/__init__.py +0 -59
  272. webscout/scout/__init__.py +0 -8
  273. webscout/scout/core/__init__.py +0 -7
  274. webscout/scout/core/crawler.py +0 -140
  275. webscout/scout/core/scout.py +0 -568
  276. webscout/scout/core/search_result.py +0 -96
  277. webscout/scout/core/text_analyzer.py +0 -63
  278. webscout/scout/core/text_utils.py +0 -277
  279. webscout/scout/core/web_analyzer.py +0 -52
  280. webscout/scout/core.py +0 -881
  281. webscout/scout/element.py +0 -460
  282. webscout/scout/parsers/__init__.py +0 -69
  283. webscout/scout/parsers/html5lib_parser.py +0 -172
  284. webscout/scout/parsers/html_parser.py +0 -236
  285. webscout/scout/parsers/lxml_parser.py +0 -178
  286. webscout/scout/utils.py +0 -37
  287. webscout/swiftcli/__init__.py +0 -809
  288. webscout/zeroart/__init__.py +0 -55
  289. webscout/zeroart/base.py +0 -60
  290. webscout/zeroart/effects.py +0 -99
  291. webscout/zeroart/fonts.py +0 -816
  292. webscout-8.2.2.dist-info/RECORD +0 -309
  293. webscout-8.2.2.dist-info/entry_points.txt +0 -5
  294. webscout-8.2.2.dist-info/top_level.txt +0 -3
  295. webstoken/__init__.py +0 -30
  296. webstoken/classifier.py +0 -189
  297. webstoken/keywords.py +0 -216
  298. webstoken/language.py +0 -128
  299. webstoken/ner.py +0 -164
  300. webstoken/normalizer.py +0 -35
  301. webstoken/processor.py +0 -77
  302. webstoken/sentiment.py +0 -206
  303. webstoken/stemmer.py +0 -73
  304. webstoken/tagger.py +0 -60
  305. webstoken/tokenizer.py +0 -158
  306. {webscout-8.2.2.dist-info → webscout-8.2.7.dist-info/licenses}/LICENSE.md +0 -0
webscout/DWEBS.py CHANGED
@@ -4,7 +4,7 @@ DWEBS - A Google search library with advanced features
4
4
  import random
5
5
  from time import sleep
6
6
  from webscout.scout import Scout
7
- from requests import get
7
+ from curl_cffi.requests import Session
8
8
  from urllib.parse import unquote, urlencode
9
9
  from typing import List, Dict, Optional, Union, Iterator, Any
10
10
  from concurrent.futures import ThreadPoolExecutor
@@ -35,34 +35,55 @@ class SearchResult:
35
35
 
36
36
  class GoogleSearch:
37
37
  """Google search implementation with configurable parameters and advanced features."""
38
-
38
+
39
39
  _executor: ThreadPoolExecutor = ThreadPoolExecutor()
40
-
40
+
41
41
  def __init__(
42
42
  self,
43
43
  timeout: int = 10,
44
44
  proxies: Optional[Dict[str, str]] = None,
45
45
  verify: bool = True,
46
46
  lang: str = "en",
47
- sleep_interval: float = 0.0
47
+ sleep_interval: float = 0.0,
48
+ impersonate: str = "chrome110"
48
49
  ):
49
50
  """
50
51
  Initialize GoogleSearch with custom settings.
51
-
52
+
52
53
  Args:
53
54
  timeout: Request timeout in seconds
54
55
  proxies: Proxy configuration for requests
55
56
  verify: Whether to verify SSL certificates
56
57
  lang: Search language
57
58
  sleep_interval: Sleep time between pagination requests
59
+ impersonate: Browser profile for curl_cffi. Defaults to "chrome110".
58
60
  """
59
- self.timeout = timeout
61
+ self.timeout = timeout # Keep timeout for potential non-session uses or reference
60
62
  self.proxies = proxies if proxies else {}
61
63
  self.verify = verify
62
64
  self.lang = lang
63
65
  self.sleep_interval = sleep_interval
64
66
  self.base_url = "https://www.google.com/search"
65
-
67
+ # Initialize curl_cffi session
68
+ self.session = Session(
69
+ proxies=self.proxies,
70
+ verify=self.verify,
71
+ timeout=self.timeout,
72
+ impersonate=impersonate
73
+ )
74
+ # Set common headers for the session
75
+ self.session.headers = {
76
+ "User-Agent": self._get_useragent(),
77
+ "Accept-Language": self.lang,
78
+ "Accept-Encoding": "gzip, deflate, br",
79
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
80
+ }
81
+ # Set default cookies for the session
82
+ self.session.cookies.update({
83
+ 'CONSENT': 'PENDING+987',
84
+ 'SOCS': 'CAESHAgBEhIaAB',
85
+ })
86
+
66
87
  def _get_useragent(self) -> str:
67
88
  """
68
89
  Generate a random user agent string.
@@ -99,29 +120,23 @@ class GoogleSearch:
99
120
  # Add search type if specified
100
121
  if search_type:
101
122
  params["tbm"] = search_type
102
-
123
+
103
124
  try:
104
- resp = get(
125
+ # Use the curl_cffi session
126
+ resp = self.session.get(
105
127
  url=self.base_url,
106
- headers={
107
- "User-Agent": self._get_useragent(),
108
- "Accept-Language": self.lang,
109
- "Accept-Encoding": "gzip, deflate, br",
110
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
111
- },
112
128
  params=params,
113
- proxies=self.proxies if any(self.proxies) else None,
114
- timeout=self.timeout,
115
- verify=self.verify,
116
- cookies={
117
- 'CONSENT': 'PENDING+987',
118
- 'SOCS': 'CAESHAgBEhIaAB',
119
- }
129
+ # Headers and cookies are now part of the session
130
+ # proxies, timeout, verify are handled by the session
120
131
  )
121
132
  resp.raise_for_status()
122
133
  return resp.text
123
134
  except Exception as e:
124
- raise RuntimeError(f"Search request failed: {str(e)}")
135
+ # Provide more specific error context if possible
136
+ if hasattr(e, 'response') and e.response is not None:
137
+ raise RuntimeError(f"Search request failed with status {e.response.status_code}: {str(e)}")
138
+ else:
139
+ raise RuntimeError(f"Search request failed: {str(e)}")
125
140
 
126
141
  def _extract_url(self, raw_link: str) -> Optional[str]:
127
142
  """
@@ -283,8 +298,15 @@ class GoogleSearch:
283
298
  start = start_num
284
299
 
285
300
  while len(fetched_results) < max_results:
301
+ # Add safe search parameter to the request
302
+ # Note: This modifies the session params for this specific request type
303
+ # It might be better to pass params directly to session.get if mixing search types
304
+ term_with_safe = f"{keywords} safe:{safe}"
305
+ if region and region.lower() != "all":
306
+ term_with_safe += f" location:{region}" # Example of adding region, adjust as needed
307
+
286
308
  response_html = self._make_request(
287
- term=keywords,
309
+ term=term_with_safe, # Pass term with safe search
288
310
  results=max_results - len(fetched_results),
289
311
  start=start
290
312
  )
@@ -304,7 +326,7 @@ class GoogleSearch:
304
326
  if len(fetched_results) >= max_results:
305
327
  break
306
328
 
307
- start += 10
329
+ start += 10 # Google typically uses increments of 10
308
330
  sleep(self.sleep_interval)
309
331
 
310
332
  return fetched_results[:max_results]
@@ -340,11 +362,15 @@ class GoogleSearch:
340
362
  safe = safe_map.get(safesearch.lower(), "moderate")
341
363
 
342
364
  # Keep track of unique results
343
- fetched_results = []
344
365
  fetched_links = set()
345
-
366
+
367
+ # Add safe search parameter
368
+ term_with_safe = f"{keywords} safe:{safe}"
369
+ if region and region.lower() != "all":
370
+ term_with_safe += f" location:{region}" # Example
371
+
346
372
  response_html = self._make_request(
347
- term=keywords,
373
+ term=term_with_safe, # Pass term with safe search
348
374
  results=max_results,
349
375
  search_type="nws"
350
376
  )
@@ -353,7 +379,7 @@ class GoogleSearch:
353
379
  html=response_html,
354
380
  num_results=max_results,
355
381
  fetched_links=fetched_links,
356
- unique=True
382
+ unique=True # News results are generally unique per request
357
383
  )
358
384
 
359
385
  return results[:max_results]
@@ -384,17 +410,19 @@ class GoogleSearch:
384
410
 
385
411
  url = f"https://www.google.com/complete/search?{urlencode(params)}"
386
412
 
413
+ # Use a simpler header set for the suggestions API
387
414
  headers = {
388
415
  "User-Agent": self._get_useragent(),
389
416
  "Accept": "application/json, text/javascript, */*",
390
417
  "Accept-Language": self.lang,
391
418
  }
392
419
 
393
- response = get(
420
+ # Use session.get but override headers for this specific request
421
+ response = self.session.get(
394
422
  url=url,
395
423
  headers=headers,
396
- timeout=self.timeout,
397
- verify=self.verify
424
+ params=params # Pass params directly
425
+ # timeout and verify are handled by session
398
426
  )
399
427
  response.raise_for_status()
400
428
 
@@ -405,25 +433,40 @@ class GoogleSearch:
405
433
  return []
406
434
 
407
435
  except Exception as e:
436
+ # Provide more specific error context if possible
437
+ if hasattr(e, 'response') and e.response is not None:
438
+ # Log error or handle differently if needed
439
+ print(f"Suggestions request failed with status {e.response.status_code}: {str(e)}")
440
+ else:
441
+ print(f"Suggestions request failed: {str(e)}")
408
442
  # Return empty list on error instead of raising exception
409
443
  return []
410
444
 
411
445
 
412
446
  # Legacy function support for backward compatibility
413
- def search(term, num_results=10, lang="en", proxy=None, advanced=False, sleep_interval=0, timeout=5, safe="active", ssl_verify=True, region=None, start_num=0, unique=False):
447
+ def search(term, num_results=10, lang="en", proxy=None, advanced=False, sleep_interval=0, timeout=5, safe="active", ssl_verify=True, region=None, start_num=0, unique=False, impersonate="chrome110"): # Added impersonate
414
448
  """Legacy function for backward compatibility."""
415
449
  google_search = GoogleSearch(
416
450
  timeout=timeout,
417
451
  proxies={"https": proxy, "http": proxy} if proxy else None,
418
452
  verify=ssl_verify,
419
453
  lang=lang,
420
- sleep_interval=sleep_interval
454
+ sleep_interval=sleep_interval,
455
+ impersonate=impersonate # Pass impersonate
421
456
  )
422
457
 
458
+ # Map legacy safe values
459
+ safe_search_map = {
460
+ "active": "on",
461
+ "moderate": "moderate",
462
+ "off": "off"
463
+ }
464
+ safesearch_val = safe_search_map.get(safe, "moderate")
465
+
423
466
  results = google_search.text(
424
467
  keywords=term,
425
468
  region=region,
426
- safesearch="on" if safe == "active" else "moderate" if safe == "moderate" else "off",
469
+ safesearch=safesearch_val,
427
470
  max_results=num_results,
428
471
  start_num=start_num,
429
472
  unique=unique
webscout/__init__.py CHANGED
@@ -5,7 +5,6 @@ from .webscout_search_async import AsyncWEBS
5
5
  from .version import __version__
6
6
  from .DWEBS import *
7
7
  from .tempid import *
8
- from .LLM import VLM, LLM
9
8
  from .Provider import *
10
9
  from .Provider.TTI import *
11
10
  from .Provider.TTS import *
webscout/cli.py CHANGED
@@ -1,6 +1,8 @@
1
1
  import sys
2
2
  from .swiftcli import CLI, option
3
3
  from .webscout_search import WEBS
4
+ from .DWEBS import GoogleSearch # Import GoogleSearch from DWEBS
5
+ from .yep_search import YepSearch # Import YepSearch from yep_search
4
6
  from .version import __version__
5
7
 
6
8
 
@@ -282,6 +284,260 @@ def weather(location: str, language: str, proxy: str = None, timeout: int = 10):
282
284
  except Exception as e:
283
285
  raise e
284
286
 
287
+ @app.command()
288
+ @option("--keywords", "-k", help="Search keywords", required=True)
289
+ @option("--region", "-r", help="Region for search results (ISO country code)", default="all")
290
+ @option("--safesearch", "-s", help="SafeSearch setting (on, moderate, off)", default="moderate")
291
+ @option("--max-results", "-m", help="Maximum number of results", type=int, default=10)
292
+ @option("--start-num", "-start", help="Starting position for pagination", type=int, default=0)
293
+ @option("--unique", "-u", help="Filter duplicate results", type=bool, default=True)
294
+ @option("--timeout", "-timeout", help="Timeout value for requests", type=int, default=10)
295
+ @option("--proxy", "-p", help="Proxy URL to use for requests")
296
+ @option("--impersonate", "-i", help="Browser to impersonate", default="chrome110")
297
+ def google_text(
298
+ keywords: str,
299
+ region: str,
300
+ safesearch: str,
301
+ max_results: int,
302
+ start_num: int,
303
+ unique: bool,
304
+ timeout: int = 10,
305
+ proxy: str = None,
306
+ impersonate: str = "chrome110"
307
+ ):
308
+ """Perform a text search using Google Search."""
309
+ google = GoogleSearch(
310
+ timeout=timeout,
311
+ proxies={"https": proxy, "http": proxy} if proxy else None,
312
+ verify=True,
313
+ lang="en",
314
+ sleep_interval=0.0,
315
+ impersonate=impersonate
316
+ )
317
+
318
+ try:
319
+ results = google.text(
320
+ keywords=keywords,
321
+ region=region,
322
+ safesearch=safesearch,
323
+ max_results=max_results,
324
+ start_num=start_num,
325
+ unique=unique
326
+ )
327
+
328
+ # Convert SearchResult objects to dictionaries for printing
329
+ formatted_results = []
330
+ for result in results:
331
+ result_dict = {
332
+ "title": result.title,
333
+ "url": result.url,
334
+ "description": result.description,
335
+ }
336
+ # Add any metadata to the result dictionary
337
+ for k, v in result.metadata.items():
338
+ result_dict[k] = v
339
+
340
+ formatted_results.append(result_dict)
341
+
342
+ _print_data(formatted_results)
343
+ except Exception as e:
344
+ raise e
345
+
346
+ @app.command()
347
+ @option("--keywords", "-k", help="Search keywords", required=True)
348
+ @option("--region", "-r", help="Region for search results (ISO country code)", default="all")
349
+ @option("--safesearch", "-s", help="SafeSearch setting (on, moderate, off)", default="moderate")
350
+ @option("--max-results", "-m", help="Maximum number of results", type=int, default=10)
351
+ @option("--timeout", "-timeout", help="Timeout value for requests", type=int, default=10)
352
+ @option("--proxy", "-p", help="Proxy URL to use for requests")
353
+ @option("--impersonate", "-i", help="Browser to impersonate", default="chrome110")
354
+ def google_news(
355
+ keywords: str,
356
+ region: str,
357
+ safesearch: str,
358
+ max_results: int,
359
+ timeout: int = 10,
360
+ proxy: str = None,
361
+ impersonate: str = "chrome110"
362
+ ):
363
+ """Perform a news search using Google Search."""
364
+ google = GoogleSearch(
365
+ timeout=timeout,
366
+ proxies={"https": proxy, "http": proxy} if proxy else None,
367
+ verify=True,
368
+ lang="en",
369
+ sleep_interval=0.0,
370
+ impersonate=impersonate
371
+ )
372
+
373
+ try:
374
+ results = google.news(
375
+ keywords=keywords,
376
+ region=region,
377
+ safesearch=safesearch,
378
+ max_results=max_results
379
+ )
380
+
381
+ # Convert SearchResult objects to dictionaries for printing
382
+ formatted_results = []
383
+ for result in results:
384
+ result_dict = {
385
+ "title": result.title,
386
+ "url": result.url,
387
+ "description": result.description,
388
+ }
389
+ # Add any metadata to the result dictionary
390
+ for k, v in result.metadata.items():
391
+ result_dict[k] = v
392
+
393
+ formatted_results.append(result_dict)
394
+
395
+ _print_data(formatted_results)
396
+ except Exception as e:
397
+ raise e
398
+
399
+ @app.command()
400
+ @option("--query", "-q", help="Search query", required=True)
401
+ @option("--region", "-r", help="Region for suggestions (ISO country code)", default="all")
402
+ @option("--timeout", "-timeout", help="Timeout value for requests", type=int, default=10)
403
+ @option("--proxy", "-p", help="Proxy URL to use for requests")
404
+ @option("--impersonate", "-i", help="Browser to impersonate", default="chrome110")
405
+ def google_suggestions(
406
+ query: str,
407
+ region: str,
408
+ timeout: int = 10,
409
+ proxy: str = None,
410
+ impersonate: str = "chrome110"
411
+ ):
412
+ """Get search suggestions from Google Search."""
413
+ google = GoogleSearch(
414
+ timeout=timeout,
415
+ proxies={"https": proxy, "http": proxy} if proxy else None,
416
+ verify=True,
417
+ lang="en",
418
+ sleep_interval=0.0,
419
+ impersonate=impersonate
420
+ )
421
+
422
+ try:
423
+ results = google.suggestions(query=query, region=region)
424
+
425
+ # Format suggestions for printing
426
+ formatted_results = []
427
+ for i, suggestion in enumerate(results, 1):
428
+ formatted_results.append({"position": i, "suggestion": suggestion})
429
+
430
+ _print_data(formatted_results)
431
+ except Exception as e:
432
+ raise e
433
+
434
+ @app.command()
435
+ @option("--keywords", "-k", help="Search keywords", required=True)
436
+ @option("--region", "-r", help="Region for search results", default="all")
437
+ @option("--safesearch", "-s", help="SafeSearch setting (on, moderate, off)", default="moderate")
438
+ @option("--max-results", "-m", help="Maximum number of results", type=int, default=10)
439
+ @option("--timeout", "-timeout", help="Timeout value for requests", type=int, default=20)
440
+ @option("--proxy", "-p", help="Proxy URL to use for requests")
441
+ @option("--impersonate", "-i", help="Browser to impersonate", default="chrome110")
442
+ def yep_text(
443
+ keywords: str,
444
+ region: str,
445
+ safesearch: str,
446
+ max_results: int,
447
+ timeout: int = 20,
448
+ proxy: str = None,
449
+ impersonate: str = "chrome110"
450
+ ):
451
+ """Perform a text search using Yep Search."""
452
+ yep = YepSearch(
453
+ timeout=timeout,
454
+ proxies={"https": proxy, "http": proxy} if proxy else None,
455
+ verify=True,
456
+ impersonate=impersonate
457
+ )
458
+
459
+ try:
460
+ results = yep.text(
461
+ keywords=keywords,
462
+ region=region,
463
+ safesearch=safesearch,
464
+ max_results=max_results
465
+ )
466
+
467
+ _print_data(results)
468
+ except Exception as e:
469
+ raise e
470
+
471
+ @app.command()
472
+ @option("--keywords", "-k", help="Search keywords", required=True)
473
+ @option("--region", "-r", help="Region for search results", default="all")
474
+ @option("--safesearch", "-s", help="SafeSearch setting (on, moderate, off)", default="moderate")
475
+ @option("--max-results", "-m", help="Maximum number of results", type=int, default=10)
476
+ @option("--timeout", "-timeout", help="Timeout value for requests", type=int, default=20)
477
+ @option("--proxy", "-p", help="Proxy URL to use for requests")
478
+ @option("--impersonate", "-i", help="Browser to impersonate", default="chrome110")
479
+ def yep_images(
480
+ keywords: str,
481
+ region: str,
482
+ safesearch: str,
483
+ max_results: int,
484
+ timeout: int = 20,
485
+ proxy: str = None,
486
+ impersonate: str = "chrome110"
487
+ ):
488
+ """Perform an image search using Yep Search."""
489
+ yep = YepSearch(
490
+ timeout=timeout,
491
+ proxies={"https": proxy, "http": proxy} if proxy else None,
492
+ verify=True,
493
+ impersonate=impersonate
494
+ )
495
+
496
+ try:
497
+ results = yep.images(
498
+ keywords=keywords,
499
+ region=region,
500
+ safesearch=safesearch,
501
+ max_results=max_results
502
+ )
503
+
504
+ _print_data(results)
505
+ except Exception as e:
506
+ raise e
507
+
508
+ @app.command()
509
+ @option("--query", "-q", help="Search query", required=True)
510
+ @option("--region", "-r", help="Region for suggestions", default="all")
511
+ @option("--timeout", "-timeout", help="Timeout value for requests", type=int, default=20)
512
+ @option("--proxy", "-p", help="Proxy URL to use for requests")
513
+ @option("--impersonate", "-i", help="Browser to impersonate", default="chrome110")
514
+ def yep_suggestions(
515
+ query: str,
516
+ region: str,
517
+ timeout: int = 20,
518
+ proxy: str = None,
519
+ impersonate: str = "chrome110"
520
+ ):
521
+ """Get search suggestions from Yep Search."""
522
+ yep = YepSearch(
523
+ timeout=timeout,
524
+ proxies={"https": proxy, "http": proxy} if proxy else None,
525
+ verify=True,
526
+ impersonate=impersonate
527
+ )
528
+
529
+ try:
530
+ results = yep.suggestions(query=query, region=region)
531
+
532
+ # Format suggestions for printing
533
+ formatted_results = []
534
+ for i, suggestion in enumerate(results, 1):
535
+ formatted_results.append({"position": i, "suggestion": suggestion})
536
+
537
+ _print_data(formatted_results)
538
+ except Exception as e:
539
+ raise e
540
+
285
541
  def main():
286
542
  """Main entry point for the CLI."""
287
543
  try: