干货 | Python调用百度地图API获取各点的经纬度信息(两种方式)

简介: 干货 | Python调用百度地图API获取各点的经纬度信息(两种方式)

小伙伴们大家好,在上一期的推文中我们介绍了如何利用百度地图的API获取POI兴趣点的相关信息,详见:


干货 | 10分钟教你用Python获取百度地图各点的经纬度信息


但是只是简单介绍了API的调用方式。今天我们来讲讲如何在Python里面调用申请的API接口,然后利用Python进行相关的数据处理,最终得到我们想要的信息。


最近大家还是要响应号召,不出门!在家好好学习吧~


微信图片_20220422160952.gif

地点检索方式

目前百度地图的地点检索服务有以下4种方式:


行政区划区域检索:开发者可通过该功能,检索某一行政区划内(目前最细到城市级别)的地点信息。

微信图片_20220422160955.png



圆形区域检索:开发者可设置圆心和半径,检索圆形区域内的地点信息(常用于周边检索场景)。

微信图片_20220422160958.png


矩形区域检索:开发者可设置检索区域左下角和右上角坐标,检索坐标对应矩形内的地点信息(常用于手机或PC端地图视野内检索)

微信图片_20220422161001.png


地点详情检索:不同于以上三种检索功能。地点详情检索针对指定POI,检索其相关的详情信息。开发者可以通过三种区域检索(或其他服务)功能,获取POI id。使用“地点详情检索”功能,传入id,即可检索POI详情信息,如评分、营业时间等(不同类型POI对应不同类别详情数据)。

微信图片_20220422161003.png


用的方式主要是第一种和第二种,今天对这两种方式都介绍一下。

行政区划区域检索

上次说了,API的调用方式是通过编辑好的URL,请求服务器然后返回所需要的的数据,数据是JSON或者XML类型的(别问我什么是JSON)。


具体的说明大家去官网看吧balablaba的……这里我就不在BB了,直接贴上一个编辑好的URL:


http://api.map.baidu.com/place/v2/search?query=超市&region=武汉市&output=json&ak=申请的AK&scope=1&page_size=20&page_num=0


上面URL中,绿色标出的是需要填写的参数。各个参数的说明如下:


query 检索关键字。行政区划区域检索不支持多关键字检索。如果需要按POI分类进行检索,请将分类通过query参数进行设置,如query=美食。
region 检索行政区划区域(增加区域内数据召回权重,如需严格限制召回数据在区域内,请搭配使用city_limit参数),可输入行政区划名或对应cityCode。
outpu 出格式为json或者xml。
ak 开发者的访问密钥,必填项。v2之前该属性为key。
scope 检索结果详细程度。取值为1 或空,则返回基本信息;取值为2,返回检索POI详细信息。
page_size 单次召回POI数量,默认为10条记录,最大返回20条。多关键字检索时,返回的记录数为关键字个数*page_size
page_num

分页页码,默认为0,0代表第一页,1代表第二页,以此类推。常与page_size搭配使用。


关于其他可选参数更多详细信息请戳:


http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi


值得注意的是,page_size=20&page_num=0表示每个URL页面返回的POI数量为20个,这个是第0个页面,因为在程序中,一般都是从0开始的。


好了,请求讲完了,接下来放Python代码:


#coding: utf-8
import requests
import json
import time
import csv
import codecs
"""
    查询关键字:
"""
FileKey = 'preclass'
KeyWord = u"超市"
def getBaiduApiAk():
    """
    获取配置文件中百度apikey:
     { "baiduak":"xx"}
    :return: str
    """
    return "填写你申请的AK"
def requestBaiduApi(keyWords, baiduAk, fileKey):
    today = time.strftime("%Y-%m-%d")
    pageNum = 0
    count = 0
    logfile = open("./" + fileKey + "-" + today + ".log", 'a+', encoding='utf-8')
    file = open("./" + fileKey + "-" + today + ".txt", 'a+', encoding='utf-8')
    file_csv = open('shops_data_青山区.csv', 'w+', encoding='utf-8')  # 追加
    writer = csv.writer(file_csv)
    writer.writerow(["no","area","name","lat","lng"])
    # print('-------------')
    # print(index)
    while True:
        try:
            URL = "http://api.map.baidu.com/place/v2/search?query=" + keyWords + \
                "&region=" + "武汉市青山区" + \
                "&output=json" +  \
                "&ak=" + baiduAk + \
                "&scope=1" + \
                "&page_size=20" + \
                "&page_num=" + str(pageNum)
            # print(pageNum)
            print(URL)
            resp = requests.get(URL)
            res = json.loads(resp.text)
            # print(resp.text.strip())
            if len(res['results']) == 0:
                logfile.writelines(time.strftime("%Y%m%d%H%M%S") + " stop " + " " + str(pageNum) + '\n')
                break
            else:
                for r in res['results']:
                    # print(r)
                    count += 1
                    city_area = r['city']+r['area']
                    shop_name = r['name']
                    shop_lat = str(r['location']['lat'])
                    shop_lng = str(r['location']['lng'])
                    writer.writerow([str(count),city_area, shop_name, shop_lat, shop_lng])
                    # file.writelines(str(r).strip() + '\n')
                    # print(r['city']+r['area']+" "+r['name']+" "+str(r['location']['lat']) + " " + str(r['location']['lng']))
            pageNum += 1
            time.sleep(1)
        except:
            print("except")
            logfile.writelines(time.strftime("%Y%m%d%H%M%S") + " except " + " " + str(pageNum) + '\n')
            break
def main():
    baiduAk = getBaiduApiAk()
    requestBaiduApi(keyWords=KeyWord, baiduAk=baiduAk, fileKey=FileKey)
if __name__ == '__main__':
    main()

(代码于2020.1.18测试无误)


代码的思路也相当简单,首先是构造URL,然后请求返回JSON格式的数据,Python处理后写入CSV文件中。


获取的数据详情如下所示,有需要的同学可根据说明修改相应的参数获取相应的数据:


微信图片_20220422161006.jpg


值得注意的是,在实际请求中,百度API限制了检索只能返回20个URL页面。这就意味着我们一个区域最多只能检索20*20=400个POI点。实际需求中往往不止400个点的。


但人民的智慧是无穷的,我们接下来介绍第二种方式解决上面400个点的弊端。

矩形区域检索

所谓矩形区域检索,就是给定一个矩形范围的经纬度坐标(实际上两点即可定位一个矩形,左下点和右上点),然后在该矩形范围内进行兴趣点的检索。


而矩形范围经纬度坐标的确定可以利用之前介绍的坐标拾取系统进行拾取。


例如下图在武汉市(武汉加油!拾取一个蓝色框的区域,把左下角的经纬度和右上角的经纬度记录下来即可,这样一个范围就做好啦。


微信图片_20220422161008.jpg


例如我们拾取了一个矩形:

左下点的经纬度为:114.2540523, 30.471019

右上点的经纬度为:114.2687126, 30.4877379


现在利用矩形区域检索的URL如下:


http://api.map.baidu.com/place/v2/search?query=超市&bounds=30.471019,114.2540523,30.4877379,114.2687126&output=json&ak=申请的AK&scope=1&page_size=20&page_num=0

 

参数无太大变化,就是region变成了bounds,并且指出了矩形区域的边界经纬度(左下点和右上点)。注意绿色处要填上你自己的AK。

 

好了,现在检查一下URL编辑是否正确,复制到浏览器回车一下看看:


微信图片_20220422161011.jpg

 

OK,大功告成。好了,现在我们来解决400个点限制的问题。不知道聪明的你们想到了没有。


没错,就是切割区域。既然百度限制了每个区域检索最多只能返回400个点,那么可以通过矩形检索的方式,将一个大矩形切割成很多小矩形,依次在每个小矩形内进行检索,最后将所有小矩形的结果加起来就有很多很多个点啦。怎样,是不是很聪明呢!


微信图片_20220422161013.jpg


例如将一个大区域分割成1234号区域分别检索,假如每个区域都返回400个点,那么总共就能获取4X400=1600个点了。


而如何分割,则不必手动拾取点进行划分,可以利用程序来计算嘛!


微信图片_20220422161016.jpg


好了,下面给出一份分割区域的Python代码:

#coding: utf-8
import requests
import json
import time
import csv
"""
    查询关键字:
"""
FileKey = 'preclass'
KeyWord = u"便利店"
"""
    关注区域的左下角和右上角百度地图坐标(经纬度)
"""
BigRect = {
    'left': {
        'x': 114.239392,
        'y': 30.471019
    },
    'right': {
        'x': 114.385995,
        'y': 30.638208
    }
}
"""
    定义细分窗口的数量,横向X * 纵向Y
"""
WindowSize = {
    'xNum': 10.0,
    'yNum': 10.0
}
"""
获取AK
:return: str
"""
def getBaiduApiAk():
    return "申请的AK"
def getSmallRect(bigRect, windowSize, windowIndex):
    """
    获取小矩形的左上角和右下角坐标字符串(百度坐标系)
    :param bigRect: 关注区域坐标信息
    :param windowSize:  细分窗口数量信息
    :param windowIndex:  Z型扫描的小矩形索引号
    :return: lat,lng,lat,lng
    """
    offset_x = (bigRect['right']['x'] - bigRect['left']['x'])/windowSize['xNum']
    offset_y = (bigRect['right']['y'] - bigRect['left']['y'])/windowSize['yNum']
    left_x = bigRect['left']['x'] + offset_x * (windowIndex % windowSize['xNum'])
    left_y = bigRect['left']['y'] + offset_y * (windowIndex // windowSize['yNum'])
    right_x = (left_x + offset_x)
    right_y = (left_y + offset_y)
    return str(left_y) + ',' + str(left_x) + ',' + str(right_y) + ',' + str(right_x)
def requestBaiduApi(keyWords, smallRect, baiduAk, index, fileKey, count):
    today = time.strftime("%Y-%m-%d")
    pageNum = 0
    logfile = open("./" + fileKey + "-" + today + ".log", 'a+', encoding='utf-8')
    file_csv = open('testdata.csv', 'w+', encoding='utf-8',newline='')  # 追加
    writer = csv.writer(file_csv)
    writer.writerow(["no","area","name","lat","lng"])
    # print('-------------')
    # print(index)
    while True:
        try:
            URL = "http://api.map.baidu.com/place/v2/search?query=" + keyWords + \
                "&bounds=" + smallRect + \
                "&output=json" +  \
                "&ak=" + baiduAk + \
                "&scope=1" + \
                "&page_size=20" + \
                "&page_num=" + str(pageNum)
            print(pageNum)
            print(URL)
            resp = requests.get(URL)
            res = json.loads(resp.text)
            # print(resp.text.strip())
            if len(res['results']) == 0:
                logfile.writelines(time.strftime("%Y%m%d%H%M%S") + " stop " + str(index) + " " + smallRect + " " + str(pageNum) + '\n')
                break
            else:
                for r in res['results']:
                    # print(r)
                    count += 1
                    city_area = r['city'] + r['area']
                    shop_name = r['name']
                    shop_lat = str(r['location']['lat'])
                    shop_lng = str(r['location']['lng'])
                    writer.writerow([str(count), city_area, shop_name, shop_lat, shop_lng])
            pageNum += 1
            time.sleep(1)
        except:
            print("except")
            logfile.writelines(time.strftime("%Y%m%d%H%M%S") + " except "  + str(index) + " " + smallRect + " " + str(pageNum) + '\n')
            break
    return count
def main():
    baiduAk = getBaiduApiAk()
    count = 0
    for index in range(int(WindowSize['xNum'] * WindowSize['yNum'])):
        smallRect = getSmallRect(BigRect, WindowSize, index)
        count = requestBaiduApi(keyWords=KeyWord, smallRect=smallRect, baiduAk=baiduAk, index=index, fileKey=FileKey,count= count)
        time.sleep(1)
        print(str(count))
if __name__ == '__main__':
    main()

(代码于2020.1.18测试无误)

读者只需要简单修改代码中的:


  • 查询关键字
  • 关注区域的左下角和右上角百度地图坐标(经纬度)
  • 定义细分窗口的数量,横向X * 纵向Y
  • 获取AK


这几处的相关信息即可使用,生成的数据如下所示:


微信图片_20220422161018.png


怎样,是不是很简单呢!至此,两种方式已经介绍完毕。当然,获取经纬度信息只是我们的第一步操作,后续的过程我们将向大家展示如何根据经纬度信息获取两点之间的真实距离。


微信图片_20220422161020.jpg


希望这次的疫情尽快过去,大家都相安无事!


小编还要回去上学吃热干面呢!武汉加油!


网络异常,图片无法展示
|

相关文章
|
10天前
|
JSON 数据可视化 API
Python 中调用 DeepSeek-R1 API的方法介绍,图文教程
本教程详细介绍了如何使用 Python 调用 DeepSeek 的 R1 大模型 API,适合编程新手。首先登录 DeepSeek 控制台获取 API Key,安装 Python 和 requests 库后,编写基础调用代码并运行。文末包含常见问题解答和更简单的可视化调用方法,建议收藏备用。 原文链接:[如何使用 Python 调用 DeepSeek-R1 API?](https://apifox.com/apiskills/how-to-call-the-deepseek-r1-api-using-python/)
|
1月前
|
数据采集 供应链 API
Python爬虫与1688图片搜索API接口:深度解析与显著收益
在电子商务领域,数据是驱动业务决策的核心。阿里巴巴旗下的1688平台作为全球领先的B2B市场,提供了丰富的API接口,特别是图片搜索API(`item_search_img`),允许开发者通过上传图片搜索相似商品。本文介绍如何结合Python爬虫技术高效利用该接口,提升搜索效率和用户体验,助力企业实现自动化商品搜索、库存管理优化、竞品监控与定价策略调整等,显著提高运营效率和市场竞争力。
83 3
|
2月前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
51 10
|
2月前
|
数据采集 JSON API
如何利用Python爬虫淘宝商品详情高级版(item_get_pro)API接口及返回值解析说明
本文介绍了如何利用Python爬虫技术调用淘宝商品详情高级版API接口(item_get_pro),获取商品的详细信息,包括标题、价格、销量等。文章涵盖了环境准备、API权限申请、请求构建和返回值解析等内容,强调了数据获取的合规性和安全性。
|
1月前
|
数据采集 JavaScript 前端开发
京东商品详情 API 接口指南(Python 篇)
本简介介绍如何使用Python抓取京东商品详情数据。首先,需搭建开发环境并安装必要的库(如requests、BeautifulSoup和lxml),了解京东反爬虫机制,确定商品ID获取方式。通过发送HTTP请求并解析HTML,可提取价格、优惠券、视频链接等信息。此方法适用于电商数据分析、竞品分析、购物助手及内容创作等场景,帮助用户做出更明智的购买决策,优化营销策略。
|
jenkins API 持续交付
PYTHON调用JENKINS的API来进行CI
我查到的相关API有两套,我主要用的是python-jenkins。 https://pypi.python.org/pypi/python-jenkins/ 按语法调用即可。。。 import jenkins server = jenkins.
2558 0
|
6天前
|
API PHP 开发者
速卖通商品详情接口(速卖通API系列)
速卖通(AliExpress)是阿里巴巴旗下的跨境电商平台,提供丰富的商品数据。通过速卖通开放平台(AliExpress Open API),开发者可获取商品详情、订单管理等数据。主要功能包括商品搜索、商品详情、订单管理和数据报告。商品详情接口aliexpress.affiliate.productdetail.get用于获取商品标题、价格、图片等详细信息。开发者需注册账号并创建应用以获取App Key和App Secret,使用PHP等语言调用API。该接口支持多种请求参数和返回字段,方便集成到各类电商应用中。
|
12天前
|
JSON API 数据格式
微店商品列表接口(微店 API 系列)
微店商品列表接口是微店API系列的一部分,帮助开发者获取店铺中的商品信息。首先需注册微店开发者账号并完成实名认证,选择合适的开发工具如PyCharm或VS Code,并确保熟悉HTTP协议和JSON格式。该接口支持GET/POST请求,主要参数包括店铺ID、页码、每页数量和商品状态等。响应数据为JSON格式,包含商品详细信息及状态码。Python示例代码展示了如何调用此接口。应用场景包括商品管理系统集成、数据分析、多平台数据同步及商品展示推广。
|
4天前
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
26 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
3天前
|
监控 供应链 搜索推荐
亚马逊商品详情接口(亚马逊 API 系列)
亚马逊作为全球最大的电商平台之一,提供了丰富的商品资源。开发者和电商从业者可通过亚马逊商品详情接口获取商品的描述、价格、评论、排名等数据,对市场分析、竞品研究、价格监控及业务优化具有重要价值。接口基于MWS服务,支持HTTP/HTTPS协议,需注册并获得API权限。Python示例展示了如何使用mws库调用接口获取商品详情。应用场景包括价格监控、市场调研、智能选品、用户推荐和库存管理等,助力电商运营和决策。
46 23

热门文章

最新文章