wolframalpha_noapi.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # Wolfram|Alpha (Science)
  2. #
  3. # @website https://www.wolframalpha.com/
  4. # @provide-api yes (https://api.wolframalpha.com/v2/)
  5. #
  6. # @using-api no
  7. # @results JSON
  8. # @stable no
  9. # @parse url, infobox
  10. from json import loads
  11. from time import time
  12. from urllib import urlencode
  13. from searx.poolrequests import get as http_get
  14. # search-url
  15. url = 'https://www.wolframalpha.com/'
  16. search_url = url + 'input/json.jsp'\
  17. '?async=false'\
  18. '&banners=raw'\
  19. '&debuggingdata=false'\
  20. '&format=image,plaintext,imagemap,minput,moutput'\
  21. '&formattimeout=2'\
  22. '&{query}'\
  23. '&output=JSON'\
  24. '&parsetimeout=2'\
  25. '&proxycode={token}'\
  26. '&scantimeout=0.5'\
  27. '&sponsorcategories=true'\
  28. '&statemethod=deploybutton'
  29. referer_url = url + 'input/?{query}'
  30. token = {'value': '',
  31. 'last_updated': 0}
  32. # pods to display as image in infobox
  33. # this pods do return a plaintext, but they look better and are more useful as images
  34. image_pods = {'VisualRepresentation',
  35. 'Illustration',
  36. 'Symbol'}
  37. # seems, wolframalpha resets its token in every hour
  38. def obtain_token():
  39. update_time = time() - (time() % 3600)
  40. try:
  41. token_response = http_get('https://www.wolframalpha.com/input/api/v1/code?ts=9999999999999999999', timeout=2.0)
  42. token['value'] = loads(token_response.text)['code']
  43. token['last_updated'] = update_time
  44. except:
  45. pass
  46. return token
  47. obtain_token()
  48. # do search-request
  49. def request(query, params):
  50. # obtain token if last update was more than an hour
  51. if time() - token['last_updated'] > 3600:
  52. obtain_token()
  53. params['url'] = search_url.format(query=urlencode({'input': query}), token=token['value'])
  54. params['headers']['Referer'] = referer_url.format(query=urlencode({'i': query}))
  55. return params
  56. # get response from search-request
  57. def response(resp):
  58. results = []
  59. resp_json = loads(resp.text)
  60. if not resp_json['queryresult']['success']:
  61. return []
  62. # TODO handle resp_json['queryresult']['assumptions']
  63. result_chunks = []
  64. infobox_title = None
  65. for pod in resp_json['queryresult']['pods']:
  66. pod_id = pod.get('id', '')
  67. pod_title = pod.get('title', '')
  68. if 'subpods' not in pod:
  69. continue
  70. if pod_id == 'Input' or not infobox_title:
  71. infobox_title = pod['subpods'][0]['plaintext']
  72. for subpod in pod['subpods']:
  73. if subpod['plaintext'] != '' and pod_id not in image_pods:
  74. # append unless it's not an actual answer
  75. if subpod['plaintext'] != '(requires interactivity)':
  76. result_chunks.append({'label': pod_title, 'value': subpod['plaintext']})
  77. elif 'img' in subpod:
  78. result_chunks.append({'label': pod_title, 'image': subpod['img']})
  79. if not result_chunks:
  80. return []
  81. results.append({'infobox': infobox_title,
  82. 'attributes': result_chunks,
  83. 'urls': [{'title': 'Wolfram|Alpha', 'url': resp.request.headers['Referer'].decode('utf8')}]})
  84. results.append({'url': resp.request.headers['Referer'].decode('utf8'),
  85. 'title': 'Wolfram|Alpha',
  86. 'content': infobox_title})
  87. return results