Files
searxng/_modules/searx/engines/duckduckgo.html
T
2026-05-10 13:35:24 +00:00

1096 lines
106 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html class="no-js" lang="en" data-content_root="../../../">
<head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../../genindex.html"><link rel="search" title="Search" href="../../../search.html">
<link rel="prefetch" href="../../../_static/searxng-wordmark.svg" as="image">
<!-- Generated with Sphinx 9.1.0 and Furo 2025.12.19 -->
<title>searx.engines.duckduckgo - SearXNG Documentation (2026.5.10+df1f24fb7)</title>
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d111a655" />
<link rel="stylesheet" type="text/css" href="../../../_static/styles/furo.css?v=7bdb33bb" />
<link rel="stylesheet" type="text/css" href="../../../_static/styles/furo-extensions.css?v=8dab3a3b" />
<link rel="stylesheet" type="text/css" href="../../../_static/searxng.css?v=4b1b1f10" />
<style>
body {
--color-code-background: #f2f2f2;
--color-code-foreground: #1e1e1e;
}
@media not print {
body[data-theme="dark"] {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
@media (prefers-color-scheme: dark) {
body:not([data-theme="light"]) {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
}
}
</style></head>
<body>
<script>
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
</script>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-toc" viewBox="0 0 24 24">
<title>Contents</title>
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24">
<title>Light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24">
<title>Dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
</svg>
</symbol>
<symbol id="svg-sun-with-moon" viewBox="0 0 24 24">
<title>Auto light/dark, in light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
<path style="opacity: 50%" d="M 5.411 14.504 C 5.471 14.504 5.532 14.504 5.591 14.504 C 3.639 16.319 4.383 19.569 6.931 20.352 C 7.693 20.586 8.512 20.551 9.25 20.252 C 8.023 23.207 4.056 23.725 2.11 21.184 C 0.166 18.642 1.702 14.949 4.874 14.536 C 5.051 14.512 5.231 14.5 5.411 14.5 L 5.411 14.504 Z"/>
<line x1="14.5" y1="3.25" x2="14.5" y2="1.25"/>
<line x1="14.5" y1="15.85" x2="14.5" y2="17.85"/>
<line x1="10.044" y1="5.094" x2="8.63" y2="3.68"/>
<line x1="19" y1="14.05" x2="20.414" y2="15.464"/>
<line x1="8.2" y1="9.55" x2="6.2" y2="9.55"/>
<line x1="20.8" y1="9.55" x2="22.8" y2="9.55"/>
<line x1="10.044" y1="14.006" x2="8.63" y2="15.42"/>
<line x1="19" y1="5.05" x2="20.414" y2="3.636"/>
<circle cx="14.5" cy="9.55" r="3.6"/>
</svg>
</symbol>
<symbol id="svg-moon-with-sun" viewBox="0 0 24 24">
<title>Auto light/dark, in dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
<path d="M 8.282 7.007 C 8.385 7.007 8.494 7.007 8.595 7.007 C 5.18 10.184 6.481 15.869 10.942 17.24 C 12.275 17.648 13.706 17.589 15 17.066 C 12.851 22.236 5.91 23.143 2.505 18.696 C -0.897 14.249 1.791 7.786 7.342 7.063 C 7.652 7.021 7.965 7 8.282 7 L 8.282 7.007 Z"/>
<line style="opacity: 50%" x1="18" y1="3.705" x2="18" y2="2.5"/>
<line style="opacity: 50%" x1="18" y1="11.295" x2="18" y2="12.5"/>
<line style="opacity: 50%" x1="15.316" y1="4.816" x2="14.464" y2="3.964"/>
<line style="opacity: 50%" x1="20.711" y1="10.212" x2="21.563" y2="11.063"/>
<line style="opacity: 50%" x1="14.205" y1="7.5" x2="13.001" y2="7.5"/>
<line style="opacity: 50%" x1="21.795" y1="7.5" x2="23" y2="7.5"/>
<line style="opacity: 50%" x1="15.316" y1="10.184" x2="14.464" y2="11.036"/>
<line style="opacity: 50%" x1="20.711" y1="4.789" x2="21.563" y2="3.937"/>
<circle style="opacity: 50%" cx="18" cy="7.5" r="2.169"/>
</svg>
</symbol>
<symbol id="svg-pencil" viewBox="0 0 24 24">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-pencil-code">
<path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" />
<path d="M13.5 6.5l4 4" />
<path d="M20 21l2 -2l-2 -2" />
<path d="M17 17l-2 2l2 2" />
</svg>
</symbol>
<symbol id="svg-eye" viewBox="0 0 24 24">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-eye-code">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path
d="M11.11 17.958c-3.209 -.307 -5.91 -2.293 -8.11 -5.958c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6c-.21 .352 -.427 .688 -.647 1.008" />
<path d="M20 21l2 -2l-2 -2" />
<path d="M17 17l-2 2l2 2" />
</svg>
</symbol>
</svg>
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation" aria-label="Toggle site navigation sidebar">
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc" aria-label="Toggle table of contents sidebar">
<label class="overlay sidebar-overlay" for="__navigation"></label>
<label class="overlay toc-overlay" for="__toc"></label>
<a class="skip-to-content muted-link" href="#furo-main-content">Skip to content</a>
<div class="page">
<header class="mobile-header">
<div class="header-left">
<label class="nav-overlay-icon" for="__navigation">
<span class="icon"><svg><use href="#svg-menu"></use></svg></span>
</label>
</div>
<div class="header-center">
<a href="../../../index.html"><div class="brand">SearXNG Documentation (2026.5.10+df1f24fb7)</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
<button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
<span class="icon"><svg><use href="#svg-toc"></use></svg></span>
</label>
</div>
</header>
<aside class="sidebar-drawer">
<div class="sidebar-container">
<div class="sidebar-sticky"><div class="sidebar-scroll"><a class="sidebar-brand" href="../../../index.html">
<div class="sidebar-logo-container">
<img class="sidebar-logo" src="../../../_static/searxng-wordmark.svg" alt="Logo"/>
</div>
<span class="sidebar-brand-text">SearXNG Documentation (2026.5.10+df1f24fb7)</span>
</a><form class="sidebar-search-container" method="get" action="../../../search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
<input type="hidden" name="check_keywords" value="yes">
<input type="hidden" name="area" value="default">
</form>
<div id="searchbox"></div><div class="sidebar-tree">
<ul>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../../user/index.html">User information</a><input aria-label="Toggle navigation of User information" class="toctree-checkbox" id="toctree-checkbox-1" name="toctree-checkbox-1" role="switch" type="checkbox"/><label for="toctree-checkbox-1"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../user/search-syntax.html">Search syntax</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../user/configured_engines.html">Configured Engines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../user/about.html">About SearXNG</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../own-instance.html">Why use a private instance?</a></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../../admin/index.html">Administrator documentation</a><input aria-label="Toggle navigation of Administrator documentation" class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" role="switch" type="checkbox"/><label for="toctree-checkbox-2"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../../admin/settings/index.html">Settings</a><input aria-label="Toggle navigation of Settings" class="toctree-checkbox" id="toctree-checkbox-3" name="toctree-checkbox-3" role="switch" type="checkbox"/><label for="toctree-checkbox-3"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings.html"><code class="docutils literal notranslate"><span class="pre">settings.yml</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_engines.html"><code class="docutils literal notranslate"><span class="pre">engines:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_brand.html"><code class="docutils literal notranslate"><span class="pre">brand:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_general.html"><code class="docutils literal notranslate"><span class="pre">general:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_search.html"><code class="docutils literal notranslate"><span class="pre">search:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_server.html"><code class="docutils literal notranslate"><span class="pre">server:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_ui.html"><code class="docutils literal notranslate"><span class="pre">ui:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_redis.html"><code class="docutils literal notranslate"><span class="pre">redis:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_valkey.html"><code class="docutils literal notranslate"><span class="pre">valkey:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_outgoing.html"><code class="docutils literal notranslate"><span class="pre">outgoing:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_categories_as_tabs.html"><code class="docutils literal notranslate"><span class="pre">categories_as_tabs:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../admin/settings/settings_plugins.html"><code class="docutils literal notranslate"><span class="pre">plugins:</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation.html">Installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation-docker.html">Installation container</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation-scripts.html">Installation Script</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation-searxng.html">Step by step installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation-granian.html">Granian</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation-uwsgi.html">uWSGI</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation-nginx.html">NGINX</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/installation-apache.html">Apache</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/update-searxng.html">SearXNG maintenance</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/answer-captcha.html">Answer CAPTCHA from servers IP</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/searx.favicons.html">Favicons</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/searx.limiter.html">Limiter</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/api.html">Administration API</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/architecture.html">Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/plugins.html">List of plugins</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../admin/buildhosts.html">Buildhosts</a></li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../../dev/index.html">Developer documentation</a><input aria-label="Toggle navigation of Developer documentation" class="toctree-checkbox" id="toctree-checkbox-4" name="toctree-checkbox-4" role="switch" type="checkbox"/><label for="toctree-checkbox-4"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/quickstart.html">Development Quickstart</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/commits.html">Git Commits &amp; Change Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/contribution_guide.html">How to contribute</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/extended_types.html">Extended Types</a></li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../../dev/engines/index.html">Engine Implementations</a><input aria-label="Toggle navigation of Engine Implementations" class="toctree-checkbox" id="toctree-checkbox-5" name="toctree-checkbox-5" role="switch" type="checkbox"/><label for="toctree-checkbox-5"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/enginelib.html">Engine Library</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/engines.html">SearXNGs engines loader</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/engine_overview.html">Engine Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/demo/demo_online.html">Demo Online Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/xpath.html">XPath Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/mediawiki.html">MediaWiki Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/json_engine.html">JSON Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/adobe_stock.html">Adobe Stock</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/alpinelinux.html">Alpine Linux Packages</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/annas_archive.html">Annas Archive</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/aol.html">AOL</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/archlinux.html">Arch Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/arxiv.html">arXiv</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/astrophysics_data_system.html">Astrophysics Data System (ADS)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/azure.html">Azure Resources</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/bing.html">Bing Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/bpb.html">Bpb</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/brave.html">Brave Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/bt4g.html">BT4G</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/chinaso.html">ChinaSo</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/core.html">CORE</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/crossref.html">Crossref</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/dailymotion.html">Dailymotion</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/discourse.html">Discourse Forums</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/duckduckgo.html">DuckDuckGo Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/geizhals.html">Geizhals</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/gitea.html">Gitea</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/github_code.html">Github Code</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/gitlab.html">GitLab</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/google.html">Google Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/huggingface.html">Hugging Face</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/karmasearch.html">Karmasearch</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/lemmy.html">Lemmy</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/loc.html">Library of Congress</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/marginalia.html">Marginalia Search</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/mastodon.html">Mastodon</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/moviepilot.html">Moviepilot</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/mrs.html">Matrix Rooms Search (MRS)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/mwmbl.html">Mwmbl Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/odysee.html">Odysee</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/openalex.html">OpenAlex</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/openlibrary.html">Open Library</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/peertube.html">Peertube Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/piped.html">Piped</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/presearch.html">Presearch Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/pubmed.html">PubMed</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/qwant.html">Qwant</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/radio_browser.html">RadioBrowser</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/recoll.html">Recoll Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/repology.html">Repology</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/reuters.html">Reuters</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/semantic_scholar.html">Semantic Scholar</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/soundcloud.html">Soundcloud</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/sourcehut.html">Sourcehut</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/springer.html">Springer Nature</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/startpage.html">Startpage Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/tagesschau.html">Tagesschau API</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/torznab.html">Torznab WebAPI</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/tubearchivist.html">Tube Archivist</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/void.html">Void Linux binary packages</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/wallhaven.html">Wallhaven</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/wikipedia.html">Wikimedia</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/yacy.html">Yacy</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/yahoo.html">Yahoo Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online/zlibrary.html">Z-Library</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/offline_concept.html">Offline Concept</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/demo/demo_offline.html">Demo Offline Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/offline/command-line-engines.html">Command Line Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/offline/nosql-engines.html">NoSQL databases</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/offline/search-indexer-engines.html">Local Search APIs</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/offline/sql-engines.html">SQL Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/engines/online_url_search/tineye.html">Tineye</a></li>
</ul>
</li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../../dev/result_types/index.html">Result Types</a><input aria-label="Toggle navigation of Result Types" class="toctree-checkbox" id="toctree-checkbox-6" name="toctree-checkbox-6" role="switch" type="checkbox"/><label for="toctree-checkbox-6"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/result_types/base_result.html">Result</a></li>
<li class="toctree-l3 has-children"><a class="reference internal" href="../../../dev/result_types/main_result.html">Main Search Results</a><input aria-label="Toggle navigation of Main Search Results" class="toctree-checkbox" id="toctree-checkbox-7" name="toctree-checkbox-7" role="switch" type="checkbox"/><label for="toctree-checkbox-7"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/result_types/main/mainresult.html"><code class="docutils literal notranslate"><span class="pre">MainResult</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/result_types/main/keyvalue.html">Key-Value Results</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/result_types/main/code.html">Code Results</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/result_types/main/paper.html">Paper Results</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/result_types/main/file.html">File Results</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/result_types/answer.html">Answer Results</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/result_types/correction.html">Correction Results</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/result_types/suggestion.html">Suggestion Results</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/result_types/infobox.html">Infobox Results</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/templates.html">Simple Theme Templates</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/search_api.html">Search API</a></li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../../dev/plugins/index.html">Plugins</a><input aria-label="Toggle navigation of Plugins" class="toctree-checkbox" id="toctree-checkbox-8" name="toctree-checkbox-8" role="switch" type="checkbox"/><label for="toctree-checkbox-8"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/plugins/development.html">Plugin Development</a></li>
<li class="toctree-l3 has-children"><a class="reference internal" href="../../../dev/plugins/builtins.html">Built-in Plugins</a><input aria-label="Toggle navigation of Built-in Plugins" class="toctree-checkbox" id="toctree-checkbox-9" name="toctree-checkbox-9" role="switch" type="checkbox"/><label for="toctree-checkbox-9"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/calculator.html">Calculator</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/hash_plugin.html">Hash Values</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/hostnames.html">Hostnames</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/infinite_scroll.html">Infinite scroll</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/self_info.html">Self-Info</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/tor_check.html">Tor check</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/unit_converter.html">Unit Converter</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/plugins/time_zone.html">Time Zone</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../../dev/answerers/index.html">Answerers</a><input aria-label="Toggle navigation of Answerers" class="toctree-checkbox" id="toctree-checkbox-10" name="toctree-checkbox-10" role="switch" type="checkbox"/><label for="toctree-checkbox-10"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/answerers/development.html">Answerer Development</a></li>
<li class="toctree-l3 has-children"><a class="reference internal" href="../../../dev/answerers/builtins.html">Built-in Answerers</a><input aria-label="Toggle navigation of Built-in Answerers" class="toctree-checkbox" id="toctree-checkbox-11" name="toctree-checkbox-11" role="switch" type="checkbox"/><label for="toctree-checkbox-11"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/answerers/random.html">Random</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../dev/answerers/statistics.html">Statistics</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/translation.html">Translation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/makefile.html">Makefile &amp; <code class="docutils literal notranslate"><span class="pre">./manage</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../dev/reST.html">reST primer</a></li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../../dev/searxng_extra/index.html">Tooling box <code class="docutils literal notranslate"><span class="pre">searxng_extra</span></code></a><input aria-label="Toggle navigation of Tooling box searxng_extra" class="toctree-checkbox" id="toctree-checkbox-12" name="toctree-checkbox-12" role="switch" type="checkbox"/><label for="toctree-checkbox-12"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../dev/searxng_extra/update.html"><code class="docutils literal notranslate"><span class="pre">searxng_extra/update/</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../../utils/index.html">DevOps tooling box</a><input aria-label="Toggle navigation of DevOps tooling box" class="toctree-checkbox" id="toctree-checkbox-13" name="toctree-checkbox-13" role="switch" type="checkbox"/><label for="toctree-checkbox-13"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../utils/searxng.sh.html"><code class="docutils literal notranslate"><span class="pre">utils/searxng.sh</span></code></a></li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../../src/index.html">Source-Code</a><input aria-label="Toggle navigation of Source-Code" class="toctree-checkbox" id="toctree-checkbox-14" name="toctree-checkbox-14" role="switch" type="checkbox"/><label for="toctree-checkbox-14"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.babel_extract.html">Custom message extractor (i18n)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.botdetection.html">Bot Detection</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.cache.html">Caches</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.exceptions.html">SearXNG Exceptions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.favicons.html">Favicons (source)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.infopage.html">Online <code class="docutils literal notranslate"><span class="pre">/info</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.locales.html">Locales</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.search.html">Search</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.search.processors.html">Search processors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.settings.html">Settings Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.sqlitedb.html">SQLite DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.utils.html">Utility functions for the engines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.valkeydb.html">Valkey DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.valkeylib.html">Valkey Library</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../src/searx.weather.html">Weather</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</aside>
<div class="main">
<div class="content">
<div class="article-container">
<a href="#" class="back-to-top muted-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
</svg>
<span>Back to top</span>
</a>
<div class="content-icon-container">
<div class="theme-toggle-container theme-toggle-content">
<button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
<span class="icon"><svg><use href="#svg-toc"></use></svg></span>
</label>
</div>
<article role="main" id="furo-main-content">
<h1>Source code for searx.engines.duckduckgo</h1><div class="highlight"><pre>
<span></span><span class="c1"># SPDX-License-Identifier: AGPL-3.0-or-later</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">DuckDuckGo WEB</span>
<span class="sd">~~~~~~~~~~~~~~</span>
<span class="sd">DDG&#39;s WEB search:</span>
<span class="sd">- DuckDuckGo WEB : ``https://links.duckduckgo.com/d.js?q=..`` (HTTP GET)</span>
<span class="sd">- DuckDuckGo WEB no-AI: ``https://noai.duckduckgo.com/`` (HTTP GET)</span>
<span class="sd">- DuckDuckGo WEB html : ``https://html.duckduckgo.com/html`` (HTTP POST no-JS / form data)</span>
<span class="sd">- DuckDuckGo WEB lite : ``https://lite.duckduckgo.com/lite`` (HTTP POST no-JS / form data)</span>
<span class="sd">DDG&#39;s content search / see engine ``duckduckgo_extra.py``</span>
<span class="sd">- DuckDuckGo Images : ``https://duckduckgo.com/i.js??q=...&amp;vqd=...``</span>
<span class="sd">- DuckDuckGo Videos : ``https://duckduckgo.com/v.js??q=...&amp;vqd=...``</span>
<span class="sd">- DuckDuckGo News : ``https://duckduckgo.com/news.js??q=...&amp;vqd=...``</span>
<span class="sd">.. hint::</span>
<span class="sd"> For WEB searches and to determine the ``vqd`` value, DDG-html (no-JS) is</span>
<span class="sd"> used.</span>
<span class="sd">Special features of the no-JS services (DDG-lite &amp; DDG-html):</span>
<span class="sd">- The no-JS clients receive a form that contains all the controlling parameters.</span>
<span class="sd">- When the form data is submitted, a real WEB browser sets the HTTP *Sec-Fetch*</span>
<span class="sd"> headers.</span>
<span class="sd">HTML ``&lt;form&gt;``, HTTP-Headers &amp; DDG&#39;s bot Blocker:</span>
<span class="sd"> The HTTP User-Agent_ (see below) is generated by the WEB-client and are</span>
<span class="sd"> checked by DDG&#39;s bot blocker.</span>
<span class="sd">To simulate the behavior of a real browser session, it might be necessary to</span>
<span class="sd">evaluate additional headers. For example, in the response from DDG, the</span>
<span class="sd">Referrer-Policy_ is always set to ``origin``. A real browser would then include</span>
<span class="sd">the following header in the next request::</span>
<span class="sd"> Referer: https://html.duckduckgo.com/</span>
<span class="sd">The fields of the html-form are reverse-engineered from DDG-html and may be</span>
<span class="sd">subject to additional bot detection mechanisms and breaking changes in the</span>
<span class="sd">future.</span>
<span class="sd">Query field:</span>
<span class="sd">Intro page: https://html.duckduckgo.com/html/</span>
<span class="sd">- ``q`` (str): Search query string</span>
<span class="sd">- ``b`` (str): Beginning parameter - empty string for first page requests. If a</span>
<span class="sd"> second page is requested, this field is not set!</span>
<span class="sd">Search options:</span>
<span class="sd">- ``kl`` (str): Keyboard language/region code (e.g. &#39;en-us&#39; default: &#39;wt-wt&#39;)</span>
<span class="sd">- ``df`` (str): Time filter, maps to values like &#39;d&#39; (day), &#39;w&#39; (week), &#39;m&#39; (month), &#39;y&#39; (year)</span>
<span class="sd">The key/value pairs ``df`` and ``kl`` are additional saved in the cookies,</span>
<span class="sd">example::</span>
<span class="sd"> Cookie: kl=en-us; df=m</span>
<span class="sd">*next page* form fields:</span>
<span class="sd">- ``nextParams`` (str): Continuation parameters from previous page response,</span>
<span class="sd"> typically empty string. Opposite of ``b``; this field is not set when</span>
<span class="sd"> requesting the first result page.</span>
<span class="sd">- ``api`` (str): API endpoint identifier, typically &#39;d.js&#39;</span>
<span class="sd">- ``o`` (str): Output format, typically ``json``</span>
<span class="sd">- ``v`` (str): Typically ``l`` for subsequent pages</span>
<span class="sd">- ``dc`` (int): Display count - value equal to offset (s) + 1</span>
<span class="sd">- ``s`` (int): Search offset for pagination</span>
<span class="sd">- ``vqd`` (str): Validation query digest</span>
<span class="sd">General assumptions regarding DDG&#39;s bot blocker:</span>
<span class="sd">- Except ``Cookie: kl=..; df=..`` DDG does not use cookies in any of its</span>
<span class="sd"> services.</span>
<span class="sd">- DDG does not accept queries with more than 499 chars</span>
<span class="sd">- The ``vqd`` value (&quot;Validation query digest&quot;) is needed to pass DDG&#39;s bot</span>
<span class="sd"> protection and is used by all request to DDG.</span>
<span class="sd">- The ``vqd`` value is generally not needed for the first query (intro); it is</span>
<span class="sd"> only required when additional pages are accessed (or when new content needs to</span>
<span class="sd"> be loaded for the query while scrolling).</span>
<span class="sd">- The second page (additional content) for a query cannot be requested without</span>
<span class="sd"> ``vqd``, as this would lead to an immediate blocking, since such a use-case</span>
<span class="sd"> does not exist in the process flows provided by DDG (and is a clear indication</span>
<span class="sd"> of a bot).</span>
<span class="sd">The following HTTP headers are being evaluated (and may possibly be responsible</span>
<span class="sd">for issues):</span>
<span class="sd">User-Agent_:</span>
<span class="sd"> The HTTP User-Agent is also involved in the formation of the vqd value, read</span>
<span class="sd"> `DuckDuckGo Bot Detection Research &amp; Solution`_. However, it is not checked</span>
<span class="sd"> whether the UA is a known header. However, it is possible that certain UA</span>
<span class="sd"> headers (such as curl) are filtered.</span>
<span class="sd">Sec-Fetch-Mode_:</span>
<span class="sd"> In the past, Sec-Fetch-Mode had to be set to &#39;navigate&#39;, otherwise there were</span>
<span class="sd"> problems with the bot blocker.. I don&#39;t know if DDG still evaluates this</span>
<span class="sd"> header today</span>
<span class="sd">Accept-Language_:</span>
<span class="sd"> DDG-Lite and DDG-HTML TRY to guess user&#39;s preferred language from the HTTP</span>
<span class="sd"> ``Accept-Language``. Optional the user can select a region filter (but not a</span>
<span class="sd"> language).</span>
<span class="sd">In DDG&#39;s bot blocker, the IP will be blocked (DDG does not have a client session!)</span>
<span class="sd">- As far as is known, it is possible to remove a un-blocked an IP by executing a</span>
<span class="sd"> DDG query in a real web browser over the blocked IP (at least that&#39;s my</span>
<span class="sd"> assumption).</span>
<span class="sd"> How exactly the blocking mechanism currently works is not fully known, and</span>
<span class="sd"> there were also changes to the bot blocker in the period of Q3/Q4 2025: in the</span>
<span class="sd"> past, the IP blocking was implemented as a &#39;sliding window&#39; (unblock after</span>
<span class="sd"> about 1 hour without requests from this IP)</span>
<span class="sd">Terms / phrases that you keep coming across:</span>
<span class="sd">- ``d.js``, ``i.js``, ``v.js``, ``news.js`` are the endpoints of the DDG&#39;s web</span>
<span class="sd"> API through which additional content for a query can be requested (vqd</span>
<span class="sd"> required)</span>
<span class="sd"> The ``*.js`` endpoints return a JSON response and can therefore only be</span>
<span class="sd"> executed on a JS-capable client.</span>
<span class="sd"> The service at https://lite.duckduckgo.com/lite offers general WEB searches</span>
<span class="sd"> (no news, videos etc). DDG-lite and DDG-html can be used by clients that do</span>
<span class="sd"> not support JS, aka *no-JS*.</span>
<span class="sd"> DDG-lite works a bit differently: here, ``d.js`` is not an endpoint but a</span>
<span class="sd"> field (``api=d.js``) in a form that is sent to DDG-lite.</span>
<span class="sd">- The request argument ``origin=funnel_home_website`` is often seen in the DDG</span>
<span class="sd"> services when the category is changed (e.g., from web search to news, images,</span>
<span class="sd"> or to the video category)</span>
<span class="sd">.. _DuckDuckGo Bot Detection Research &amp; Solution:</span>
<span class="sd"> https://github.com/ggfevans/searxng/blob/mod-sidecar-harvester/docs/ddg-bot-detection-research.md</span>
<span class="sd">.. _Sec-Fetch-Mode:</span>
<span class="sd"> https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Sec-Fetch-Mode&gt;</span>
<span class="sd">.. _Referrer-Policy:</span>
<span class="sd"> https://developer.mozilla.org/docs/Web/HTTP/Reference/Headers/Referrer-Policy#directives</span>
<span class="sd">.. _Referer:</span>
<span class="sd"> https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Referer</span>
<span class="sd">.. _User-Agent:</span>
<span class="sd"> https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent</span>
<span class="sd">.. _Accept-Language:</span>
<span class="sd"> https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Language</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># pylint: disable=global-statement</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">t</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">babel</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">lxml.html</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx</span><span class="w"> </span><span class="kn">import</span> <span class="n">locales</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.enginelib</span><span class="w"> </span><span class="kn">import</span> <span class="n">EngineCache</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.enginelib.traits</span><span class="w"> </span><span class="kn">import</span> <span class="n">EngineTraits</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.exceptions</span><span class="w"> </span><span class="kn">import</span> <span class="n">SearxEngineCaptchaException</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.external_bang</span><span class="w"> </span><span class="kn">import</span> <span class="n">EXTERNAL_BANGS</span><span class="p">,</span> <span class="n">get_node</span> <span class="c1"># type: ignore</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.result_types</span><span class="w"> </span><span class="kn">import</span> <span class="n">EngineResults</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.utils</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
<span class="n">ElementType</span><span class="p">,</span>
<span class="n">eval_xpath</span><span class="p">,</span>
<span class="n">eval_xpath_getindex</span><span class="p">,</span>
<span class="n">extr</span><span class="p">,</span>
<span class="n">extract_text</span><span class="p">,</span>
<span class="n">gen_useragent</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.extended_types</span><span class="w"> </span><span class="kn">import</span> <span class="n">SXNG_Response</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.search.processors</span><span class="w"> </span><span class="kn">import</span> <span class="n">OnlineParams</span>
<span class="n">about</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span> <span class="o">|</span> <span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;website&quot;</span><span class="p">:</span> <span class="s2">&quot;https://lite.duckduckgo.com/lite/&quot;</span><span class="p">,</span>
<span class="s2">&quot;wikidata_id&quot;</span><span class="p">:</span> <span class="s2">&quot;Q12805&quot;</span><span class="p">,</span>
<span class="s2">&quot;use_official_api&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;require_api_key&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;results&quot;</span><span class="p">:</span> <span class="s2">&quot;HTML&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">categories</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;general&quot;</span><span class="p">,</span> <span class="s2">&quot;web&quot;</span><span class="p">]</span>
<span class="n">paging</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">time_range_support</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">safesearch</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>
<span class="sd">&quot;&quot;&quot;DDG-lite: user can&#39;t select but the results are filtered.&quot;&quot;&quot;</span>
<span class="n">ddg_url</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;https://html.duckduckgo.com/html/&quot;</span>
<span class="sd">&quot;&quot;&quot;The process flow for determining the ``vqd`` values was implemented for the</span>
<span class="sd">no-JS variant (DDG-html)&quot;&quot;&quot;</span>
<span class="n">time_range_dict</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;day&quot;</span><span class="p">:</span> <span class="s2">&quot;d&quot;</span><span class="p">,</span> <span class="s2">&quot;week&quot;</span><span class="p">:</span> <span class="s2">&quot;w&quot;</span><span class="p">,</span> <span class="s2">&quot;month&quot;</span><span class="p">:</span> <span class="s2">&quot;m&quot;</span><span class="p">,</span> <span class="s2">&quot;year&quot;</span><span class="p">:</span> <span class="s2">&quot;y&quot;</span><span class="p">}</span>
<span class="n">_CACHE</span><span class="p">:</span> <span class="n">EngineCache</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># pyright: ignore[reportAssignmentType]</span>
<span class="sd">&quot;&quot;&quot;Persistent (SQLite) key/value cache that deletes its values after ``expire``</span>
<span class="sd">seconds.&quot;&quot;&quot;</span>
<span class="n">_HTTP_User_Agent</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">gen_useragent</span><span class="p">()</span>
<span class="k">def</span><span class="w"> </span><span class="nf">get_cache</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">EngineCache</span><span class="p">:</span>
<span class="k">global</span> <span class="n">_CACHE</span>
<span class="k">if</span> <span class="n">_CACHE</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># pyright: ignore[reportUnnecessaryComparison]</span>
<span class="n">_CACHE</span> <span class="o">=</span> <span class="n">EngineCache</span><span class="p">(</span><span class="s2">&quot;duckduckgo&quot;</span><span class="p">)</span> <span class="c1"># pyright: ignore[reportUnreachable]</span>
<span class="k">return</span> <span class="n">_CACHE</span>
<span class="k">def</span><span class="w"> </span><span class="nf">set_vqd</span><span class="p">(</span><span class="n">query</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="nb">int</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">params</span><span class="p">:</span> <span class="s2">&quot;OnlineParams&quot;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">cache</span> <span class="o">=</span> <span class="n">get_cache</span><span class="p">()</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">secret_hash</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">//</span><span class="si">{</span><span class="n">params</span><span class="p">[</span><span class="s1">&#39;headers&#39;</span><span class="p">][</span><span class="s1">&#39;User-Agent&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">expire</span><span class="o">=</span><span class="mi">3600</span><span class="p">)</span>
<div class="viewcode-block" id="get_vqd">
<a class="viewcode-back" href="../../../dev/engines/online/duckduckgo.html#searx.engines.duckduckgo.get_vqd">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">get_vqd</span><span class="p">(</span>
<span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
<span class="n">params</span><span class="p">:</span> <span class="s2">&quot;OnlineParams&quot;</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the ``vqd`` value that fits to the *query* (and HTTP User-Agent_</span>
<span class="sd"> header).</span>
<span class="sd"> :param query: the query term</span>
<span class="sd"> :param params: request parameters</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">cache</span> <span class="o">=</span> <span class="n">get_cache</span><span class="p">()</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">secret_hash</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">//</span><span class="si">{</span><span class="n">params</span><span class="p">[</span><span class="s1">&#39;headers&#39;</span><span class="p">][</span><span class="s1">&#39;User-Agent&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">value</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;get_vqd: re-use cached value: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span></div>
<div class="viewcode-block" id="get_ddg_lang">
<a class="viewcode-back" href="../../../dev/engines/online/duckduckgo.html#searx.engines.duckduckgo.get_ddg_lang">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">get_ddg_lang</span><span class="p">(</span>
<span class="n">eng_traits</span><span class="p">:</span> <span class="n">EngineTraits</span><span class="p">,</span>
<span class="n">sxng_locale</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
<span class="n">default</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;en_US&quot;</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Get DuckDuckGo&#39;s language identifier from SearXNG&#39;s locale.</span>
<span class="sd"> .. hint::</span>
<span class="sd"> `DDG-lite &lt;https://lite.duckduckgo.com/lite&gt;`__ and the *no Javascript*</span>
<span class="sd"> page https://html.duckduckgo.com/html do not offer a language selection</span>
<span class="sd"> to the user.</span>
<span class="sd"> DDG defines its languages by a region code (:py:obj:`fetch_traits`). To</span>
<span class="sd"> get region and language of a DDG service use:</span>
<span class="sd"> .. code: python</span>
<span class="sd"> eng_region = traits.get_region(params[&quot;searxng_locale&quot;], traits.all_locale)</span>
<span class="sd"> eng_lang = get_ddg_lang(traits, params[&quot;searxng_locale&quot;])</span>
<span class="sd"> It might confuse, but the ``l`` value of the cookie is what SearXNG calls</span>
<span class="sd"> the *region*:</span>
<span class="sd"> .. code:: python</span>
<span class="sd"> # !ddi paris :es-AR --&gt; {&#39;ad&#39;: &#39;es_AR&#39;, &#39;ah&#39;: &#39;ar-es&#39;, &#39;l&#39;: &#39;ar-es&#39;}</span>
<span class="sd"> params[&#39;cookies&#39;][&#39;ad&#39;] = eng_lang</span>
<span class="sd"> params[&#39;cookies&#39;][&#39;ah&#39;] = eng_region</span>
<span class="sd"> params[&#39;cookies&#39;][&#39;l&#39;] = eng_region</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lang</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="n">eng_traits</span><span class="o">.</span><span class="n">get_language</span><span class="p">(</span><span class="n">sxng_locale</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span>
<span class="k">return</span> <span class="n">eng_traits</span><span class="o">.</span><span class="n">custom</span><span class="p">[</span><span class="s2">&quot;lang_region&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">sxng_locale</span><span class="p">,</span> <span class="n">lang</span><span class="p">)</span> <span class="ow">or</span> <span class="kc">None</span></div>
<span class="n">ddg_reg_map</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;tw-tzh&quot;</span><span class="p">:</span> <span class="s2">&quot;zh_TW&quot;</span><span class="p">,</span>
<span class="s2">&quot;hk-tzh&quot;</span><span class="p">:</span> <span class="s2">&quot;zh_HK&quot;</span><span class="p">,</span>
<span class="s2">&quot;ct-ca&quot;</span><span class="p">:</span> <span class="s2">&quot;skip&quot;</span><span class="p">,</span> <span class="c1"># ct-ca and es-ca both map to ca_ES</span>
<span class="s2">&quot;es-ca&quot;</span><span class="p">:</span> <span class="s2">&quot;ca_ES&quot;</span><span class="p">,</span>
<span class="s2">&quot;id-en&quot;</span><span class="p">:</span> <span class="s2">&quot;id_ID&quot;</span><span class="p">,</span>
<span class="s2">&quot;no-no&quot;</span><span class="p">:</span> <span class="s2">&quot;nb_NO&quot;</span><span class="p">,</span>
<span class="s2">&quot;jp-jp&quot;</span><span class="p">:</span> <span class="s2">&quot;ja_JP&quot;</span><span class="p">,</span>
<span class="s2">&quot;kr-kr&quot;</span><span class="p">:</span> <span class="s2">&quot;ko_KR&quot;</span><span class="p">,</span>
<span class="s2">&quot;xa-ar&quot;</span><span class="p">:</span> <span class="s2">&quot;ar_SA&quot;</span><span class="p">,</span>
<span class="s2">&quot;sl-sl&quot;</span><span class="p">:</span> <span class="s2">&quot;sl_SI&quot;</span><span class="p">,</span>
<span class="s2">&quot;th-en&quot;</span><span class="p">:</span> <span class="s2">&quot;th_TH&quot;</span><span class="p">,</span>
<span class="s2">&quot;vn-en&quot;</span><span class="p">:</span> <span class="s2">&quot;vi_VN&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">ddg_lang_map</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1"># use ar --&gt; ar_EG (Egypt&#39;s arabic)</span>
<span class="s2">&quot;ar_DZ&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;ar_JO&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;ar_SA&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># use bn --&gt; bn_BD</span>
<span class="s2">&quot;bn_IN&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># use de --&gt; de_DE</span>
<span class="s2">&quot;de_CH&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># use en --&gt; en_US,</span>
<span class="s2">&quot;en_AU&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;en_CA&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;en_GB&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># Esperanto</span>
<span class="s2">&quot;eo_XX&quot;</span><span class="p">:</span> <span class="s2">&quot;eo&quot;</span><span class="p">,</span>
<span class="c1"># use es --&gt; es_ES,</span>
<span class="s2">&quot;es_AR&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_CL&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_CO&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_CR&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_EC&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_MX&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_PE&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_UY&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;es_VE&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># use fr --&gt; rf_FR</span>
<span class="s2">&quot;fr_CA&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;fr_CH&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="s2">&quot;fr_BE&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># use nl --&gt; nl_NL</span>
<span class="s2">&quot;nl_BE&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># use pt --&gt; pt_PT</span>
<span class="s2">&quot;pt_BR&quot;</span><span class="p">:</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">,</span>
<span class="c1"># skip these languages</span>
<span class="s2">&quot;od_IN&quot;</span><span class="p">:</span> <span class="s2">&quot;skip&quot;</span><span class="p">,</span>
<span class="s2">&quot;io_XX&quot;</span><span class="p">:</span> <span class="s2">&quot;skip&quot;</span><span class="p">,</span>
<span class="s2">&quot;tokipona_XX&quot;</span><span class="p">:</span> <span class="s2">&quot;skip&quot;</span><span class="p">,</span>
<span class="p">}</span>
<div class="viewcode-block" id="quote_ddg_bangs">
<a class="viewcode-back" href="../../../dev/engines/online/duckduckgo.html#searx.engines.duckduckgo.quote_ddg_bangs">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">quote_ddg_bangs</span><span class="p">(</span><span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;To avoid a redirect, the !bang directives in the query string are</span>
<span class="sd"> quoted.&quot;&quot;&quot;</span>
<span class="n">_q</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;(\s+)&quot;</span><span class="p">,</span> <span class="n">query</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">val</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">val</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;!&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">get_node</span><span class="p">(</span><span class="n">EXTERNAL_BANGS</span><span class="p">,</span> <span class="n">val</span><span class="p">[</span><span class="mi">1</span><span class="p">:]):</span>
<span class="n">val</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;&#39;</span><span class="si">{</span><span class="n">val</span><span class="si">}</span><span class="s2">&#39;&quot;</span>
<span class="n">_q</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
<span class="k">return</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_q</span><span class="p">)</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">request</span><span class="p">(</span><span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">params</span><span class="p">:</span> <span class="s2">&quot;OnlineParams&quot;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">query</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">500</span><span class="p">:</span>
<span class="c1"># DDG does not accept queries with more than 499 chars</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">return</span>
<span class="n">query</span> <span class="o">=</span> <span class="n">quote_ddg_bangs</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
<span class="n">eng_region</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">traits</span><span class="o">.</span><span class="n">get_region</span><span class="p">(</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;searxng_locale&quot;</span><span class="p">],</span>
<span class="n">traits</span><span class="o">.</span><span class="n">all_locale</span><span class="p">,</span>
<span class="p">)</span> <span class="c1"># pyright: ignore[reportAssignmentType]</span>
<span class="c1"># HTTP headers</span>
<span class="c1"># ============</span>
<span class="n">headers</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;headers&quot;</span><span class="p">]</span>
<span class="c1"># The vqd value is generated from the query and the UA header. To be able to</span>
<span class="c1"># reuse the vqd value, the UA header must be static.</span>
<span class="n">headers</span><span class="p">[</span><span class="s2">&quot;User-Agent&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_HTTP_User_Agent</span>
<span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Sec-Fetch-Dest&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;document&quot;</span>
<span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Sec-Fetch-Mode&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;navigate&quot;</span>
<span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Sec-Fetch-Site&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;same-origin&quot;</span>
<span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Sec-Fetch-User&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;?1&quot;</span>
<span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Referer&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;https://html.duckduckgo.com/&quot;</span>
<span class="n">ui_lang</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;searxng_locale&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Accept-Language&quot;</span><span class="p">):</span>
<span class="n">headers</span><span class="p">[</span><span class="s2">&quot;Accept-Language&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">ui_lang</span><span class="si">}</span><span class="s2">,</span><span class="si">{</span><span class="n">ui_lang</span><span class="si">}</span><span class="s2">-</span><span class="si">{</span><span class="n">ui_lang</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span><span class="si">}</span><span class="s2">;q=0.7&quot;</span>
<span class="c1"># DDG search form (POST data)</span>
<span class="c1"># ===========================</span>
<span class="c1"># form_data: dict[str,str] = {&quot;v&quot;: &quot;l&quot;, &quot;api&quot;: &quot;d.js&quot;, &quot;o&quot;: &quot;json&quot;}</span>
<span class="c1"># &quot;&quot;&quot;The WEB-API &quot;endpoint&quot; is ``api``.&quot;&quot;&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;data&quot;</span><span class="p">]</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;q&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">query</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ddg_url</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;method&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;POST&quot;</span>
<span class="k">if</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;pageno&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;b&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># vqd is required to request other pages after the first one</span>
<span class="n">vqd</span> <span class="o">=</span> <span class="n">get_vqd</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>
<span class="k">if</span> <span class="n">vqd</span><span class="p">:</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;vqd&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">vqd</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Don&quot;t try to call follow up pages without a vqd value.</span>
<span class="c1"># DDG recognizes this as a request from a bot. This lowers the</span>
<span class="c1"># reputation of the SearXNG IP and DDG starts to activate CAPTCHAs.</span>
<span class="c1"># set suspend time to zero is OK --&gt; ddg does not block the IP</span>
<span class="k">raise</span> <span class="n">SearxEngineCaptchaException</span><span class="p">(</span>
<span class="n">suspended_time</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
<span class="n">message</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;VQD missed (page: </span><span class="si">{</span><span class="n">params</span><span class="p">[</span><span class="s1">&#39;pageno&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">, locale: </span><span class="si">{</span><span class="n">params</span><span class="p">[</span><span class="s1">&#39;searxng_locale&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;searxng_locale&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;zh&quot;</span><span class="p">):</span>
<span class="c1"># Some locales (at least China) do not have a &quot;next page&quot; button and DDG</span>
<span class="c1"># will return a HTTP/2 403 Forbidden for a request of such a page.</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">return</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;nextParams&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;api&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;d.js&quot;</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;o&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;json&quot;</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;v&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;l&quot;</span>
<span class="n">offset</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">+</span> <span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="s2">&quot;pageno&quot;</span><span class="p">]</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="mi">15</span> <span class="c1"># Page 2 = 10, Page 2+n = 10 + n*15</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;dc&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;s&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">offset</span>
<span class="k">if</span> <span class="n">eng_region</span> <span class="o">==</span> <span class="s2">&quot;wt-wt&quot;</span><span class="p">:</span>
<span class="c1"># Put empty kl in form data if language/region set to all</span>
<span class="c1"># data[&quot;kl&quot;] = &quot;&quot;</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;kl&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;wt-wt&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;kl&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">eng_region</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;cookies&quot;</span><span class="p">][</span><span class="s2">&quot;kl&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">eng_region</span>
<span class="n">t_range</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">time_range_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="s2">&quot;time_range&quot;</span><span class="p">]),</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">t_range</span><span class="p">:</span>
<span class="n">data</span><span class="p">[</span><span class="s2">&quot;df&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">t_range</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;cookies&quot;</span><span class="p">][</span><span class="s2">&quot;df&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">t_range</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;headers&quot;</span><span class="p">][</span><span class="s2">&quot;Content-Type&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;application/x-www-form-urlencoded&quot;</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;headers&quot;</span><span class="p">][</span><span class="s2">&quot;Referer&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ddg_url</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;param headers: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;headers&quot;</span><span class="p">])</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;param data: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;data&quot;</span><span class="p">])</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;param cookies: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;cookies&quot;</span><span class="p">])</span>
<div class="viewcode-block" id="is_ddg_captcha">
<a class="viewcode-back" href="../../../dev/engines/online/duckduckgo.html#searx.engines.duckduckgo.is_ddg_captcha">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">is_ddg_captcha</span><span class="p">(</span><span class="n">dom</span><span class="p">:</span> <span class="n">ElementType</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;In case of CAPTCHA ddg response its own *not a Robot* dialog and is not</span>
<span class="sd"> redirected to a CAPTCHA page.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">eval_xpath</span><span class="p">(</span><span class="n">dom</span><span class="p">,</span> <span class="s2">&quot;//form[@id=&#39;challenge-form&#39;]&quot;</span><span class="p">))</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">response</span><span class="p">(</span><span class="n">resp</span><span class="p">:</span> <span class="s2">&quot;SXNG_Response&quot;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">EngineResults</span><span class="p">:</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">EngineResults</span><span class="p">()</span>
<span class="k">if</span> <span class="n">resp</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">303</span><span class="p">:</span>
<span class="k">return</span> <span class="n">res</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">lxml</span><span class="o">.</span><span class="n">html</span><span class="o">.</span><span class="n">fromstring</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
<span class="n">params</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">search_params</span>
<span class="k">if</span> <span class="n">is_ddg_captcha</span><span class="p">(</span><span class="n">doc</span><span class="p">):</span>
<span class="c1"># set suspend time to zero is OK --&gt; ddg does not block the IP</span>
<span class="k">raise</span> <span class="n">SearxEngineCaptchaException</span><span class="p">(</span><span class="n">suspended_time</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">message</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;CAPTCHA (</span><span class="si">{</span><span class="n">params</span><span class="p">[</span><span class="s1">&#39;data&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;kl&#39;</span><span class="p">)</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
<span class="n">form</span> <span class="o">=</span> <span class="n">eval_xpath</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span> <span class="s1">&#39;//input[@name=&quot;vqd&quot;]/..&#39;</span><span class="p">)</span>
<span class="c1"># Some locales (at least China) do not have a &quot;next page&quot; button and DDG</span>
<span class="c1"># will return a HTTP/2 403 Forbidden for a request of such a page.</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
<span class="n">form</span> <span class="o">=</span> <span class="n">form</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">form_vqd</span> <span class="o">=</span> <span class="n">eval_xpath</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="s1">&#39;//input[@name=&quot;vqd&quot;]/@value&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">q</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="s2">&quot;data&quot;</span><span class="p">][</span><span class="s2">&quot;q&quot;</span><span class="p">])</span>
<span class="n">set_vqd</span><span class="p">(</span>
<span class="n">query</span><span class="o">=</span><span class="n">q</span><span class="p">,</span>
<span class="n">value</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">form_vqd</span><span class="p">),</span>
<span class="n">params</span><span class="o">=</span><span class="n">resp</span><span class="o">.</span><span class="n">search_params</span><span class="p">,</span>
<span class="p">)</span>
<span class="c1"># just select &quot;web-result&quot; and ignore results of class &quot;result--ad result--ad--small&quot;</span>
<span class="k">for</span> <span class="n">div_result</span> <span class="ow">in</span> <span class="n">eval_xpath</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span> <span class="s1">&#39;//div[@id=&quot;links&quot;]/div[contains(@class, &quot;web-result&quot;)]&#39;</span><span class="p">):</span>
<span class="n">_title</span> <span class="o">=</span> <span class="n">eval_xpath</span><span class="p">(</span><span class="n">div_result</span><span class="p">,</span> <span class="s2">&quot;.//h2/a&quot;</span><span class="p">)</span>
<span class="n">_content</span> <span class="o">=</span> <span class="n">eval_xpath_getindex</span><span class="p">(</span><span class="n">div_result</span><span class="p">,</span> <span class="s1">&#39;.//a[contains(@class, &quot;result__snippet&quot;)]&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[])</span>
<span class="n">res</span><span class="o">.</span><span class="n">add</span><span class="p">(</span>
<span class="n">res</span><span class="o">.</span><span class="n">types</span><span class="o">.</span><span class="n">MainResult</span><span class="p">(</span>
<span class="n">title</span><span class="o">=</span><span class="n">extract_text</span><span class="p">(</span><span class="n">_title</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">url</span><span class="o">=</span><span class="n">eval_xpath</span><span class="p">(</span><span class="n">div_result</span><span class="p">,</span> <span class="s2">&quot;.//h2/a/@href&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">],</span>
<span class="n">content</span><span class="o">=</span><span class="n">extract_text</span><span class="p">(</span><span class="n">_content</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="n">zero_click_info_xpath</span> <span class="o">=</span> <span class="s1">&#39;//div[@id=&quot;zero_click_abstract&quot;]&#39;</span>
<span class="n">zero_click</span> <span class="o">=</span> <span class="n">extract_text</span><span class="p">(</span><span class="n">eval_xpath</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span> <span class="n">zero_click_info_xpath</span><span class="p">))</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="c1"># type: ignore</span>
<span class="k">if</span> <span class="n">zero_click</span> <span class="ow">and</span> <span class="p">(</span>
<span class="s2">&quot;Your IP address is&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">zero_click</span>
<span class="ow">and</span> <span class="s2">&quot;Your user agent:&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">zero_click</span>
<span class="ow">and</span> <span class="s2">&quot;URL Decoded:&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">zero_click</span>
<span class="p">):</span>
<span class="n">res</span><span class="o">.</span><span class="n">add</span><span class="p">(</span>
<span class="n">res</span><span class="o">.</span><span class="n">types</span><span class="o">.</span><span class="n">Answer</span><span class="p">(</span>
<span class="n">answer</span><span class="o">=</span><span class="n">zero_click</span><span class="p">,</span>
<span class="n">url</span><span class="o">=</span><span class="n">eval_xpath_getindex</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span> <span class="s1">&#39;//div[@id=&quot;zero_click_abstract&quot;]/a/@href&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">res</span>
<div class="viewcode-block" id="fetch_traits">
<a class="viewcode-back" href="../../../dev/engines/online/duckduckgo.html#searx.engines.duckduckgo.fetch_traits">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">fetch_traits</span><span class="p">(</span><span class="n">engine_traits</span><span class="p">:</span> <span class="n">EngineTraits</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Fetch languages &amp; regions from DuckDuckGo.</span>
<span class="sd"> SearXNG&#39;s ``all`` locale maps DuckDuckGo&#39;s &quot;All regions&quot; (``wt-wt``).</span>
<span class="sd"> DuckDuckGo&#39;s language &quot;Browsers preferred language&quot; (``wt_WT``) makes no</span>
<span class="sd"> sense in a SearXNG request since SearXNG&#39;s ``all`` will not add a</span>
<span class="sd"> ``Accept-Language`` HTTP header. The value in ``engine_traits.all_locale``</span>
<span class="sd"> is ``wt-wt`` (the region).</span>
<span class="sd"> Beside regions DuckDuckGo also defines its languages by region codes. By</span>
<span class="sd"> example these are the english languages in DuckDuckGo:</span>
<span class="sd"> - en_US</span>
<span class="sd"> - en_AU</span>
<span class="sd"> - en_CA</span>
<span class="sd"> - en_GB</span>
<span class="sd"> The function :py:obj:`get_ddg_lang` evaluates DuckDuckGo&#39;s language from</span>
<span class="sd"> SearXNG&#39;s locale.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># pylint: disable=too-many-branches, too-many-statements, disable=import-outside-toplevel</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.network</span><span class="w"> </span><span class="kn">import</span> <span class="n">get</span> <span class="c1"># see https://github.com/searxng/searxng/issues/762</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">js_obj_str_to_python</span>
<span class="c1"># fetch regions</span>
<span class="n">engine_traits</span><span class="o">.</span><span class="n">all_locale</span> <span class="o">=</span> <span class="s2">&quot;wt-wt&quot;</span>
<span class="c1"># updated from u661.js to u.7669f071a13a7daa57cb / should be updated automatically?</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">get</span><span class="p">(</span><span class="s2">&quot;https://duckduckgo.com/dist/util/u.7669f071a13a7daa57cb.js&quot;</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">resp</span><span class="o">.</span><span class="n">ok</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Response from DuckDuckGo regions is not OK.&quot;</span><span class="p">)</span>
<span class="n">js_code</span> <span class="o">=</span> <span class="n">extr</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="s2">&quot;regions:&quot;</span><span class="p">,</span> <span class="s2">&quot;,snippetLengths&quot;</span><span class="p">)</span>
<span class="n">regions</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">js_code</span><span class="p">)</span>
<span class="k">for</span> <span class="n">eng_tag</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">regions</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">eng_tag</span> <span class="o">==</span> <span class="s2">&quot;wt-wt&quot;</span><span class="p">:</span>
<span class="n">engine_traits</span><span class="o">.</span><span class="n">all_locale</span> <span class="o">=</span> <span class="s2">&quot;wt-wt&quot;</span>
<span class="k">continue</span>
<span class="n">region</span> <span class="o">=</span> <span class="n">ddg_reg_map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">eng_tag</span><span class="p">)</span>
<span class="k">if</span> <span class="n">region</span> <span class="o">==</span> <span class="s2">&quot;skip&quot;</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">region</span><span class="p">:</span>
<span class="n">eng_territory</span><span class="p">,</span> <span class="n">eng_lang</span> <span class="o">=</span> <span class="n">eng_tag</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;-&quot;</span><span class="p">)</span>
<span class="n">region</span> <span class="o">=</span> <span class="n">eng_lang</span> <span class="o">+</span> <span class="s2">&quot;_&quot;</span> <span class="o">+</span> <span class="n">eng_territory</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sxng_tag</span> <span class="o">=</span> <span class="n">locales</span><span class="o">.</span><span class="n">region_tag</span><span class="p">(</span><span class="n">babel</span><span class="o">.</span><span class="n">Locale</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">region</span><span class="p">))</span>
<span class="k">except</span> <span class="n">babel</span><span class="o">.</span><span class="n">UnknownLocaleError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;ERROR: </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s</span><span class="s2">) -&gt; </span><span class="si">%s</span><span class="s2"> is unknown by babel&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">eng_tag</span><span class="p">,</span> <span class="n">region</span><span class="p">))</span>
<span class="k">continue</span>
<span class="n">conflict</span> <span class="o">=</span> <span class="n">engine_traits</span><span class="o">.</span><span class="n">regions</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">sxng_tag</span><span class="p">)</span>
<span class="k">if</span> <span class="n">conflict</span><span class="p">:</span>
<span class="k">if</span> <span class="n">conflict</span> <span class="o">!=</span> <span class="n">eng_tag</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;CONFLICT: babel </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">, </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">sxng_tag</span><span class="p">,</span> <span class="n">conflict</span><span class="p">,</span> <span class="n">eng_tag</span><span class="p">))</span>
<span class="k">continue</span>
<span class="n">engine_traits</span><span class="o">.</span><span class="n">regions</span><span class="p">[</span><span class="n">sxng_tag</span><span class="p">]</span> <span class="o">=</span> <span class="n">eng_tag</span>
<span class="c1"># fetch languages</span>
<span class="n">engine_traits</span><span class="o">.</span><span class="n">custom</span><span class="p">[</span><span class="s2">&quot;lang_region&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">js_code</span> <span class="o">=</span> <span class="n">extr</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="s2">&quot;languages:&quot;</span><span class="p">,</span> <span class="s2">&quot;,regions&quot;</span><span class="p">)</span>
<span class="n">languages</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="n">js_obj_str_to_python</span><span class="p">(</span><span class="n">js_code</span><span class="p">)</span>
<span class="k">for</span> <span class="n">eng_lang</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">languages</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">eng_lang</span> <span class="o">==</span> <span class="s2">&quot;wt_WT&quot;</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">babel_tag</span> <span class="o">=</span> <span class="n">ddg_lang_map</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">eng_lang</span><span class="p">,</span> <span class="n">eng_lang</span><span class="p">)</span>
<span class="k">if</span> <span class="n">babel_tag</span> <span class="o">==</span> <span class="s2">&quot;skip&quot;</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">babel_tag</span> <span class="o">==</span> <span class="s2">&quot;lang_region&quot;</span><span class="p">:</span>
<span class="n">sxng_tag</span> <span class="o">=</span> <span class="n">locales</span><span class="o">.</span><span class="n">region_tag</span><span class="p">(</span><span class="n">babel</span><span class="o">.</span><span class="n">Locale</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">eng_lang</span><span class="p">))</span>
<span class="n">engine_traits</span><span class="o">.</span><span class="n">custom</span><span class="p">[</span><span class="s2">&quot;lang_region&quot;</span><span class="p">][</span><span class="n">sxng_tag</span><span class="p">]</span> <span class="o">=</span> <span class="n">eng_lang</span>
<span class="k">continue</span>
<span class="n">sxng_tag</span> <span class="o">=</span> <span class="n">locales</span><span class="o">.</span><span class="n">language_tag</span><span class="p">(</span><span class="n">babel</span><span class="o">.</span><span class="n">Locale</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">babel_tag</span><span class="p">))</span>
<span class="k">except</span> <span class="n">babel</span><span class="o">.</span><span class="n">UnknownLocaleError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;ERROR: language </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s</span><span class="s2">) is unknown by babel&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">eng_lang</span><span class="p">))</span>
<span class="k">continue</span>
<span class="n">conflict</span> <span class="o">=</span> <span class="n">engine_traits</span><span class="o">.</span><span class="n">languages</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">sxng_tag</span><span class="p">)</span>
<span class="k">if</span> <span class="n">conflict</span><span class="p">:</span>
<span class="k">if</span> <span class="n">conflict</span> <span class="o">!=</span> <span class="n">eng_lang</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;CONFLICT: babel </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">, </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">sxng_tag</span><span class="p">,</span> <span class="n">conflict</span><span class="p">,</span> <span class="n">eng_lang</span><span class="p">))</span>
<span class="k">continue</span>
<span class="n">engine_traits</span><span class="o">.</span><span class="n">languages</span><span class="p">[</span><span class="n">sxng_tag</span><span class="p">]</span> <span class="o">=</span> <span class="n">eng_lang</span></div>
</pre></div>
</article>
</div>
<footer>
<div class="related-pages">
</div>
<div class="bottom-of-page">
<div class="left-details">
<div class="copyright">
Copyright &#169; SearXNG team
</div>
Made with
<a href="https://github.com/pradyunsg/furo">Furo</a>
</div>
<div class="right-details">
<div class="icons">
<a class="muted-link " href="https://github.com/searxng/searxng/" aria-label="GitHub">&#x1F4BE;</a>
<a class="muted-link " href="https://searx.space/" aria-label="searx.space">&#x1F310;</a>
</div>
</div>
</div>
</footer>
</div>
<aside class="toc-drawer no-toc">
</aside>
</div>
</div><script src="../../../_static/documentation_options.js?v=c15363ef"></script>
<script src="../../../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../../../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="../../../_static/scripts/furo.js?v=46bd48cc"></script>
</body>
</html>