互联网搜索引擎之DuckDuckGo

什么是DuckDuckGo

官网:https://duckduckgo.com/

DuckDuckGo是一款互联网搜索引擎,其注重用户隐私,及避免个性化检索所致的过滤气泡[4]。它与其他搜索引擎不同的地方在于其不会分析自己的用户、对所有使用同一组关键词的用户显示同样的结果[7]。它也强调返回最佳结果,而不是最多网站链接之结果。

DuckDuckGo的优势

  • 使用该搜索引擎的最大优势是在线隐私。 DuckDuckGo 以各种方式维护您的隐私。
  • DuckDuckGo 不会监控任何用户信息并记录搜索历史。
  • DuckDuckGo 不会在任何内容中歧视并显示公正的结果。
  • DuckDuckGo 比 Google 更快。 重定向时不需要太多时间。
  • DuckDuckGo 显然不像 Google 和其他搜索引擎那样运行。
  • 不会根据您之前的搜索和个人信息定位广告。

DuckDuckGo 是一个网络搜索引擎就像谷歌一样。 这只是一个网站您可以在其中查找内容并搜索互联网。 隐私是其日益流行的主要原因。

ai agent tool:ddg-search DuckDuckGo 搜索

duckduckgo_search.py
源码: langchain_community/utilities/duckduckgo_search.py

"""Util that calls DuckDuckGo Search.

No setup required. Free.
https://pypi.org/project/duckduckgo-search/
"""

from typing import Any, Dict, List, Optional

from pydantic import BaseModel, ConfigDict, model_validator


class DuckDuckGoSearchAPIWrapper(BaseModel):
    """Wrapper for DuckDuckGo Search API.

    Free and does not require any setup.
    """

    region: Optional[str] = "wt-wt"
    """
    See https://pypi.org/project/duckduckgo-search/#regions
    """
    safesearch: str = "moderate"
    """
    Options: strict, moderate, off
    """
    time: Optional[str] = "y"
    """
    Options: d, w, m, y
    """
    max_results: int = 5
    backend: str = "api"
    """
    Options: api, html, lite
    """
    source: str = "text"
    """
    Options: text, news
    """

    model_config = ConfigDict(
        extra="forbid",
    )

    @model_validator(mode="before")
    @classmethod
    def validate_environment(cls, values: Dict) -> Any:
        """Validate that python package exists in environment."""
        try:
            from duckduckgo_search import DDGS  # noqa: F401
        except ImportError:
            raise ImportError(
                "Could not import duckduckgo-search python package. "
                "Please install it with `pip install -U duckduckgo-search`."
            )
        return values

    def _ddgs_text(
        self, query: str, max_results: Optional[int] = None
    ) -> List[Dict[str, str]]:
        """Run query through DuckDuckGo text search and return results."""
        from duckduckgo_search import DDGS

        with DDGS() as ddgs:
            ddgs_gen = ddgs.text(
                query,
                region=self.region,  # type: ignore[arg-type]
                safesearch=self.safesearch,
                timelimit=self.time,
                max_results=max_results or self.max_results,
                backend=self.backend,
            )
            if ddgs_gen:
                return [r for r in ddgs_gen]
        return []

    def _ddgs_news(
        self, query: str, max_results: Optional[int] = None
    ) -> List[Dict[str, str]]:
        """Run query through DuckDuckGo news search and return results."""
        from duckduckgo_search import DDGS

        with DDGS() as ddgs:
            ddgs_gen = ddgs.news(
                query,
                region=self.region,  # type: ignore[arg-type]
                safesearch=self.safesearch,
                timelimit=self.time,
                max_results=max_results or self.max_results,
            )
            if ddgs_gen:
                return [r for r in ddgs_gen]
        return []

    def run(self, query: str) -> str:
        """Run query through DuckDuckGo and return concatenated results."""
        if self.source == "text":
            results = self._ddgs_text(query)
        elif self.source == "news":
            results = self._ddgs_news(query)
        else:
            results = []

        if not results:
            return "No good DuckDuckGo Search Result was found"
        return " ".join(r["body"] for r in results)

    def results(
        self, query: str, max_results: int, source: Optional[str] = None
    ) -> List[Dict[str, str]]:
        """Run query through DuckDuckGo and return metadata.

        Args:
            query: The query to search for.
            max_results: The number of results to return.
            source: The source to look from.

        Returns:
            A list of dictionaries with the following keys:
                snippet - The description of the result.
                title - The title of the result.
                link - The link to the result.
        """
        source = source or self.source
        if source == "text":
            results = [
                {"snippet": r["body"], "title": r["title"], "link": r["href"]}
                for r in self._ddgs_text(query, max_results=max_results)
            ]
        elif source == "news":
            results = [
                {
                    "snippet": r["body"],
                    "title": r["title"],
                    "link": r["url"],
                    "date": r["date"],
                    "source": r["source"],
                }
                for r in self._ddgs_news(query, max_results=max_results)
            ]
        else:
            results = []

        if results is None:
            results = [{"Result": "No good DuckDuckGo Search Result was found"}]

        return results

属性定义:

  • region: 可选字符串,指定搜索区域,默认为 “wt-wt”(全球)。

  • safesearch: 字符串,控制安全搜索级别,默认为 “moderate”(适度)。

  • time: 可选字符串,限制搜索结果的时间范围,默认为 “y”(一年内)。

  • max_results: 整数,设置返回的最大结果数,默认为 5。

  • backend: 字符串,指定搜索的后端类型,默认为 “api”。

  • source: 字符串,指定搜索内容的来源,默认为 “text”(文本)。

  • 使用 ConfigDict 配置模型,设置 extra=“forbid”,禁止添加未定义的额外属性。

  • validate_environment: 使用 model_validator 装饰器定义一个类方法,在实例创建之前验证环境,确保 duckduckgo_search 包已安装。如果未安装,抛出 ImportError。

私有搜索方法

  • _ddgs_text: 执行 DuckDuckGo 的文本搜索,返回结果列表。
  • _ddgs_news: 执行 DuckDuckGo 的新闻搜索,返回结果列表。

主要方法

  • run: 接受一个查询字符串,决定执行文本搜索还是新闻搜索,并返回结果的连接字符串。如果没有找到结果,返回一条消息。
  • results: 返回一个包含搜索结果元数据的字典列表。根据 source 的值(文本或新闻),调用相应的私有搜索方法,并提取所需的字段(如标题、链接、描述等)。

DuckDuckGoSearchAPIWrapper 类封装了 DuckDuckGo 搜索 API 的功能,使得用户可以方便地执行文本和新闻搜索。通过使用 Pydantic,代码实现了数据验证、配置管理和自定义验证逻辑,确保了代码的健壮性和可靠性。这个类非常适合需要集成 DuckDuckGo 搜索功能的应用程序。

继承 BaseModel 的主要原因是利用 Pydantic 提供的强大功能:

  1. 数据验证
    BaseModel 自动为模型的属性提供数据验证。这意味着在创建 DuckDuckGoSearchAPIWrapper 的实例时,Pydantic 会检查传入的数据类型是否符合定义的类型。例如,如果某个属性被定义为 int,而用户传入了一个字符串,Pydantic 会抛出一个错误,确保数据的正确性。

  2. 默认值和类型提示
    通过继承 BaseModel,可以轻松定义属性的默认值和类型提示。这使得代码更加清晰和易于维护。例如,您可以为 region 属性设置默认值为 “wt-wt”,并指定其类型为 Optional[str],这使得其他开发者在使用这个类时能够快速理解每个属性的预期类型和默认行为。

3。 额外的配置选项
BaseModel 提供了许多配置选项,例如 ConfigDict,可以用来控制模型的行为。在这个例子中,使用 extra="forbid" 配置,确保实例不能包含未定义的额外属性,这有助于防止意外的错误和数据不一致

  1. 方便的序列化和反序列化
    Pydantic 的模型可以轻松地进行序列化(转换为字典或 JSON)和反序列化(从字典或 JSON 创建模型实例)。这对于处理 API 请求和响应非常有用,因为可以直接将模型实例转换为 JSON 格式,或者从 JSON 数据创建模型实例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西京刀客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值