From 918a46223e4ebb9b34888026b3c561dc78ea353b Mon Sep 17 00:00:00 2001 From: ppinchuk Date: Tue, 12 Aug 2025 09:47:04 -0600 Subject: [PATCH 1/3] Split up class by browser instance --- elm/web/search/google.py | 66 +++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/elm/web/search/google.py b/elm/web/search/google.py index 77c99e61..525a6ca4 100644 --- a/elm/web/search/google.py +++ b/elm/web/search/google.py @@ -50,37 +50,6 @@ class PlaywrightGoogleLinkSearch(PlaywrightSearchEngineLinkSearch): "https://www.google.com/search?q={}&gl=sg&hl=en&udm=14&start=0&num=10" ) - def __init__(self, use_homepage=True, **launch_kwargs): - """ - - Parameters - ---------- - use_homepage : bool, default=True - If ``True``, the browser will be navigated to the search - engine homepage and the query will be input into the search - bar. If ``False``, the query will be embedded in the URL - and the browser will navigate directly to the filled-out - URL. By default, ``False``. - **launch_kwargs - Keyword arguments to be passed to - `playwright.firefox.launch`. For example, you can pass - ``headless=False, slow_mo=50`` for a visualization of the - search. - """ - self.use_homepage = use_homepage - self.launch_kwargs = {"humanize": 0.1, "headless": True} - self.launch_kwargs.update(launch_kwargs) - self._browser = None - - async def _load_browser(self, pw_instance): - """Empty implementation since we are using camoufox""" - - @asynccontextmanager - async def _browser_page(self): - """Get page to use for search""" - async with AsyncCamoufox(**self.launch_kwargs) as browser: - yield await browser.new_page() - async def _perform_homepage_search(self, page, search_query): """Fill in search bar with user query and hit enter""" await self._move_mouse(page) @@ -120,6 +89,41 @@ async def _fill_in_search_bar(self, page, search_query): return await asyncio.sleep(random.uniform(0.5, 1.5)) +class CamoufoxGoogleLinkSearch(PlaywrightGoogleLinkSearch): + """Search for top links on Google using Camoufox browser""" + + def __init__(self, use_homepage=True, **launch_kwargs): + """ + + Parameters + ---------- + use_homepage : bool, default=True + If ``True``, the browser will be navigated to the search + engine homepage and the query will be input into the search + bar. If ``False``, the query will be embedded in the URL + and the browser will navigate directly to the filled-out + URL. By default, ``False``. + **launch_kwargs + Keyword arguments to be passed to + `playwright.firefox.launch`. For example, you can pass + ``headless=False, slow_mo=50`` for a visualization of the + search. + """ + self.use_homepage = use_homepage + self.launch_kwargs = {"humanize": 0.1, "headless": True} + self.launch_kwargs.update(launch_kwargs) + self._browser = None + + async def _load_browser(self, pw_instance): + """Empty implementation since we are using camoufox""" + + @asynccontextmanager + async def _browser_page(self): + """Get page to use for search""" + async with AsyncCamoufox(**self.launch_kwargs) as browser: + yield await browser.new_page() + + class PlaywrightGoogleCSELinkSearch(PlaywrightSearchEngineLinkSearch): """Search for top links on a custom google search engine From 699a32105b21126e33d9f36f615c500c9169eca5 Mon Sep 17 00:00:00 2001 From: ppinchuk Date: Tue, 12 Aug 2025 09:49:24 -0600 Subject: [PATCH 2/3] Add new SE as option --- elm/web/search/run.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/elm/web/search/run.py b/elm/web/search/run.py index 1fc95cef..79838538 100644 --- a/elm/web/search/run.py +++ b/elm/web/search/run.py @@ -14,6 +14,7 @@ PlaywrightDuckDuckGoLinkSearch) from elm.web.search.dux import DuxDistributedGlobalSearch from elm.web.search.google import (APIGoogleCSESearch, APISerperSearch, + CamoufoxGoogleLinkSearch, PlaywrightGoogleCSELinkSearch, PlaywrightGoogleLinkSearch) from elm.web.search.tavily import APITavilySearch @@ -34,6 +35,8 @@ "APISerperSearch": _SE_OPT(APISerperSearch, False, "google_serper_api_kwargs"), "APITavilySearch": _SE_OPT(APITavilySearch, False, "tavily_api_kwargs"), + "CamoufoxGoogleLinkSearch": _SE_OPT(CamoufoxGoogleLinkSearch, True, + "cf_google_se_kwargs"), "DuxDistributedGlobalSearch": _SE_OPT(DuxDistributedGlobalSearch, False, "ddgs_kwargs"), "PlaywrightBingLinkSearch": _SE_OPT(PlaywrightBingLinkSearch, True, @@ -127,6 +130,7 @@ async def web_search_links_as_docs(queries, search_engines=_DEFAULT_SE, - google_serper_api_kwargs - tavily_api_kwargs - ddgs_kwargs + - cf_google_se_kwargs - pw_bing_se_kwargs - pw_ddg_se_kwargs - pw_google_cse_kwargs @@ -226,6 +230,7 @@ async def search_with_fallback(queries, search_engines=_DEFAULT_SE, - google_serper_api_kwargs - tavily_api_kwargs - ddgs_kwargs + - cf_google_se_kwargs - pw_bing_se_kwargs - pw_ddg_se_kwargs - pw_google_cse_kwargs From c212f2d61731bb50907cedcabe0afe499e12db43 Mon Sep 17 00:00:00 2001 From: ppinchuk Date: Tue, 12 Aug 2025 09:49:39 -0600 Subject: [PATCH 3/3] Bump version --- elm/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elm/version.py b/elm/version.py index f9ff74d6..9f8fb8d7 100644 --- a/elm/version.py +++ b/elm/version.py @@ -2,4 +2,4 @@ ELM version number """ -__version__ = "0.0.24" +__version__ = "0.0.25"