当我们想获取北京市"麦当劳"全部餐饮地址时,请求的地址:
https://restapi.amap.com/v3/place/text?keywords=麦当劳&city=北京&offset=20&page=1&key={key}&extensions=base
url中,?后面跟的就是请求时的参数。
- keywords :要搜索的关键词
- city :城市,可以查看具体的城市码表(官方提供)
- offset :每页显示多少条数据
- page :页数
- key :之前申请的用户 key
- extensions : 传入 base 即可,all 的话比较多余
还有些可选项,不传就行啦,比如 output=xml ,默认不传就是 json 形式返回结果。
1. 读取用户 key 函数
目的是读取本地 key ,灵活化处理(这样不用暴露自己的 key 给大家看了 ) user-key中写入你自己的key。
def read_key():
""" 持久化key,便于读取 """
key_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'user-key')
print(key_path)
with open(key_path, 'r', encoding='utf-8') as f:
key = f.read()
print(key)
return key
2. requests 请求,get 方式通用函数
使用方法按照去看 requests 库的官方文档即可。
def request_url_get(url):
""" 请求url方法get方法 """
try:
r = requests.get(url=url, timeout=30)
if r.status_code == 200:
return r.text
return None
except RequestException:
print('请求url返回错误异常')
return None
3. 调用高德 api 抽象方法,解析返回的 json 函数
使用了 python 自带的 json 库,将高德 api 返回的字符串转为了 json 形式,但是在 python 中,其实是 dict 类型的,获取结果可以通过类似 result['address'] 的形式获取想要的内容。
def parse_json(content_json):
""" 解析json函数 """
result_json = json.loads(content_json)
return result_json
def request_api(url):
""" 请求高德api 解析json """
result = request_url_get(url)
result_json = parse_json(result)
return result_json
4. 调用高德 api 抽象方法,解析返回的 json 函数
def run():
""" 运行函数 """
keywords = '麦当劳'
city = 'beijing'
key = read_key()
offset = 20
index_url = f'https://restapi.amap.com/v3/place/text?keywords={keywords}&city={city}&' \
f'offset={offset}&page=1&key={key}&extensions=base'
index_result = request_api(index_url)
pages = math.ceil(int(index_result['count']) / offset) # 算出一共需要的总页数
for page in range(1, pages + 1):
url = f'https://restapi.amap.com/v3/place/text?keywords={keywords}&city={city}&' \
f'offset={offset}&page={page}&key={key}&extensions=base'
result = request_api(url)
print(result)
最后这个函数,好好说下,精华思路都在这块。
为了代码的灵活度,我们可以将请求的中的变化参数抽出来,作为程序中的变量去构造请求。
请求第一次时,高德地图会返回一个 count 字段,代表总数量,使用 count / offset ,就能得到一共我们要循环访问多少页。代码中做了向上转型的处理。
例如下面:
查询北京麦当劳一共 262 个数据,每页只显示 20 条数据(offset的值),所以 262/20 = 13.1 。
这样需要让传入 url 中的 page 从 1 - 14 页去循环获取数据。所以在代码中,使用了 math.ceil 的方法让 13.1 变成 14。
看下最终获取完数据的截图: