autocomplete.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. '''
  2. searx is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU Affero General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. searx is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU Affero General Public License for more details.
  10. You should have received a copy of the GNU Affero General Public License
  11. along with searx. If not, see < http://www.gnu.org/licenses/ >.
  12. (C) 2013- by Adam Tauber, <asciimoo@gmail.com>
  13. '''
  14. from lxml import etree
  15. from json import loads
  16. from urllib.parse import urlencode
  17. from requests import RequestException
  18. from searx import settings
  19. from searx.poolrequests import get as http_get
  20. from searx.exceptions import SearxEngineResponseException
  21. def get(*args, **kwargs):
  22. if 'timeout' not in kwargs:
  23. kwargs['timeout'] = settings['outgoing']['request_timeout']
  24. kwargs['raise_for_httperror'] = True
  25. return http_get(*args, **kwargs)
  26. def brave(query, lang):
  27. # brave search autocompleter
  28. url = 'https://search.brave.com/api/suggest?{query}'
  29. resp = get(url.format(query=urlencode({'q': query})))
  30. results = []
  31. if resp.ok:
  32. data = loads(resp.text)
  33. for suggestion in data[1]:
  34. results.append(suggestion)
  35. return results
  36. def dbpedia(query, lang):
  37. # dbpedia autocompleter, no HTTPS
  38. autocomplete_url = 'https://lookup.dbpedia.org/api/search.asmx/KeywordSearch?'
  39. response = get(autocomplete_url + urlencode(dict(QueryString=query)))
  40. results = []
  41. if response.ok:
  42. dom = etree.fromstring(response.content)
  43. results = dom.xpath('//Result/Label//text()')
  44. return results
  45. def duckduckgo(query, lang):
  46. # duckduckgo autocompleter
  47. url = 'https://ac.duckduckgo.com/ac/?{0}&type=list'
  48. resp = loads(get(url.format(urlencode(dict(q=query)))).text)
  49. if len(resp) > 1:
  50. return resp[1]
  51. return []
  52. def google(query, lang):
  53. # google autocompleter
  54. autocomplete_url = 'https://suggestqueries.google.com/complete/search?client=toolbar&'
  55. response = get(autocomplete_url + urlencode(dict(hl=lang, q=query)))
  56. results = []
  57. if response.ok:
  58. dom = etree.fromstring(response.text)
  59. results = dom.xpath('//suggestion/@data')
  60. return results
  61. def startpage(query, lang):
  62. # startpage autocompleter
  63. lui = ENGINES_LANGUAGES['startpage'].get(lang, 'english')
  64. url = 'https://startpage.com/suggestions?{query}'
  65. resp = get(url.format(query=urlencode({'q': query, 'segment': 'startpage.udog', 'lui': lui})))
  66. data = resp.json()
  67. return [e['text'] for e in data.get('suggestions', []) if 'text' in e]
  68. def swisscows(query, lang):
  69. # swisscows autocompleter
  70. url = 'https://swisscows.ch/api/suggest?{query}&itemsCount=5'
  71. resp = loads(get(url.format(query=urlencode({'query': query}))).text)
  72. return resp
  73. def qwant(query, lang):
  74. # qwant autocompleter (additional parameter : lang=en_en&count=xxx )
  75. url = 'https://api.qwant.com/api/suggest?{query}'
  76. resp = get(url.format(query=urlencode({'q': query, 'lang': lang})))
  77. results = []
  78. if resp.ok:
  79. data = loads(resp.text)
  80. if data['status'] == 'success':
  81. for item in data['data']['items']:
  82. results.append(item['value'])
  83. return results
  84. def wikipedia(query, lang):
  85. # wikipedia autocompleter
  86. url = 'https://' + lang + '.wikipedia.org/w/api.php?action=opensearch&{0}&limit=10&namespace=0&format=json'
  87. resp = loads(get(url.format(urlencode(dict(search=query)))).text)
  88. if len(resp) > 1:
  89. return resp[1]
  90. return []
  91. backends = {'brave': brave,
  92. 'dbpedia': dbpedia,
  93. 'duckduckgo': duckduckgo,
  94. 'google': google,
  95. 'startpage': startpage,
  96. 'swisscows': swisscows,
  97. 'qwant': qwant,
  98. 'wikipedia': wikipedia
  99. }
  100. def search_autocomplete(backend_name, query, lang):
  101. backend = backends.get(backend_name)
  102. if backend is None:
  103. return []
  104. try:
  105. return backend(query, lang)
  106. except (RequestException, SearxEngineResponseException):
  107. return []