From 56e565a58252af15b371b5ad6eda5a9bf4bd374d Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 3 Mar 2026 12:27:37 +0100 Subject: [PATCH] [feat] autocomplete: add bing autocompleter --- docs/admin/settings/settings_search.rst | 1 + searx/autocomplete.py | 24 ++++++++++++++++++++++++ searx/settings.yml | 4 ++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/admin/settings/settings_search.rst b/docs/admin/settings/settings_search.rst index b4ee39086..b60810d78 100644 --- a/docs/admin/settings/settings_search.rst +++ b/docs/admin/settings/settings_search.rst @@ -36,6 +36,7 @@ - ``360search`` - ``baidu`` + - ``bing`` - ``brave`` - ``dbpedia`` - ``duckduckgo`` diff --git a/searx/autocomplete.py b/searx/autocomplete.py index 9612c85e8..8b7285376 100644 --- a/searx/autocomplete.py +++ b/searx/autocomplete.py @@ -1,6 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later """This module implements functions needed for the autocompleter.""" + # pylint: disable=use-dict-literal +import string +import random import json import typing as t @@ -53,6 +56,26 @@ def baidu(query: str, _sxng_locale: str) -> list[str]: return results +def bing(query: str, _sxng_locale: str) -> list[str]: + # bing search autocompleter + base_url = "https://www.bing.com/AS/Suggestions?" + # cvid has to be a 32 character long string consisting of numbers and uppsercase characters + cvid = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(32)) + response = get(base_url + urlencode({'qry': query, 'csr': 1, 'cvid': cvid})) + results: list[str] = [] + + if response.ok: + data: dict[str, t.Any] = response.json() + if 's' in data: + for item in data['s']: + completion: str = item['q'] + # bing uses PUA unicode characters to highlight parts of the query + # we have to remove these manually (U+E000 and U+E001) + completion = completion.replace("\ue000", "").replace("\ue001", "") + results.append(completion) + return results + + def brave(query: str, _sxng_locale: str) -> list[str]: # brave search autocompleter url = 'https://search.brave.com/api/suggest?' @@ -331,6 +354,7 @@ def yandex(query: str, _sxng_locale: str) -> list[str]: backends: dict[str, t.Callable[[str, str], list[str]]] = { '360search': qihu360search, 'baidu': baidu, + 'bing': bing, 'brave': brave, 'dbpedia': dbpedia, 'duckduckgo': duckduckgo, diff --git a/searx/settings.yml b/searx/settings.yml index c4ec42120..75199b2ae 100644 --- a/searx/settings.yml +++ b/searx/settings.yml @@ -32,8 +32,8 @@ brand: search: # Filter results. 0: None, 1: Moderate, 2: Strict safe_search: 0 - # Existing autocomplete backends: "360search", "baidu", "brave", "dbpedia", "duckduckgo", "google", "yandex", - # "mwmbl", "naver", "seznam", "sogou", "startpage", "swisscows", "quark", "qwant", "wikipedia" - + # Existing autocomplete backends: "360search", "baidu", "bing", "brave", "dbpedia", "duckduckgo", "google", + # "yandex", "mwmbl", "naver", "seznam", "sogou", "startpage", "swisscows", "quark", "qwant", "wikipedia" - # leave blank to turn it off by default. autocomplete: "" # minimun characters to type before autocompleter starts