From 28ec87d065750d1dae20f9a1d2a9a5cbb77c882f Mon Sep 17 00:00:00 2001 From: deedy5 <65482418+deedy5@users.noreply.github.com> Date: Thu, 14 May 2026 19:14:02 +0300 Subject: [PATCH 1/2] fix(engines): update Google useragents --- ddgs/engines/google.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ddgs/engines/google.py b/ddgs/engines/google.py index 4fb6b0a..0c62a5f 100644 --- a/ddgs/engines/google.py +++ b/ddgs/engines/google.py @@ -27,14 +27,12 @@ def get_ua() -> str: f"AppleWebKit/537.36 (KHTML, like Gecko) " f"Chrome/{chrome_major}.0.{chrome_build}.{chrome_patch} Mobile Safari/537.36" ) - return f"{ua} GoogleApp/{random.randint(0, 9)}" + return ua + bytes.fromhex("4e53544e5756").decode() class Google(BaseSearchEngine[TextResult]): """Google search engine.""" - disabled = True # !!! - name = "google" category = "text" provider = "google" From c9a1891d86b500ef51ac0f6a5113eaa5ce2ffdc9 Mon Sep 17 00:00:00 2001 From: deedy5 <65482418+deedy5@users.noreply.github.com> Date: Thu, 14 May 2026 23:52:37 +0300 Subject: [PATCH 2/2] feat(engines): add Startpage --- README.md | 2 +- ddgs/cli.py | 1 + ddgs/engines/startpage.py | 70 +++++++++++++++++++++++++++++++++++++++ skills/ddgs/SKILL.md | 2 +- 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 ddgs/engines/startpage.py diff --git a/README.md b/README.md index ddc5408..5922baa 100755 --- a/README.md +++ b/README.md @@ -231,7 +231,7 @@ ___ | DDGS function | Available backends | | --------------|:-------------------| -| text() | `bing`, `brave`, `duckduckgo`, `google`, `grokipedia`, `mojeek`, `yandex`, `yahoo`, `wikipedia`| +| text() | `bing`, `brave`, `duckduckgo`, `google`, `grokipedia`, `mojeek`, `startpage`, `yandex`, `yahoo`, `wikipedia`| | images() | `bing`, `duckduckgo` | | videos() | `duckduckgo` | | news() | `bing`, `duckduckgo`, `yahoo` | diff --git a/ddgs/cli.py b/ddgs/cli.py index da11818..d38bd20 100644 --- a/ddgs/cli.py +++ b/ddgs/cli.py @@ -201,6 +201,7 @@ def version() -> str: "google", "grokipedia", "mojeek", + "startpage", "yandex", "yahoo", "wikipedia", diff --git a/ddgs/engines/startpage.py b/ddgs/engines/startpage.py new file mode 100644 index 0000000..aae339c --- /dev/null +++ b/ddgs/engines/startpage.py @@ -0,0 +1,70 @@ +"""Startpage search engine implementation.""" + +import logging +from collections.abc import Mapping +from typing import Any, ClassVar + +from ddgs.base import BaseSearchEngine +from ddgs.results import TextResult + +logger = logging.getLogger(__name__) + + +class Startpage(BaseSearchEngine[TextResult]): + """Startpage search engine.""" + + name = "startpage" + category = "text" + provider = "google" + + search_url = "https://www.startpage.com/sp/search" + search_method = "POST" + headers_update: ClassVar[dict[str, str]] = {"Referer": "https://www.startpage.com/"} + + items_xpath = "//div[contains(@class, 'result')][./a]" + elements_xpath: ClassVar[Mapping[str, str]] = { + "title": ".//h2//text()", + "href": "./a/@href", + "body": ".//p//text()", + } + + def get_sc(self) -> str: + """Get sc param.""" + resp_text = self.http_client.request("GET", "https://www.startpage.com/").text + tree = self.extract_tree(resp_text) + sc_elements = tree.xpath('//form[@id="search"]//input[@name="sc"]/@value') + self._sc = sc_elements[0] if sc_elements else "" + return self._sc + + def build_payload( + self, + query: str, + region: str, + safesearch: str, + timelimit: str | None, + page: int = 1, + **kwargs: str, # noqa: ARG002 + ) -> dict[str, Any]: + """Build a payload for the Startpage search request.""" + country, lang = region.lower().split("-") + safesearch_base = {"on": "heavy", "moderate": "moderate", "off": "none"} + payload: dict[str, Any] = { + "query": query, + "cat": "web", + "t": "device", + "sc": self.get_sc(), + "lui": "english", + "language": "english", + "abp": "1", + "abd": "0", + "abe": "0", + "qsr": f"{lang}_{country.upper()}", + "qadf": safesearch_base[safesearch.lower()], + "segment": "organic", + } + if page > 1: + payload["page"] = str(page) + if timelimit: + payload["with_date"] = timelimit + + return payload diff --git a/skills/ddgs/SKILL.md b/skills/ddgs/SKILL.md index 7dbc3dd..b0116ca 100644 --- a/skills/ddgs/SKILL.md +++ b/skills/ddgs/SKILL.md @@ -123,7 +123,7 @@ Available backends by method: | Method | Backends | |--------|----------| -| `text()` | `bing`, `brave`, `duckduckgo`, `google`, `grokipedia`, `mojeek`, `yandex`, `yahoo`, `wikipedia` | +| `text()` | `bing`, `brave`, `duckduckgo`, `google`, `grokipedia`, `mojeek`, `startpage`, `yandex`, `yahoo`, `wikipedia` | | `images()` | `bing`, `duckduckgo` | | `videos()` | `duckduckgo` | | `news()` | `bing`, `duckduckgo`, `yahoo` |