generated from mwc/lab_weather
136 lines
3.7 KiB
Python
136 lines
3.7 KiB
Python
#!/usr/bin/python
|
|
# coding: utf8
|
|
|
|
from __future__ import absolute_import
|
|
|
|
from collections import OrderedDict
|
|
import logging
|
|
import re
|
|
import six
|
|
|
|
from geocoder.base import OneResult, MultipleResultsQuery
|
|
from geocoder.keys import baidu_key, baidu_security_key
|
|
|
|
|
|
class BaiduResult(OneResult):
|
|
|
|
@property
|
|
def lat(self):
|
|
return self.raw.get('location', {}).get('lat')
|
|
|
|
@property
|
|
def lng(self):
|
|
return self.raw.get('location', {}).get('lng')
|
|
|
|
@property
|
|
def quality(self):
|
|
return self.raw.get('level')
|
|
|
|
@property
|
|
def confidence(self):
|
|
return self.raw.get('confidence')
|
|
|
|
|
|
class BaiduQuery(MultipleResultsQuery):
|
|
"""
|
|
Baidu Geocoding API
|
|
===================
|
|
Baidu Maps Geocoding API is a free open the API, the default quota
|
|
one million times / day.
|
|
|
|
Params
|
|
------
|
|
:param location: Your search location you want geocoded.
|
|
:param key: Baidu API key.
|
|
:param referer: Baidu API referer website.
|
|
|
|
References
|
|
----------
|
|
API Documentation: http://developer.baidu.com/map
|
|
Get Baidu Key: http://lbsyun.baidu.com/apiconsole/key
|
|
"""
|
|
provider = 'baidu'
|
|
method = 'geocode'
|
|
|
|
_URL = 'http://api.map.baidu.com/geocoder/v2/'
|
|
_RESULT_CLASS = BaiduResult
|
|
_KEY = baidu_key
|
|
|
|
def _build_params(self, location, provider_key, **kwargs):
|
|
coordtype = kwargs.get('coordtype', 'wgs84ll')
|
|
params = {
|
|
'address': re.sub('[ ,]', '%', location),
|
|
'output': 'json',
|
|
'ret_coordtype': coordtype,
|
|
'ak': provider_key,
|
|
}
|
|
|
|
# adapt params to authentication method
|
|
self.security_key = kwargs.get('sk', baidu_security_key)
|
|
if self.security_key:
|
|
return self._encode_params(params)
|
|
else:
|
|
return params
|
|
|
|
def _encode_params(self, params):
|
|
# maintain the order of the parameters during signature creation when returning the results
|
|
# signature is added to the end of the parameters
|
|
ordered_params = sorted([(k, v)
|
|
for (k, v) in params.items() if v])
|
|
|
|
params = OrderedDict(ordered_params)
|
|
|
|
# urlencode with Chinese symbols sabotage the query
|
|
params['sn'] = self._sign_url(
|
|
'/geocoder/v2/',
|
|
params,
|
|
self.security_key
|
|
)
|
|
|
|
return params
|
|
|
|
def _sign_url(self, base_url, params, security_key):
|
|
"""
|
|
Signs a request url with a security key.
|
|
"""
|
|
import hashlib
|
|
|
|
if six.PY3:
|
|
from urllib.parse import urlencode, quote, quote_plus
|
|
else:
|
|
from urllib import urlencode, quote, quote_plus
|
|
|
|
if not base_url or not self.security_key:
|
|
return None
|
|
|
|
params = params.copy()
|
|
address = params.pop('address')
|
|
|
|
url = base_url + '?address=' + address + '&' + urlencode(params)
|
|
encoded_url = quote(url, safe="/:=&?#+!$,;'@()*[]")
|
|
|
|
signature = quote_plus(encoded_url + self.security_key).encode('utf-8')
|
|
encoded_signature = hashlib.md5(signature).hexdigest()
|
|
|
|
return encoded_signature
|
|
|
|
def _build_headers(self, provider_key, **kwargs):
|
|
return {'Referer': kwargs.get('referer', 'http://developer.baidu.com')}
|
|
|
|
def _adapt_results(self, json_response):
|
|
return [json_response['result']]
|
|
|
|
def _catch_errors(self, json_response):
|
|
status_code = json_response.get('status')
|
|
if status_code != 0:
|
|
self.status_code = status_code
|
|
self.error = json_response.get('message')
|
|
|
|
return self.error
|
|
|
|
|
|
if __name__ == '__main__':
|
|
logging.basicConfig(level=logging.INFO)
|
|
g = BaiduQuery('将台路', key='')
|
|
g.debug()
|