forked from zaclys/searxng
449 lines
49 KiB
HTML
449 lines
49 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>searx.engines.bing — SearXNG Documentation (2023.8.11+905ce2a6f)</title>
|
||
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=4f649999" />
|
||
<link rel="stylesheet" type="text/css" href="../../../_static/searxng.css?v=52e4ff28" />
|
||
<link rel="stylesheet" type="text/css" href="../../../_static/tabs.css?v=a5c4661c" />
|
||
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js?v=3c88bde0"></script>
|
||
<script src="../../../_static/doctools.js?v=888ff710"></script>
|
||
<script src="../../../_static/sphinx_highlight.js?v=4825356b"></script>
|
||
<script src="../../../_static/tabs.js?v=3030b3cb"></script>
|
||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||
<link rel="search" title="Search" href="../../../search.html" />
|
||
</head><body>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../../../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../../../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../../../index.html">SearXNG Documentation (2023.8.11+905ce2a6f)</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="../engines.html" accesskey="U">searx.engines</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">searx.engines.bing</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<h1>Source code for searx.engines.bing</h1><div class="highlight"><pre>
|
||
<span></span><span class="c1"># SPDX-License-Identifier: AGPL-3.0-or-later</span>
|
||
<span class="c1"># lint: pylint</span>
|
||
<span class="sd">"""This is the implementation of the Bing-WEB engine. Some of this</span>
|
||
<span class="sd">implementations are shared by other engines:</span>
|
||
|
||
<span class="sd">- :ref:`bing images engine`</span>
|
||
<span class="sd">- :ref:`bing news engine`</span>
|
||
<span class="sd">- :ref:`bing videos engine`</span>
|
||
|
||
<span class="sd">On the `preference page`_ Bing offers a lot of languages an regions (see section</span>
|
||
<span class="sd">'Search results languages' and 'Country/region'). However, the abundant choice</span>
|
||
<span class="sd">does not correspond to reality, where Bing has a full-text indexer only for a</span>
|
||
<span class="sd">limited number of languages. By example: you can select a language like Māori</span>
|
||
<span class="sd">but you never get a result in this language.</span>
|
||
|
||
<span class="sd">What comes a bit closer to the truth are the `search-APIs`_ but they don`t seem</span>
|
||
<span class="sd">to be completely correct either (if you take a closer look you will find some</span>
|
||
<span class="sd">inaccuracies there too):</span>
|
||
|
||
<span class="sd">- :py:obj:`searx.engines.bing.bing_traits_url`</span>
|
||
<span class="sd">- :py:obj:`searx.engines.bing_videos.bing_traits_url`</span>
|
||
<span class="sd">- :py:obj:`searx.engines.bing_images.bing_traits_url`</span>
|
||
<span class="sd">- :py:obj:`searx.engines.bing_news.bing_traits_url`</span>
|
||
|
||
<span class="sd">.. _preference page: https://www.bing.com/account/general</span>
|
||
<span class="sd">.. _search-APIs: https://learn.microsoft.com/en-us/bing/search-apis/</span>
|
||
|
||
<span class="sd">"""</span>
|
||
<span class="c1"># pylint: disable=too-many-branches, invalid-name</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">TYPE_CHECKING</span>
|
||
<span class="kn">import</span> <span class="nn">datetime</span>
|
||
<span class="kn">import</span> <span class="nn">re</span>
|
||
<span class="kn">import</span> <span class="nn">uuid</span>
|
||
<span class="kn">from</span> <span class="nn">urllib.parse</span> <span class="kn">import</span> <span class="n">urlencode</span>
|
||
<span class="kn">from</span> <span class="nn">lxml</span> <span class="kn">import</span> <span class="n">html</span>
|
||
<span class="kn">import</span> <span class="nn">babel</span>
|
||
<span class="kn">import</span> <span class="nn">babel.languages</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">searx.utils</span> <span class="kn">import</span> <span class="n">eval_xpath</span><span class="p">,</span> <span class="n">extract_text</span><span class="p">,</span> <span class="n">eval_xpath_list</span><span class="p">,</span> <span class="n">eval_xpath_getindex</span>
|
||
<span class="kn">from</span> <span class="nn">searx.locales</span> <span class="kn">import</span> <span class="n">language_tag</span><span class="p">,</span> <span class="n">region_tag</span>
|
||
<span class="kn">from</span> <span class="nn">searx.enginelib.traits</span> <span class="kn">import</span> <span class="n">EngineTraits</span>
|
||
|
||
<span class="k">if</span> <span class="n">TYPE_CHECKING</span><span class="p">:</span>
|
||
<span class="kn">import</span> <span class="nn">logging</span>
|
||
|
||
<span class="n">logger</span><span class="p">:</span> <span class="n">logging</span><span class="o">.</span><span class="n">Logger</span>
|
||
|
||
<span class="n">traits</span><span class="p">:</span> <span class="n">EngineTraits</span>
|
||
|
||
<span class="n">about</span> <span class="o">=</span> <span class="p">{</span>
|
||
<span class="s2">"website"</span><span class="p">:</span> <span class="s1">'https://www.bing.com'</span><span class="p">,</span>
|
||
<span class="s2">"wikidata_id"</span><span class="p">:</span> <span class="s1">'Q182496'</span><span class="p">,</span>
|
||
<span class="s2">"official_api_documentation"</span><span class="p">:</span> <span class="s1">'https://www.microsoft.com/en-us/bing/apis/bing-web-search-api'</span><span class="p">,</span>
|
||
<span class="s2">"use_official_api"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
|
||
<span class="s2">"require_api_key"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
|
||
<span class="s2">"results"</span><span class="p">:</span> <span class="s1">'HTML'</span><span class="p">,</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="n">send_accept_language_header</span> <span class="o">=</span> <span class="kc">True</span>
|
||
<span class="sd">"""Bing tries to guess user's language and territory from the HTTP</span>
|
||
<span class="sd">Accept-Language. Optional the user can select a search-language (can be</span>
|
||
<span class="sd">different to the UI language) and a region (market code)."""</span>
|
||
|
||
<span class="c1"># engine dependent config</span>
|
||
<span class="n">categories</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'general'</span><span class="p">,</span> <span class="s1">'web'</span><span class="p">]</span>
|
||
<span class="n">paging</span> <span class="o">=</span> <span class="kc">True</span>
|
||
<span class="n">time_range_support</span> <span class="o">=</span> <span class="kc">True</span>
|
||
<span class="n">safesearch</span> <span class="o">=</span> <span class="kc">True</span>
|
||
<span class="n">safesearch_types</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2</span><span class="p">:</span> <span class="s1">'STRICT'</span><span class="p">,</span> <span class="mi">1</span><span class="p">:</span> <span class="s1">'DEMOTE'</span><span class="p">,</span> <span class="mi">0</span><span class="p">:</span> <span class="s1">'OFF'</span><span class="p">}</span> <span class="c1"># cookie: ADLT=STRICT</span>
|
||
|
||
<span class="n">base_url</span> <span class="o">=</span> <span class="s1">'https://www.bing.com/search'</span>
|
||
<span class="sd">"""Bing (Web) search URL"""</span>
|
||
|
||
<span class="n">bing_traits_url</span> <span class="o">=</span> <span class="s1">'https://learn.microsoft.com/en-us/bing/search-apis/bing-web-search/reference/market-codes'</span>
|
||
<span class="sd">"""Bing (Web) search API description"""</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">_get_offset_from_pageno</span><span class="p">(</span><span class="n">pageno</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">pageno</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">+</span> <span class="mi">1</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">set_bing_cookies</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="n">engine_language</span><span class="p">,</span> <span class="n">engine_region</span><span class="p">,</span> <span class="n">SID</span><span class="p">):</span>
|
||
|
||
<span class="c1"># set cookies</span>
|
||
<span class="c1"># -----------</span>
|
||
|
||
<span class="n">params</span><span class="p">[</span><span class="s1">'cookies'</span><span class="p">][</span><span class="s1">'_EDGE_V'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'1'</span>
|
||
|
||
<span class="c1"># _EDGE_S: F=1&SID=3A5253BD6BCA609509B741876AF961CA&mkt=zh-tw</span>
|
||
<span class="n">_EDGE_S</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s1">'F=1'</span><span class="p">,</span>
|
||
<span class="s1">'SID=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">SID</span><span class="p">,</span>
|
||
<span class="s1">'mkt=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">engine_region</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span>
|
||
<span class="s1">'ui=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">engine_language</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span>
|
||
<span class="p">]</span>
|
||
<span class="n">params</span><span class="p">[</span><span class="s1">'cookies'</span><span class="p">][</span><span class="s1">'_EDGE_S'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'&'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_EDGE_S</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">"cookie _EDGE_S=</span><span class="si">%s</span><span class="s2">"</span><span class="p">,</span> <span class="n">params</span><span class="p">[</span><span class="s1">'cookies'</span><span class="p">][</span><span class="s1">'_EDGE_S'</span><span class="p">])</span>
|
||
|
||
<span class="c1"># "_EDGE_CD": "m=zh-tw",</span>
|
||
|
||
<span class="n">_EDGE_CD</span> <span class="o">=</span> <span class="p">[</span> <span class="c1"># pylint: disable=invalid-name</span>
|
||
<span class="s1">'m=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">engine_region</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="c1"># search region: zh-cn</span>
|
||
<span class="s1">'u=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">engine_language</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="c1"># UI: en-us</span>
|
||
<span class="p">]</span>
|
||
|
||
<span class="n">params</span><span class="p">[</span><span class="s1">'cookies'</span><span class="p">][</span><span class="s1">'_EDGE_CD'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'&'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_EDGE_CD</span><span class="p">)</span> <span class="o">+</span> <span class="s1">';'</span>
|
||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"cookie _EDGE_CD=</span><span class="si">%s</span><span class="s2">"</span><span class="p">,</span> <span class="n">params</span><span class="p">[</span><span class="s1">'cookies'</span><span class="p">][</span><span class="s1">'_EDGE_CD'</span><span class="p">])</span>
|
||
|
||
<span class="n">SRCHHPGUSR</span> <span class="o">=</span> <span class="p">[</span> <span class="c1"># pylint: disable=invalid-name</span>
|
||
<span class="s1">'SRCHLANG=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">engine_language</span><span class="p">,</span>
|
||
<span class="c1"># Trying to set ADLT cookie here seems not to have any effect, I assume</span>
|
||
<span class="c1"># there is some age verification by a cookie (and/or session ID) needed,</span>
|
||
<span class="c1"># to disable the SafeSearch.</span>
|
||
<span class="s1">'ADLT=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">safesearch_types</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="s1">'safesearch'</span><span class="p">],</span> <span class="s1">'DEMOTE'</span><span class="p">),</span>
|
||
<span class="p">]</span>
|
||
<span class="n">params</span><span class="p">[</span><span class="s1">'cookies'</span><span class="p">][</span><span class="s1">'SRCHHPGUSR'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'&'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">SRCHHPGUSR</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">"cookie SRCHHPGUSR=</span><span class="si">%s</span><span class="s2">"</span><span class="p">,</span> <span class="n">params</span><span class="p">[</span><span class="s1">'cookies'</span><span class="p">][</span><span class="s1">'SRCHHPGUSR'</span><span class="p">])</span>
|
||
|
||
|
||
<div class="viewcode-block" id="request"><a class="viewcode-back" href="../../../dev/engines/online/bing.html#searx.engines.bing.request">[docs]</a><span class="k">def</span> <span class="nf">request</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""Assemble a Bing-Web request."""</span>
|
||
|
||
<span class="n">engine_region</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="s1">'searxng_locale'</span><span class="p">],</span> <span class="s1">'en-US'</span><span class="p">)</span>
|
||
<span class="n">engine_language</span> <span class="o">=</span> <span class="n">traits</span><span class="o">.</span><span class="n">get_language</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="s1">'searxng_locale'</span><span class="p">],</span> <span class="s1">'en'</span><span class="p">)</span>
|
||
|
||
<span class="n">SID</span> <span class="o">=</span> <span class="n">uuid</span><span class="o">.</span><span class="n">uuid1</span><span class="p">()</span><span class="o">.</span><span class="n">hex</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
|
||
<span class="n">CVID</span> <span class="o">=</span> <span class="n">uuid</span><span class="o">.</span><span class="n">uuid1</span><span class="p">()</span><span class="o">.</span><span class="n">hex</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
|
||
|
||
<span class="n">set_bing_cookies</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="n">engine_language</span><span class="p">,</span> <span class="n">engine_region</span><span class="p">,</span> <span class="n">SID</span><span class="p">)</span>
|
||
|
||
<span class="c1"># build URL query</span>
|
||
<span class="c1"># ---------------</span>
|
||
|
||
<span class="c1"># query term</span>
|
||
<span class="n">page</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'pageno'</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
|
||
<span class="n">query_params</span> <span class="o">=</span> <span class="p">{</span>
|
||
<span class="c1"># fmt: off</span>
|
||
<span class="s1">'q'</span><span class="p">:</span> <span class="n">query</span><span class="p">,</span>
|
||
<span class="s1">'pq'</span><span class="p">:</span> <span class="n">query</span><span class="p">,</span>
|
||
<span class="s1">'cvid'</span><span class="p">:</span> <span class="n">CVID</span><span class="p">,</span>
|
||
<span class="s1">'qs'</span><span class="p">:</span> <span class="s1">'n'</span><span class="p">,</span>
|
||
<span class="s1">'sp'</span><span class="p">:</span> <span class="s1">'-1'</span>
|
||
<span class="c1"># fmt: on</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="c1"># page</span>
|
||
<span class="k">if</span> <span class="n">page</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
|
||
<span class="n">referer</span> <span class="o">=</span> <span class="n">base_url</span> <span class="o">+</span> <span class="s1">'?'</span> <span class="o">+</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">query_params</span><span class="p">)</span>
|
||
<span class="n">params</span><span class="p">[</span><span class="s1">'headers'</span><span class="p">][</span><span class="s1">'Referer'</span><span class="p">]</span> <span class="o">=</span> <span class="n">referer</span>
|
||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"headers.Referer --> </span><span class="si">%s</span><span class="s2">"</span><span class="p">,</span> <span class="n">referer</span><span class="p">)</span>
|
||
|
||
<span class="n">query_params</span><span class="p">[</span><span class="s1">'first'</span><span class="p">]</span> <span class="o">=</span> <span class="n">_get_offset_from_pageno</span><span class="p">(</span><span class="n">page</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">page</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
|
||
<span class="n">query_params</span><span class="p">[</span><span class="s1">'FORM'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'PERE'</span>
|
||
<span class="k">elif</span> <span class="n">page</span> <span class="o">></span> <span class="mi">2</span><span class="p">:</span>
|
||
<span class="n">query_params</span><span class="p">[</span><span class="s1">'FORM'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'PERE</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">page</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span>
|
||
|
||
<span class="n">filters</span> <span class="o">=</span> <span class="s1">''</span>
|
||
<span class="k">if</span> <span class="n">params</span><span class="p">[</span><span class="s1">'time_range'</span><span class="p">]:</span>
|
||
<span class="n">query_params</span><span class="p">[</span><span class="s1">'filt'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'custom'</span>
|
||
|
||
<span class="k">if</span> <span class="n">params</span><span class="p">[</span><span class="s1">'time_range'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'day'</span><span class="p">:</span>
|
||
<span class="n">filters</span> <span class="o">=</span> <span class="s1">'ex1:"ez1"'</span>
|
||
<span class="k">elif</span> <span class="n">params</span><span class="p">[</span><span class="s1">'time_range'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'week'</span><span class="p">:</span>
|
||
<span class="n">filters</span> <span class="o">=</span> <span class="s1">'ex1:"ez2"'</span>
|
||
<span class="k">elif</span> <span class="n">params</span><span class="p">[</span><span class="s1">'time_range'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'month'</span><span class="p">:</span>
|
||
<span class="n">filters</span> <span class="o">=</span> <span class="s1">'ex1:"ez3"'</span>
|
||
<span class="k">elif</span> <span class="n">params</span><span class="p">[</span><span class="s1">'time_range'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'year'</span><span class="p">:</span>
|
||
<span class="n">epoch_1970</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="n">today_no</span> <span class="o">=</span> <span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">()</span> <span class="o">-</span> <span class="n">epoch_1970</span><span class="p">)</span><span class="o">.</span><span class="n">days</span>
|
||
<span class="n">filters</span> <span class="o">=</span> <span class="s1">'ex1:"ez5_</span><span class="si">%s</span><span class="s1">_</span><span class="si">%s</span><span class="s1">"'</span> <span class="o">%</span> <span class="p">(</span><span class="n">today_no</span> <span class="o">-</span> <span class="mi">365</span><span class="p">,</span> <span class="n">today_no</span><span class="p">)</span>
|
||
|
||
<span class="n">params</span><span class="p">[</span><span class="s1">'url'</span><span class="p">]</span> <span class="o">=</span> <span class="n">base_url</span> <span class="o">+</span> <span class="s1">'?'</span> <span class="o">+</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">query_params</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">filters</span><span class="p">:</span>
|
||
<span class="n">params</span><span class="p">[</span><span class="s1">'url'</span><span class="p">]</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s1">'url'</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'&filters='</span> <span class="o">+</span> <span class="n">filters</span>
|
||
<span class="k">return</span> <span class="n">params</span></div>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">response</span><span class="p">(</span><span class="n">resp</span><span class="p">):</span>
|
||
<span class="c1"># pylint: disable=too-many-locals,import-outside-toplevel</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">searx.network</span> <span class="kn">import</span> <span class="n">Request</span><span class="p">,</span> <span class="n">multi_requests</span> <span class="c1"># see https://github.com/searxng/searxng/issues/762</span>
|
||
|
||
<span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="n">result_len</span> <span class="o">=</span> <span class="mi">0</span>
|
||
|
||
<span class="n">dom</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="c1"># parse results again if nothing is found yet</span>
|
||
|
||
<span class="n">url_to_resolve</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="n">url_to_resolve_index</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
|
||
<span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">eval_xpath_list</span><span class="p">(</span><span class="n">dom</span><span class="p">,</span> <span class="s1">'//ol[@id="b_results"]/li[contains(@class, "b_algo")]'</span><span class="p">):</span>
|
||
|
||
<span class="n">link</span> <span class="o">=</span> <span class="n">eval_xpath_getindex</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="s1">'.//h2/a'</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">link</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">continue</span>
|
||
<span class="n">url</span> <span class="o">=</span> <span class="n">link</span><span class="o">.</span><span class="n">attrib</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'href'</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">link</span><span class="p">)</span>
|
||
|
||
<span class="n">content</span> <span class="o">=</span> <span class="n">eval_xpath</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="s1">'(.//p)[1]'</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">content</span><span class="p">:</span>
|
||
<span class="c1"># Make sure that the element is free of <a href> links</span>
|
||
<span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s1">'.//a'</span><span class="p">):</span>
|
||
<span class="n">e</span><span class="o">.</span><span class="n">getparent</span><span class="p">()</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">e</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="c1"># get the real URL either using the URL shown to user or following the Bing URL</span>
|
||
<span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'https://www.bing.com/ck/a?'</span><span class="p">):</span>
|
||
<span class="n">url_cite</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">result</span><span class="p">,</span> <span class="s1">'.//div[@class="b_attribution"]/cite'</span><span class="p">))</span>
|
||
<span class="c1"># Bing can shorten the URL either at the end or in the middle of the string</span>
|
||
<span class="k">if</span> <span class="p">(</span>
|
||
<span class="n">url_cite</span>
|
||
<span class="ow">and</span> <span class="n">url_cite</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'https://'</span><span class="p">)</span>
|
||
<span class="ow">and</span> <span class="s1">'…'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">url_cite</span>
|
||
<span class="ow">and</span> <span class="s1">'...'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">url_cite</span>
|
||
<span class="ow">and</span> <span class="s1">'›'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">url_cite</span>
|
||
<span class="p">):</span>
|
||
<span class="c1"># no need for an additional HTTP request</span>
|
||
<span class="n">url</span> <span class="o">=</span> <span class="n">url_cite</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="c1"># resolve the URL with an additional HTTP request</span>
|
||
<span class="n">url_to_resolve</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">url</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'&ntb=1'</span><span class="p">,</span> <span class="s1">'&ntb=F'</span><span class="p">))</span>
|
||
<span class="n">url_to_resolve_index</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
||
<span class="n">url</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># remove the result if the HTTP Bing redirect raise an exception</span>
|
||
|
||
<span class="c1"># append result</span>
|
||
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s1">'url'</span><span class="p">:</span> <span class="n">url</span><span class="p">,</span> <span class="s1">'title'</span><span class="p">:</span> <span class="n">title</span><span class="p">,</span> <span class="s1">'content'</span><span class="p">:</span> <span class="n">content</span><span class="p">})</span>
|
||
<span class="c1"># increment result pointer for the next iteration in this loop</span>
|
||
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
|
||
<span class="c1"># resolve all Bing redirections in parallel</span>
|
||
<span class="n">request_list</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="n">Request</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">allow_redirects</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">headers</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="s1">'headers'</span><span class="p">])</span> <span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="n">url_to_resolve</span>
|
||
<span class="p">]</span>
|
||
<span class="n">response_list</span> <span class="o">=</span> <span class="n">multi_requests</span><span class="p">(</span><span class="n">request_list</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">redirect_response</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">response_list</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">redirect_response</span><span class="p">,</span> <span class="ne">Exception</span><span class="p">):</span>
|
||
<span class="n">results</span><span class="p">[</span><span class="n">url_to_resolve_index</span><span class="p">[</span><span class="n">i</span><span class="p">]][</span><span class="s1">'url'</span><span class="p">]</span> <span class="o">=</span> <span class="n">redirect_response</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">'location'</span><span class="p">]</span>
|
||
|
||
<span class="c1"># get number_of_results</span>
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">result_len_container</span> <span class="o">=</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</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="s1">'//span[@class="sb_count"]//text()'</span><span class="p">))</span>
|
||
<span class="k">if</span> <span class="s2">"-"</span> <span class="ow">in</span> <span class="n">result_len_container</span><span class="p">:</span>
|
||
|
||
<span class="c1"># Remove the part "from-to" for paginated request ...</span>
|
||
<span class="n">result_len_container</span> <span class="o">=</span> <span class="n">result_len_container</span><span class="p">[</span><span class="n">result_len_container</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">"-"</span><span class="p">)</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span> <span class="p">:]</span>
|
||
|
||
<span class="n">result_len_container</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s1">'[^0-9]'</span><span class="p">,</span> <span class="s1">''</span><span class="p">,</span> <span class="n">result_len_container</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">result_len_container</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="n">result_len</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">result_len_container</span><span class="p">)</span>
|
||
|
||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="c1"># pylint: disable=broad-except</span>
|
||
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s1">'result error :</span><span class="se">\n</span><span class="si">%s</span><span class="s1">'</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">result_len</span> <span class="ow">and</span> <span class="n">_get_offset_from_pageno</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">search_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"pageno"</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="o">></span> <span class="n">result_len</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="p">[]</span>
|
||
|
||
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s1">'number_of_results'</span><span class="p">:</span> <span class="n">result_len</span><span class="p">})</span>
|
||
<span class="k">return</span> <span class="n">results</span>
|
||
|
||
|
||
<div class="viewcode-block" id="fetch_traits"><a class="viewcode-back" href="../../../dev/engines/online/bing.html#searx.engines.bing.fetch_traits">[docs]</a><span class="k">def</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">"""Fetch languages and regions from Bing-Web."""</span>
|
||
|
||
<span class="n">xpath_market_codes</span> <span class="o">=</span> <span class="s1">'//table[1]/tbody/tr/td[3]'</span>
|
||
<span class="c1"># xpath_country_codes = '//table[2]/tbody/tr/td[2]'</span>
|
||
<span class="n">xpath_language_codes</span> <span class="o">=</span> <span class="s1">'//table[3]/tbody/tr/td[2]'</span>
|
||
|
||
<span class="n">_fetch_traits</span><span class="p">(</span><span class="n">engine_traits</span><span class="p">,</span> <span class="n">bing_traits_url</span><span class="p">,</span> <span class="n">xpath_language_codes</span><span class="p">,</span> <span class="n">xpath_market_codes</span><span class="p">)</span></div>
|
||
|
||
|
||
<span class="k">def</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="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">xpath_language_codes</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">xpath_market_codes</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
|
||
<span class="c1"># pylint: disable=too-many-locals,import-outside-toplevel</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">searx.network</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="c1"># insert alias to map from a language (zh) to a language + script (zh_Hans)</span>
|
||
<span class="n">engine_traits</span><span class="o">.</span><span class="n">languages</span><span class="p">[</span><span class="s1">'zh'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'zh-hans'</span>
|
||
|
||
<span class="n">resp</span> <span class="o">=</span> <span class="n">get</span><span class="p">(</span><span class="n">url</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="c1"># type: ignore</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"ERROR: response from peertube is not OK."</span><span class="p">)</span>
|
||
|
||
<span class="n">dom</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="c1"># type: ignore</span>
|
||
|
||
<span class="n">map_lang</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'jp'</span><span class="p">:</span> <span class="s1">'ja'</span><span class="p">}</span>
|
||
<span class="k">for</span> <span class="n">td</span> <span class="ow">in</span> <span class="n">eval_xpath</span><span class="p">(</span><span class="n">dom</span><span class="p">,</span> <span class="n">xpath_language_codes</span><span class="p">):</span>
|
||
<span class="n">eng_lang</span> <span class="o">=</span> <span class="n">td</span><span class="o">.</span><span class="n">text</span>
|
||
|
||
<span class="k">if</span> <span class="n">eng_lang</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">'en-gb'</span><span class="p">,</span> <span class="s1">'pt-br'</span><span class="p">):</span>
|
||
<span class="c1"># language 'en' is already in the list and a language 'en-gb' can't</span>
|
||
<span class="c1"># be handled in SearXNG, same with pt-br which is covered by pt-pt.</span>
|
||
<span class="k">continue</span>
|
||
|
||
<span class="n">babel_lang</span> <span class="o">=</span> <span class="n">map_lang</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="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'-'</span><span class="p">,</span> <span class="s1">'_'</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">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_lang</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">"ERROR: language (</span><span class="si">%s</span><span class="s2">) is unknown by babel"</span> <span class="o">%</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">"CONFLICT: babel </span><span class="si">%s</span><span class="s2"> --> </span><span class="si">%s</span><span class="s2">, </span><span class="si">%s</span><span class="s2">"</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>
|
||
|
||
<span class="n">map_region</span> <span class="o">=</span> <span class="p">{</span>
|
||
<span class="s1">'en-ID'</span><span class="p">:</span> <span class="s1">'id_ID'</span><span class="p">,</span>
|
||
<span class="s1">'no-NO'</span><span class="p">:</span> <span class="s1">'nb_NO'</span><span class="p">,</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="k">for</span> <span class="n">td</span> <span class="ow">in</span> <span class="n">eval_xpath</span><span class="p">(</span><span class="n">dom</span><span class="p">,</span> <span class="n">xpath_market_codes</span><span class="p">):</span>
|
||
<span class="n">eng_region</span> <span class="o">=</span> <span class="n">td</span><span class="o">.</span><span class="n">text</span>
|
||
<span class="n">babel_region</span> <span class="o">=</span> <span class="n">map_region</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">eng_region</span><span class="p">,</span> <span class="n">eng_region</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'-'</span><span class="p">,</span> <span class="s1">'_'</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">eng_region</span> <span class="o">==</span> <span class="s1">'en-WW'</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="n">eng_region</span>
|
||
<span class="k">continue</span>
|
||
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">sxng_tag</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">babel_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">"ERROR: region (</span><span class="si">%s</span><span class="s2">) is unknown by babel"</span> <span class="o">%</span> <span class="p">(</span><span class="n">eng_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_region</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"CONFLICT: babel </span><span class="si">%s</span><span class="s2"> --> </span><span class="si">%s</span><span class="s2">, </span><span class="si">%s</span><span class="s2">"</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_region</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_region</span>
|
||
</pre></div>
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span id="sidebar-top"></span>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
|
||
|
||
<p class="logo"><a href="../../../index.html">
|
||
<img class="logo" src="../../../_static/searxng-wordmark.svg" alt="Logo"/>
|
||
</a></p>
|
||
|
||
|
||
<h3><a href="../../../index.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../../../user/index.html">User information</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../../../own-instance.html">Why use a private instance?</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../../../admin/index.html">Administrator documentation</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../../../dev/index.html">Developer documentation</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../../../utils/index.html">DevOps tooling box</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../../../src/index.html">Source-Code</a></li>
|
||
</ul>
|
||
|
||
<h3>Project Links</h3>
|
||
<ul>
|
||
<li><a href="https://github.com/searxng/searxng/tree/master">Source</a>
|
||
|
||
<li><a href="https://github.com/searxng/searxng/wiki">Wiki</a>
|
||
|
||
<li><a href="https://searx.space">Public instances</a>
|
||
|
||
<li><a href="https://github.com/searxng/searxng/issues">Issue Tracker</a>
|
||
</ul><h3>Navigation</h3>
|
||
<ul>
|
||
<li><a href="../../../index.html">Overview</a>
|
||
<ul>
|
||
<li><a href="../../index.html">Module code</a>
|
||
<ul>
|
||
<li><a href="../engines.html">searx.engines</a>
|
||
|
||
|
||
</ul>
|
||
</li></ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<div id="searchbox" style="display: none" role="search">
|
||
<h3 id="searchlabel">Quick search</h3>
|
||
<div class="searchformwrapper">
|
||
<form class="search" action="../../../search.html" method="get">
|
||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright SearXNG team.
|
||
</div>
|
||
<script src="../../../_static/version_warning_offset.js"></script>
|
||
|
||
</body>
|
||
</html> |