We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Startpage not returning any results
**Version:**
I tried it with `v0.17.0` and `820b468bfe96f693d60ce06f1e78af51f00deefc`

**Installation-Method:** 
Manually according to wiki (with uwsgi)

**What happened?**
The startpage engine is not returning any results

**How To Reproduce**
Execute a query with `!sp test`

**Expected behavior**
Results from startpage

**Additional context**
I added some log lines to the startpage engine file and it seems like it gets some
response back from startpage. 

Maybe startpage changed their formatting? 
I didn't have a closer look on the way results are parsed yet. 

--- 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/startpage.py`
Content:
```
1 #  Startpage (Web)
2 #
3 # @website     https://startpage.com
4 # @provide-api no (nothing found)
5 #
6 # @using-api   no
7 # @results     HTML
8 # @stable      no (HTML can change)
9 # @parse       url, title, content
10 #
11 # @todo        paging
12 
13 from lxml import html
14 from dateutil import parser
15 from datetime import datetime, timedelta
16 import re
17 from unicodedata import normalize, combining
18 from babel import Locale
19 from babel.localedata import locale_identifiers
20 from searx.utils import extract_text, eval_xpath, match_language
21 
22 # engine dependent config
23 categories = ['general']
24 # there is a mechanism to block "bot" search
25 # (probably the parameter qid), require
26 # storing of qid's between mulitble search-calls
27 
28 paging = True
29 language_support = True
30 supported_languages_url = 'https://www.startpage.com/do/settings'
31 
32 # search-url
33 base_url = 'https://startpage.com/'
34 search_url = base_url + 'do/search'
35 
36 # specific xpath variables
37 # ads xpath //div[@id="results"]/div[@id="sponsored"]//div[@class="result"]
38 # not ads: div[@class="result"] are the direct childs of div[@id="results"]
39 results_xpath = '//div[@class="w-gl__result"]'
40 link_xpath = './/a[@class="w-gl__result-title"]'
41 content_xpath = './/p[@class="w-gl__description"]'
42 
43 
44 # do search-request
45 def request(query, params):
46 
47     params['url'] = search_url
48     params['method'] = 'POST'
49     params['data'] = {
50         'query': query,
51         'page': params['pageno'],
52         'cat': 'web',
53         'cmd': 'process_search',
54         'engine0': 'v1all',
55     }
56 
57     # set language if specified
58     if params['language'] != 'all':
59         lang_code = match_language(params['language'], supported_languages, fallback=None)
60         if lang_code:
61             language_name = supported_languages[lang_code]['alias']
62             params['data']['language'] = language_name
63             params['data']['lui'] = language_name
64 
65     return params
66 
67 
68 # get response from search-request
69 def response(resp):
70     results = []
71 
72     dom = html.fromstring(resp.text)
73 
74     # parse results
75     for result in eval_xpath(dom, results_xpath):
76         links = eval_xpath(result, link_xpath)
77         if not links:
78             continue
79         link = links[0]
80         url = link.attrib.get('href')
81 
82         # block google-ad url's
83         if re.match(r"^http(s|)://(www\.)?google\.[a-z]+/aclk.*$", url):
84             continue
85 
86         # block startpage search url's
87         if re.match(r"^http(s|)://(www\.)?startpage\.com/do/search\?.*$", url):
88             continue
89 
90         title = extract_text(link)
91 
92         if eval_xpath(result, content_xpath):
93             content = extract_text(eval_xpath(result, content_xpath))
94         else:
95             content = ''
96 
97         published_date = None
98 
99         # check if search result starts with something like: "2 Sep 2014 ... "
100         if re.match(r"^([1-9]|[1-2][0-9]|3[0-1]) [A-Z][a-z]{2} [0-9]{4} \.\.\. ", content):
101             date_pos = content.find('...') + 4
102             date_string = content[0:date_pos - 5]
103             # fix content string
104             content = content[date_pos:]
105 
106             try:
107                 published_date = parser.parse(date_string, dayfirst=True)
108             except ValueError:
109                 pass
110 
111         # check if search result starts with something like: "5 days ago ... "
112         elif re.match(r"^[0-9]+ days? ago \.\.\. ", content):
113             date_pos = content.find('...') + 4
114             date_string = content[0:date_pos - 5]
115 
116             # calculate datetime
117             published_date = datetime.now() - timedelta(days=int(re.match(r'\d+', date_string).group()))
118 
119             # fix content string
120             content = content[date_pos:]
121 
122         if published_date:
123             # append result
124             results.append({'url': url,
125                             'title': title,
126                             'content': content,
127                             'publishedDate': published_date})
128         else:
129             # append result
130             results.append({'url': url,
131                             'title': title,
132                             'content': content})
133 
134     # return results
135     return results
136 
137 
138 # get supported languages from their site
139 def _fetch_supported_languages(resp):
140     # startpage's language selector is a mess
141     # each option has a displayed name and a value, either of which may represent the language name
142     # in the native script, the language name in English, an English transliteration of the native name,
143     # the English name of the writing script used by the language, or occasionally something else entirely.
144 
145     # this cases are so special they need to be hardcoded, a couple of them are mispellings
146     language_names = {
147         'english_uk': 'en-GB',
148         'fantizhengwen': ['zh-TW', 'zh-HK'],
149         'hangul': 'ko',
150         'malayam': 'ml',
151         'norsk': 'nb',
152         'sinhalese': 'si',
153         'sudanese': 'su'
154     }
155 
156     # get the English name of every language known by babel
157     language_names.update({name.lower(): lang_code for lang_code, name in Locale('en')._data['languages'].items()})
158 
159     # get the native name of every language known by babel
160     for lang_code in filter(lambda lang_code: lang_code.find('_') == -1, locale_identifiers()):
161         native_name = Locale(lang_code).get_language_name().lower()
162         # add native name exactly as it is
163         language_names[native_name] = lang_code
164 
165         # add "normalized" language name (i.e. français becomes francais and español becomes espanol)
166         unaccented_name = ''.join(filter(lambda c: not combining(c), normalize('NFKD', native_name)))
167         if len(unaccented_name) == len(unaccented_name.encode()):
168             # add only if result is ascii (otherwise "normalization" didn't work)
169             language_names[unaccented_name] = lang_code
170 
171     dom = html.fromstring(resp.text)
172     sp_lang_names = []
173     for option in dom.xpath('//form[@id="settings-form"]//select[@name="language"]/option'):
174         sp_lang_names.append((option.get('value'), extract_text(option).lower()))
175 
176     supported_languages = {}
177     for sp_option_value, sp_option_text in sp_lang_names:
178         lang_code = language_names.get(sp_option_value) or language_names.get(sp_option_text)
179         if isinstance(lang_code, str):
180             supported_languages[lang_code] = {'alias': sp_option_value}
181         elif isinstance(lang_code, list):
182             for lc in lang_code:
183                 supported_languages[lc] = {'alias': sp_option_value}
184         else:
185             print('Unknown language option in Startpage: {} ({})'.format(sp_option_value, sp_option_text))
186 
187     return supported_languages
188
```
--- 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/startpage.py b/searx/engines/startpage.py
--- a/searx/engines/startpage.py
+++ b/searx/engines/startpage.py
@@ -36,8 +36,8 @@
 # specific xpath variables
 # ads xpath //div[@id="results"]/div[@id="sponsored"]//div[@class="result"]
 # not ads: div[@class="result"] are the direct childs of div[@id="results"]
-results_xpath = '//div[@class="w-gl__result"]'
-link_xpath = './/a[@class="w-gl__result-title"]'
+results_xpath = '//div[@class="w-gl__result__main"]'
+link_xpath = './/a[@class="w-gl__result-url result-link"]'
 content_xpath = './/p[@class="w-gl__description"]'

{"golden_diff": "diff --git a/searx/engines/startpage.py b/searx/engines/startpage.py\n--- a/searx/engines/startpage.py\n+++ b/searx/engines/startpage.py\n@@ -36,8 +36,8 @@\n # specific xpath variables\n # ads xpath //div[@id=\"results\"]/div[@id=\"sponsored\"]//div[@class=\"result\"]\n # not ads: div[@class=\"result\"] are the direct childs of div[@id=\"results\"]\n-results_xpath = '//div[@class=\"w-gl__result\"]'\n-link_xpath = './/a[@class=\"w-gl__result-title\"]'\n+results_xpath = '//div[@class=\"w-gl__result__main\"]'\n+link_xpath = './/a[@class=\"w-gl__result-url result-link\"]'\n content_xpath = './/p[@class=\"w-gl__description\"]'\n", "issue": "Startpage not returning any results\n**Version:**\r\nI tried it with `v0.17.0` and `820b468bfe96f693d60ce06f1e78af51f00deefc`\r\n\r\n**Installation-Method:** \r\nManually according to wiki (with uwsgi)\r\n\r\n**What happened?**\r\nThe startpage engine is not returning any results\r\n\r\n**How To Reproduce**\r\nExecute a query with `!sp test`\r\n\r\n**Expected behavior**\r\nResults from startpage\r\n\r\n**Additional context**\r\nI added some log lines to the startpage engine file and it seems like it gets some\r\nresponse back from startpage. \r\n\r\nMaybe startpage changed their formatting? \r\nI didn't have a closer look on the way results are parsed yet. \n", "before_files": [{"content": "#  Startpage (Web)\n#\n# @website     https://startpage.com\n# @provide-api no (nothing found)\n#\n# @using-api   no\n# @results     HTML\n# @stable      no (HTML can change)\n# @parse       url, title, content\n#\n# @todo        paging\n\nfrom lxml import html\nfrom dateutil import parser\nfrom datetime import datetime, timedelta\nimport re\nfrom unicodedata import normalize, combining\nfrom babel import Locale\nfrom babel.localedata import locale_identifiers\nfrom searx.utils import extract_text, eval_xpath, match_language\n\n# engine dependent config\ncategories = ['general']\n# there is a mechanism to block \"bot\" search\n# (probably the parameter qid), require\n# storing of qid's between mulitble search-calls\n\npaging = True\nlanguage_support = True\nsupported_languages_url = 'https://www.startpage.com/do/settings'\n\n# search-url\nbase_url = 'https://startpage.com/'\nsearch_url = base_url + 'do/search'\n\n# specific xpath variables\n# ads xpath //div[@id=\"results\"]/div[@id=\"sponsored\"]//div[@class=\"result\"]\n# not ads: div[@class=\"result\"] are the direct childs of div[@id=\"results\"]\nresults_xpath = '//div[@class=\"w-gl__result\"]'\nlink_xpath = './/a[@class=\"w-gl__result-title\"]'\ncontent_xpath = './/p[@class=\"w-gl__description\"]'\n\n\n# do search-request\ndef request(query, params):\n\n    params['url'] = search_url\n    params['method'] = 'POST'\n    params['data'] = {\n        'query': query,\n        'page': params['pageno'],\n        'cat': 'web',\n        'cmd': 'process_search',\n        'engine0': 'v1all',\n    }\n\n    # set language if specified\n    if params['language'] != 'all':\n        lang_code = match_language(params['language'], supported_languages, fallback=None)\n        if lang_code:\n            language_name = supported_languages[lang_code]['alias']\n            params['data']['language'] = language_name\n            params['data']['lui'] = language_name\n\n    return params\n\n\n# get response from search-request\ndef response(resp):\n    results = []\n\n    dom = html.fromstring(resp.text)\n\n    # parse results\n    for result in eval_xpath(dom, results_xpath):\n        links = eval_xpath(result, link_xpath)\n        if not links:\n            continue\n        link = links[0]\n        url = link.attrib.get('href')\n\n        # block google-ad url's\n        if re.match(r\"^http(s|)://(www\\.)?google\\.[a-z]+/aclk.*$\", url):\n            continue\n\n        # block startpage search url's\n        if re.match(r\"^http(s|)://(www\\.)?startpage\\.com/do/search\\?.*$\", url):\n            continue\n\n        title = extract_text(link)\n\n        if eval_xpath(result, content_xpath):\n            content = extract_text(eval_xpath(result, content_xpath))\n        else:\n            content = ''\n\n        published_date = None\n\n        # check if search result starts with something like: \"2 Sep 2014 ... \"\n        if re.match(r\"^([1-9]|[1-2][0-9]|3[0-1]) [A-Z][a-z]{2} [0-9]{4} \\.\\.\\. \", content):\n            date_pos = content.find('...') + 4\n            date_string = content[0:date_pos - 5]\n            # fix content string\n            content = content[date_pos:]\n\n            try:\n                published_date = parser.parse(date_string, dayfirst=True)\n            except ValueError:\n                pass\n\n        # check if search result starts with something like: \"5 days ago ... \"\n        elif re.match(r\"^[0-9]+ days? ago \\.\\.\\. \", content):\n            date_pos = content.find('...') + 4\n            date_string = content[0:date_pos - 5]\n\n            # calculate datetime\n            published_date = datetime.now() - timedelta(days=int(re.match(r'\\d+', date_string).group()))\n\n            # fix content string\n            content = content[date_pos:]\n\n        if published_date:\n            # append result\n            results.append({'url': url,\n                            'title': title,\n                            'content': content,\n                            'publishedDate': published_date})\n        else:\n            # append result\n            results.append({'url': url,\n                            'title': title,\n                            'content': content})\n\n    # return results\n    return results\n\n\n# get supported languages from their site\ndef _fetch_supported_languages(resp):\n    # startpage's language selector is a mess\n    # each option has a displayed name and a value, either of which may represent the language name\n    # in the native script, the language name in English, an English transliteration of the native name,\n    # the English name of the writing script used by the language, or occasionally something else entirely.\n\n    # this cases are so special they need to be hardcoded, a couple of them are mispellings\n    language_names = {\n        'english_uk': 'en-GB',\n        'fantizhengwen': ['zh-TW', 'zh-HK'],\n        'hangul': 'ko',\n        'malayam': 'ml',\n        'norsk': 'nb',\n        'sinhalese': 'si',\n        'sudanese': 'su'\n    }\n\n    # get the English name of every language known by babel\n    language_names.update({name.lower(): lang_code for lang_code, name in Locale('en')._data['languages'].items()})\n\n    # get the native name of every language known by babel\n    for lang_code in filter(lambda lang_code: lang_code.find('_') == -1, locale_identifiers()):\n        native_name = Locale(lang_code).get_language_name().lower()\n        # add native name exactly as it is\n        language_names[native_name] = lang_code\n\n        # add \"normalized\" language name (i.e. fran\u00e7ais becomes francais and espa\u00f1ol becomes espanol)\n        unaccented_name = ''.join(filter(lambda c: not combining(c), normalize('NFKD', native_name)))\n        if len(unaccented_name) == len(unaccented_name.encode()):\n            # add only if result is ascii (otherwise \"normalization\" didn't work)\n            language_names[unaccented_name] = lang_code\n\n    dom = html.fromstring(resp.text)\n    sp_lang_names = []\n    for option in dom.xpath('//form[@id=\"settings-form\"]//select[@name=\"language\"]/option'):\n        sp_lang_names.append((option.get('value'), extract_text(option).lower()))\n\n    supported_languages = {}\n    for sp_option_value, sp_option_text in sp_lang_names:\n        lang_code = language_names.get(sp_option_value) or language_names.get(sp_option_text)\n        if isinstance(lang_code, str):\n            supported_languages[lang_code] = {'alias': sp_option_value}\n        elif isinstance(lang_code, list):\n            for lc in lang_code:\n                supported_languages[lc] = {'alias': sp_option_value}\n        else:\n            print('Unknown language option in Startpage: {} ({})'.format(sp_option_value, sp_option_text))\n\n    return supported_languages\n", "path": "searx/engines/startpage.py"}], "after_files": [{"content": "#  Startpage (Web)\n#\n# @website     https://startpage.com\n# @provide-api no (nothing found)\n#\n# @using-api   no\n# @results     HTML\n# @stable      no (HTML can change)\n# @parse       url, title, content\n#\n# @todo        paging\n\nfrom lxml import html\nfrom dateutil import parser\nfrom datetime import datetime, timedelta\nimport re\nfrom unicodedata import normalize, combining\nfrom babel import Locale\nfrom babel.localedata import locale_identifiers\nfrom searx.utils import extract_text, eval_xpath, match_language\n\n# engine dependent config\ncategories = ['general']\n# there is a mechanism to block \"bot\" search\n# (probably the parameter qid), require\n# storing of qid's between mulitble search-calls\n\npaging = True\nlanguage_support = True\nsupported_languages_url = 'https://www.startpage.com/do/settings'\n\n# search-url\nbase_url = 'https://startpage.com/'\nsearch_url = base_url + 'do/search'\n\n# specific xpath variables\n# ads xpath //div[@id=\"results\"]/div[@id=\"sponsored\"]//div[@class=\"result\"]\n# not ads: div[@class=\"result\"] are the direct childs of div[@id=\"results\"]\nresults_xpath = '//div[@class=\"w-gl__result__main\"]'\nlink_xpath = './/a[@class=\"w-gl__result-url result-link\"]'\ncontent_xpath = './/p[@class=\"w-gl__description\"]'\n\n\n# do search-request\ndef request(query, params):\n\n    params['url'] = search_url\n    params['method'] = 'POST'\n    params['data'] = {\n        'query': query,\n        'page': params['pageno'],\n        'cat': 'web',\n        'cmd': 'process_search',\n        'engine0': 'v1all',\n    }\n\n    # set language if specified\n    if params['language'] != 'all':\n        lang_code = match_language(params['language'], supported_languages, fallback=None)\n        if lang_code:\n            language_name = supported_languages[lang_code]['alias']\n            params['data']['language'] = language_name\n            params['data']['lui'] = language_name\n\n    return params\n\n\n# get response from search-request\ndef response(resp):\n    results = []\n\n    dom = html.fromstring(resp.text)\n\n    # parse results\n    for result in eval_xpath(dom, results_xpath):\n        links = eval_xpath(result, link_xpath)\n        if not links:\n            continue\n        link = links[0]\n        url = link.attrib.get('href')\n\n        # block google-ad url's\n        if re.match(r\"^http(s|)://(www\\.)?google\\.[a-z]+/aclk.*$\", url):\n            continue\n\n        # block startpage search url's\n        if re.match(r\"^http(s|)://(www\\.)?startpage\\.com/do/search\\?.*$\", url):\n            continue\n\n        title = extract_text(link)\n\n        if eval_xpath(result, content_xpath):\n            content = extract_text(eval_xpath(result, content_xpath))\n        else:\n            content = ''\n\n        published_date = None\n\n        # check if search result starts with something like: \"2 Sep 2014 ... \"\n        if re.match(r\"^([1-9]|[1-2][0-9]|3[0-1]) [A-Z][a-z]{2} [0-9]{4} \\.\\.\\. \", content):\n            date_pos = content.find('...') + 4\n            date_string = content[0:date_pos - 5]\n            # fix content string\n            content = content[date_pos:]\n\n            try:\n                published_date = parser.parse(date_string, dayfirst=True)\n            except ValueError:\n                pass\n\n        # check if search result starts with something like: \"5 days ago ... \"\n        elif re.match(r\"^[0-9]+ days? ago \\.\\.\\. \", content):\n            date_pos = content.find('...') + 4\n            date_string = content[0:date_pos - 5]\n\n            # calculate datetime\n            published_date = datetime.now() - timedelta(days=int(re.match(r'\\d+', date_string).group()))\n\n            # fix content string\n            content = content[date_pos:]\n\n        if published_date:\n            # append result\n            results.append({'url': url,\n                            'title': title,\n                            'content': content,\n                            'publishedDate': published_date})\n        else:\n            # append result\n            results.append({'url': url,\n                            'title': title,\n                            'content': content})\n\n    # return results\n    return results\n\n\n# get supported languages from their site\ndef _fetch_supported_languages(resp):\n    # startpage's language selector is a mess\n    # each option has a displayed name and a value, either of which may represent the language name\n    # in the native script, the language name in English, an English transliteration of the native name,\n    # the English name of the writing script used by the language, or occasionally something else entirely.\n\n    # this cases are so special they need to be hardcoded, a couple of them are mispellings\n    language_names = {\n        'english_uk': 'en-GB',\n        'fantizhengwen': ['zh-TW', 'zh-HK'],\n        'hangul': 'ko',\n        'malayam': 'ml',\n        'norsk': 'nb',\n        'sinhalese': 'si',\n        'sudanese': 'su'\n    }\n\n    # get the English name of every language known by babel\n    language_names.update({name.lower(): lang_code for lang_code, name in Locale('en')._data['languages'].items()})\n\n    # get the native name of every language known by babel\n    for lang_code in filter(lambda lang_code: lang_code.find('_') == -1, locale_identifiers()):\n        native_name = Locale(lang_code).get_language_name().lower()\n        # add native name exactly as it is\n        language_names[native_name] = lang_code\n\n        # add \"normalized\" language name (i.e. fran\u00e7ais becomes francais and espa\u00f1ol becomes espanol)\n        unaccented_name = ''.join(filter(lambda c: not combining(c), normalize('NFKD', native_name)))\n        if len(unaccented_name) == len(unaccented_name.encode()):\n            # add only if result is ascii (otherwise \"normalization\" didn't work)\n            language_names[unaccented_name] = lang_code\n\n    dom = html.fromstring(resp.text)\n    sp_lang_names = []\n    for option in dom.xpath('//form[@id=\"settings-form\"]//select[@name=\"language\"]/option'):\n        sp_lang_names.append((option.get('value'), extract_text(option).lower()))\n\n    supported_languages = {}\n    for sp_option_value, sp_option_text in sp_lang_names:\n        lang_code = language_names.get(sp_option_value) or language_names.get(sp_option_text)\n        if isinstance(lang_code, str):\n            supported_languages[lang_code] = {'alias': sp_option_value}\n        elif isinstance(lang_code, list):\n            for lc in lang_code:\n                supported_languages[lc] = {'alias': sp_option_value}\n        else:\n            print('Unknown language option in Startpage: {} ({})'.format(sp_option_value, sp_option_text))\n\n    return supported_languages\n", "path": "searx/engines/startpage.py"}]}