We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Yahoo: Result titles getting mixed together
**Version of SearXNG, commit number if you are using on master branch and stipulate if you forked SearXNG**
2024.4.19+0f70e4d30

**How did you install SearXNG?**
searxng-docker

**What happened?**
I've noticed that result titles are getting mixed up together when they shouldn't.

**How To Reproduce**
Search `!yh gba custom bios`.

**Expected behavior**
Result titles not being mixed together.

**Screenshots & Logs**
Highlighted in red are the parts where the title is wrong.
![Screenshott](https://github.com/searxng/searxng/assets/129474298/4e3dc27b-3e97-438b-a349-3e6ce317cab9)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `searx/engines/yahoo.py`
Content:
```
1 # SPDX-License-Identifier: AGPL-3.0-or-later
2 """Yahoo Search (Web)
3 
4 Languages are supported by mapping the language to a domain.  If domain is not
5 found in :py:obj:`lang2domain` URL ``<lang>.search.yahoo.com`` is used.
6 
7 """
8 
9 from urllib.parse import (
10     unquote,
11     urlencode,
12 )
13 from lxml import html
14 
15 from searx.utils import (
16     eval_xpath_getindex,
17     eval_xpath_list,
18     extract_text,
19 )
20 from searx.enginelib.traits import EngineTraits
21 
22 traits: EngineTraits
23 
24 # about
25 about = {
26     "website": 'https://search.yahoo.com/',
27     "wikidata_id": None,
28     "official_api_documentation": 'https://developer.yahoo.com/api/',
29     "use_official_api": False,
30     "require_api_key": False,
31     "results": 'HTML',
32 }
33 
34 # engine dependent config
35 categories = ['general', 'web']
36 paging = True
37 time_range_support = True
38 # send_accept_language_header = True
39 
40 time_range_dict = {
41     'day': ('1d', 'd'),
42     'week': ('1w', 'w'),
43     'month': ('1m', 'm'),
44 }
45 
46 lang2domain = {
47     'zh_chs': 'hk.search.yahoo.com',
48     'zh_cht': 'tw.search.yahoo.com',
49     'any': 'search.yahoo.com',
50     'en': 'search.yahoo.com',
51     'bg': 'search.yahoo.com',
52     'cs': 'search.yahoo.com',
53     'da': 'search.yahoo.com',
54     'el': 'search.yahoo.com',
55     'et': 'search.yahoo.com',
56     'he': 'search.yahoo.com',
57     'hr': 'search.yahoo.com',
58     'ja': 'search.yahoo.com',
59     'ko': 'search.yahoo.com',
60     'sk': 'search.yahoo.com',
61     'sl': 'search.yahoo.com',
62 }
63 """Map language to domain"""
64 
65 locale_aliases = {
66     'zh': 'zh_Hans',
67     'zh-HK': 'zh_Hans',
68     'zh-CN': 'zh_Hans',  # dead since 2015 / routed to hk.search.yahoo.com
69     'zh-TW': 'zh_Hant',
70 }
71 
72 
73 def request(query, params):
74     """build request"""
75 
76     lang = locale_aliases.get(params['language'], None)
77     if not lang:
78         lang = params['language'].split('-')[0]
79     lang = traits.get_language(lang, traits.all_locale)
80 
81     offset = (params['pageno'] - 1) * 7 + 1
82     age, btf = time_range_dict.get(params['time_range'], ('', ''))
83 
84     args = urlencode(
85         {
86             'p': query,
87             'ei': 'UTF-8',
88             'fl': 1,
89             'vl': 'lang_' + lang,
90             'btf': btf,
91             'fr2': 'time',
92             'age': age,
93             'b': offset,
94             'xargs': 0,
95         }
96     )
97 
98     domain = lang2domain.get(lang, '%s.search.yahoo.com' % lang)
99     params['url'] = 'https://%s/search?%s' % (domain, args)
100     return params
101 
102 
103 def parse_url(url_string):
104     """remove yahoo-specific tracking-url"""
105 
106     endings = ['/RS', '/RK']
107     endpositions = []
108     start = url_string.find('http', url_string.find('/RU=') + 1)
109 
110     for ending in endings:
111         endpos = url_string.rfind(ending)
112         if endpos > -1:
113             endpositions.append(endpos)
114 
115     if start == 0 or len(endpositions) == 0:
116         return url_string
117 
118     end = min(endpositions)
119     return unquote(url_string[start:end])
120 
121 
122 def response(resp):
123     """parse response"""
124 
125     results = []
126     dom = html.fromstring(resp.text)
127 
128     # parse results
129     for result in eval_xpath_list(dom, '//div[contains(@class,"algo-sr")]'):
130         url = eval_xpath_getindex(result, './/h3/a/@href', 0, default=None)
131         if url is None:
132             continue
133         url = parse_url(url)
134 
135         title = extract_text(result.xpath('.//h3//a/@aria-label'))
136         content = eval_xpath_getindex(result, './/div[contains(@class, "compText")]', 0, default='')
137         content = extract_text(content, allow_none=True)
138 
139         # append result
140         results.append({'url': url, 'title': title, 'content': content})
141 
142     for suggestion in eval_xpath_list(dom, '//div[contains(@class, "AlsoTry")]//table//a'):
143         # append suggestion
144         results.append({'suggestion': extract_text(suggestion)})
145 
146     return results
147 
148 
149 def fetch_traits(engine_traits: EngineTraits):
150     """Fetch languages from yahoo"""
151 
152     # pylint: disable=import-outside-toplevel
153     import babel
154     from searx import network
155     from searx.locales import language_tag
156 
157     engine_traits.all_locale = 'any'
158 
159     resp = network.get('https://search.yahoo.com/preferences/languages')
160     if not resp.ok:
161         print("ERROR: response from yahoo is not OK.")
162 
163     dom = html.fromstring(resp.text)
164     offset = len('lang_')
165 
166     eng2sxng = {'zh_chs': 'zh_Hans', 'zh_cht': 'zh_Hant'}
167 
168     for val in eval_xpath_list(dom, '//div[contains(@class, "lang-item")]/input/@value'):
169         eng_tag = val[offset:]
170 
171         try:
172             sxng_tag = language_tag(babel.Locale.parse(eng2sxng.get(eng_tag, eng_tag)))
173         except babel.UnknownLocaleError:
174             print('ERROR: unknown language --> %s' % eng_tag)
175             continue
176 
177         conflict = engine_traits.languages.get(sxng_tag)
178         if conflict:
179             if conflict != eng_tag:
180                 print("CONFLICT: babel %s --> %s, %s" % (sxng_tag, conflict, eng_tag))
181             continue
182         engine_traits.languages[sxng_tag] = eng_tag
183
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/searx/engines/yahoo.py b/searx/engines/yahoo.py
--- a/searx/engines/yahoo.py
+++ b/searx/engines/yahoo.py
@@ -132,7 +132,8 @@
             continue
         url = parse_url(url)
 
-        title = extract_text(result.xpath('.//h3//a/@aria-label'))
+        title = eval_xpath_getindex(result, './/h3//a/@aria-label', 0, default='')
+        title = extract_text(title)
         content = eval_xpath_getindex(result, './/div[contains(@class, "compText")]', 0, default='')
         content = extract_text(content, allow_none=True)

{"golden_diff": "diff --git a/searx/engines/yahoo.py b/searx/engines/yahoo.py\n--- a/searx/engines/yahoo.py\n+++ b/searx/engines/yahoo.py\n@@ -132,7 +132,8 @@\n             continue\n         url = parse_url(url)\n \n-        title = extract_text(result.xpath('.//h3//a/@aria-label'))\n+        title = eval_xpath_getindex(result, './/h3//a/@aria-label', 0, default='')\n+        title = extract_text(title)\n         content = eval_xpath_getindex(result, './/div[contains(@class, \"compText\")]', 0, default='')\n         content = extract_text(content, allow_none=True)\n", "issue": "Yahoo: Result titles getting mixed together\n**Version of SearXNG, commit number if you are using on master branch and stipulate if you forked SearXNG**\r\n2024.4.19+0f70e4d30\r\n\r\n**How did you install SearXNG?**\r\nsearxng-docker\r\n\r\n**What happened?**\r\nI've noticed that result titles are getting mixed up together when they shouldn't.\r\n\r\n**How To Reproduce**\r\nSearch `!yh gba custom bios`.\r\n\r\n**Expected behavior**\r\nResult titles not being mixed together.\r\n\r\n**Screenshots & Logs**\r\nHighlighted in red are the parts where the title is wrong.\r\n![Screenshott](https://github.com/searxng/searxng/assets/129474298/4e3dc27b-3e97-438b-a349-3e6ce317cab9)\r\n\n", "before_files": [{"content": "# SPDX-License-Identifier: AGPL-3.0-or-later\n\"\"\"Yahoo Search (Web)\n\nLanguages are supported by mapping the language to a domain.  If domain is not\nfound in :py:obj:`lang2domain` URL ``<lang>.search.yahoo.com`` is used.\n\n\"\"\"\n\nfrom urllib.parse import (\n    unquote,\n    urlencode,\n)\nfrom lxml import html\n\nfrom searx.utils import (\n    eval_xpath_getindex,\n    eval_xpath_list,\n    extract_text,\n)\nfrom searx.enginelib.traits import EngineTraits\n\ntraits: EngineTraits\n\n# about\nabout = {\n    \"website\": 'https://search.yahoo.com/',\n    \"wikidata_id\": None,\n    \"official_api_documentation\": 'https://developer.yahoo.com/api/',\n    \"use_official_api\": False,\n    \"require_api_key\": False,\n    \"results\": 'HTML',\n}\n\n# engine dependent config\ncategories = ['general', 'web']\npaging = True\ntime_range_support = True\n# send_accept_language_header = True\n\ntime_range_dict = {\n    'day': ('1d', 'd'),\n    'week': ('1w', 'w'),\n    'month': ('1m', 'm'),\n}\n\nlang2domain = {\n    'zh_chs': 'hk.search.yahoo.com',\n    'zh_cht': 'tw.search.yahoo.com',\n    'any': 'search.yahoo.com',\n    'en': 'search.yahoo.com',\n    'bg': 'search.yahoo.com',\n    'cs': 'search.yahoo.com',\n    'da': 'search.yahoo.com',\n    'el': 'search.yahoo.com',\n    'et': 'search.yahoo.com',\n    'he': 'search.yahoo.com',\n    'hr': 'search.yahoo.com',\n    'ja': 'search.yahoo.com',\n    'ko': 'search.yahoo.com',\n    'sk': 'search.yahoo.com',\n    'sl': 'search.yahoo.com',\n}\n\"\"\"Map language to domain\"\"\"\n\nlocale_aliases = {\n    'zh': 'zh_Hans',\n    'zh-HK': 'zh_Hans',\n    'zh-CN': 'zh_Hans',  # dead since 2015 / routed to hk.search.yahoo.com\n    'zh-TW': 'zh_Hant',\n}\n\n\ndef request(query, params):\n    \"\"\"build request\"\"\"\n\n    lang = locale_aliases.get(params['language'], None)\n    if not lang:\n        lang = params['language'].split('-')[0]\n    lang = traits.get_language(lang, traits.all_locale)\n\n    offset = (params['pageno'] - 1) * 7 + 1\n    age, btf = time_range_dict.get(params['time_range'], ('', ''))\n\n    args = urlencode(\n        {\n            'p': query,\n            'ei': 'UTF-8',\n            'fl': 1,\n            'vl': 'lang_' + lang,\n            'btf': btf,\n            'fr2': 'time',\n            'age': age,\n            'b': offset,\n            'xargs': 0,\n        }\n    )\n\n    domain = lang2domain.get(lang, '%s.search.yahoo.com' % lang)\n    params['url'] = 'https://%s/search?%s' % (domain, args)\n    return params\n\n\ndef parse_url(url_string):\n    \"\"\"remove yahoo-specific tracking-url\"\"\"\n\n    endings = ['/RS', '/RK']\n    endpositions = []\n    start = url_string.find('http', url_string.find('/RU=') + 1)\n\n    for ending in endings:\n        endpos = url_string.rfind(ending)\n        if endpos > -1:\n            endpositions.append(endpos)\n\n    if start == 0 or len(endpositions) == 0:\n        return url_string\n\n    end = min(endpositions)\n    return unquote(url_string[start:end])\n\n\ndef response(resp):\n    \"\"\"parse response\"\"\"\n\n    results = []\n    dom = html.fromstring(resp.text)\n\n    # parse results\n    for result in eval_xpath_list(dom, '//div[contains(@class,\"algo-sr\")]'):\n        url = eval_xpath_getindex(result, './/h3/a/@href', 0, default=None)\n        if url is None:\n            continue\n        url = parse_url(url)\n\n        title = extract_text(result.xpath('.//h3//a/@aria-label'))\n        content = eval_xpath_getindex(result, './/div[contains(@class, \"compText\")]', 0, default='')\n        content = extract_text(content, allow_none=True)\n\n        # append result\n        results.append({'url': url, 'title': title, 'content': content})\n\n    for suggestion in eval_xpath_list(dom, '//div[contains(@class, \"AlsoTry\")]//table//a'):\n        # append suggestion\n        results.append({'suggestion': extract_text(suggestion)})\n\n    return results\n\n\ndef fetch_traits(engine_traits: EngineTraits):\n    \"\"\"Fetch languages from yahoo\"\"\"\n\n    # pylint: disable=import-outside-toplevel\n    import babel\n    from searx import network\n    from searx.locales import language_tag\n\n    engine_traits.all_locale = 'any'\n\n    resp = network.get('https://search.yahoo.com/preferences/languages')\n    if not resp.ok:\n        print(\"ERROR: response from yahoo is not OK.\")\n\n    dom = html.fromstring(resp.text)\n    offset = len('lang_')\n\n    eng2sxng = {'zh_chs': 'zh_Hans', 'zh_cht': 'zh_Hant'}\n\n    for val in eval_xpath_list(dom, '//div[contains(@class, \"lang-item\")]/input/@value'):\n        eng_tag = val[offset:]\n\n        try:\n            sxng_tag = language_tag(babel.Locale.parse(eng2sxng.get(eng_tag, eng_tag)))\n        except babel.UnknownLocaleError:\n            print('ERROR: unknown language --> %s' % eng_tag)\n            continue\n\n        conflict = engine_traits.languages.get(sxng_tag)\n        if conflict:\n            if conflict != eng_tag:\n                print(\"CONFLICT: babel %s --> %s, %s\" % (sxng_tag, conflict, eng_tag))\n            continue\n        engine_traits.languages[sxng_tag] = eng_tag\n", "path": "searx/engines/yahoo.py"}], "after_files": [{"content": "# SPDX-License-Identifier: AGPL-3.0-or-later\n\"\"\"Yahoo Search (Web)\n\nLanguages are supported by mapping the language to a domain.  If domain is not\nfound in :py:obj:`lang2domain` URL ``<lang>.search.yahoo.com`` is used.\n\n\"\"\"\n\nfrom urllib.parse import (\n    unquote,\n    urlencode,\n)\nfrom lxml import html\n\nfrom searx.utils import (\n    eval_xpath_getindex,\n    eval_xpath_list,\n    extract_text,\n)\nfrom searx.enginelib.traits import EngineTraits\n\ntraits: EngineTraits\n\n# about\nabout = {\n    \"website\": 'https://search.yahoo.com/',\n    \"wikidata_id\": None,\n    \"official_api_documentation\": 'https://developer.yahoo.com/api/',\n    \"use_official_api\": False,\n    \"require_api_key\": False,\n    \"results\": 'HTML',\n}\n\n# engine dependent config\ncategories = ['general', 'web']\npaging = True\ntime_range_support = True\n# send_accept_language_header = True\n\ntime_range_dict = {\n    'day': ('1d', 'd'),\n    'week': ('1w', 'w'),\n    'month': ('1m', 'm'),\n}\n\nlang2domain = {\n    'zh_chs': 'hk.search.yahoo.com',\n    'zh_cht': 'tw.search.yahoo.com',\n    'any': 'search.yahoo.com',\n    'en': 'search.yahoo.com',\n    'bg': 'search.yahoo.com',\n    'cs': 'search.yahoo.com',\n    'da': 'search.yahoo.com',\n    'el': 'search.yahoo.com',\n    'et': 'search.yahoo.com',\n    'he': 'search.yahoo.com',\n    'hr': 'search.yahoo.com',\n    'ja': 'search.yahoo.com',\n    'ko': 'search.yahoo.com',\n    'sk': 'search.yahoo.com',\n    'sl': 'search.yahoo.com',\n}\n\"\"\"Map language to domain\"\"\"\n\nlocale_aliases = {\n    'zh': 'zh_Hans',\n    'zh-HK': 'zh_Hans',\n    'zh-CN': 'zh_Hans',  # dead since 2015 / routed to hk.search.yahoo.com\n    'zh-TW': 'zh_Hant',\n}\n\n\ndef request(query, params):\n    \"\"\"build request\"\"\"\n\n    lang = locale_aliases.get(params['language'], None)\n    if not lang:\n        lang = params['language'].split('-')[0]\n    lang = traits.get_language(lang, traits.all_locale)\n\n    offset = (params['pageno'] - 1) * 7 + 1\n    age, btf = time_range_dict.get(params['time_range'], ('', ''))\n\n    args = urlencode(\n        {\n            'p': query,\n            'ei': 'UTF-8',\n            'fl': 1,\n            'vl': 'lang_' + lang,\n            'btf': btf,\n            'fr2': 'time',\n            'age': age,\n            'b': offset,\n            'xargs': 0,\n        }\n    )\n\n    domain = lang2domain.get(lang, '%s.search.yahoo.com' % lang)\n    params['url'] = 'https://%s/search?%s' % (domain, args)\n    return params\n\n\ndef parse_url(url_string):\n    \"\"\"remove yahoo-specific tracking-url\"\"\"\n\n    endings = ['/RS', '/RK']\n    endpositions = []\n    start = url_string.find('http', url_string.find('/RU=') + 1)\n\n    for ending in endings:\n        endpos = url_string.rfind(ending)\n        if endpos > -1:\n            endpositions.append(endpos)\n\n    if start == 0 or len(endpositions) == 0:\n        return url_string\n\n    end = min(endpositions)\n    return unquote(url_string[start:end])\n\n\ndef response(resp):\n    \"\"\"parse response\"\"\"\n\n    results = []\n    dom = html.fromstring(resp.text)\n\n    # parse results\n    for result in eval_xpath_list(dom, '//div[contains(@class,\"algo-sr\")]'):\n        url = eval_xpath_getindex(result, './/h3/a/@href', 0, default=None)\n        if url is None:\n            continue\n        url = parse_url(url)\n\n        title = eval_xpath_getindex(result, './/h3//a/@aria-label', 0, default='')\n        title = extract_text(title)\n        content = eval_xpath_getindex(result, './/div[contains(@class, \"compText\")]', 0, default='')\n        content = extract_text(content, allow_none=True)\n\n        # append result\n        results.append({'url': url, 'title': title, 'content': content})\n\n    for suggestion in eval_xpath_list(dom, '//div[contains(@class, \"AlsoTry\")]//table//a'):\n        # append suggestion\n        results.append({'suggestion': extract_text(suggestion)})\n\n    return results\n\n\ndef fetch_traits(engine_traits: EngineTraits):\n    \"\"\"Fetch languages from yahoo\"\"\"\n\n    # pylint: disable=import-outside-toplevel\n    import babel\n    from searx import network\n    from searx.locales import language_tag\n\n    engine_traits.all_locale = 'any'\n\n    resp = network.get('https://search.yahoo.com/preferences/languages')\n    if not resp.ok:\n        print(\"ERROR: response from yahoo is not OK.\")\n\n    dom = html.fromstring(resp.text)\n    offset = len('lang_')\n\n    eng2sxng = {'zh_chs': 'zh_Hans', 'zh_cht': 'zh_Hant'}\n\n    for val in eval_xpath_list(dom, '//div[contains(@class, \"lang-item\")]/input/@value'):\n        eng_tag = val[offset:]\n\n        try:\n            sxng_tag = language_tag(babel.Locale.parse(eng2sxng.get(eng_tag, eng_tag)))\n        except babel.UnknownLocaleError:\n            print('ERROR: unknown language --> %s' % eng_tag)\n            continue\n\n        conflict = engine_traits.languages.get(sxng_tag)\n        if conflict:\n            if conflict != eng_tag:\n                print(\"CONFLICT: babel %s --> %s, %s\" % (sxng_tag, conflict, eng_tag))\n            continue\n        engine_traits.languages[sxng_tag] = eng_tag\n", "path": "searx/engines/yahoo.py"}]}