麻辣GIS微信平台

更多 GIS 干货

微信关注不错过

「GIS数据」基于百度开发者平台的POI简单爬取

什么是POI?

POI是"Point of Information"的缩写,中文可以翻译为"信息点"。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。我们通常使用POI的数据进行一些GIS方面的分析。

百度地图 POI

百度开发者平台

百度地图是国内常用的地图之一,百度开发者平台则是百度提供给开发者各种API进行二次开发的开放平台。我们可以通过百度LBS API获取其提供的一些开发功能。

Python程序

本次开发基于百度开发者平台和py3

百度开发者平台有数个检索POI的方式,具体可参考其官方文档:
http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi

我这里根据需求选择了其中两种:行政区划区域检索和地点详情。前者提供所要检索的行政区划,后者提供具体的经纬度范围。两种方式根据获取不同格式的url进行区分。

获取url

值得注意的是,url最多只能取到20个(page_num),每页有20条数据,这意味着一次检索最多只能查到400条数据,哪怕实际空间数据超过400。url中最后一个参数ak,是需要到百度开发者平台申请的密钥。

行政区划检索

def method_region(tag,city):
    urls=[] #声明一个数组列表
    for i in range(0,20):
    page_num=str(i)  
    url='http://api.map.baidu.com/place/v2/search?query='+tag+'&region='+city_name+'&page_size=20&page_num='+str(page_num)+'&output=json&ak='+ak
    urls.append(url)

由于最多只能获取400条数据的条件会在爬取过程中丢失一部分实际存在的数据,因此,在爬取过程中,更多采用了地点详情爬取,即根据经纬度爬取。根据经纬度爬取需要提供所选区域的东西经度和南北纬度。之所以可以使数据更详实,是因为可以通过不断划分这个区域,使之成为更小的区域,从而实现对更多数据的采集。

def method_bounds(lng_r,lng_l,lat_r,lat_l):

    lng_c=lng_r-lng_l
    lat_c=lat_r-lat_l

    lng_num=int(lng_c/0.1)+1#以0.1度划分区域
    lat_num=int(lat_c/0.1)+1

    arr=np.zeros((lat_num+1,lng_num+1,2))#组成新的经纬度区域
    for lat in range(0,lat_num+1):
        for lng in range(0,lng_num+1):
            arr[lat][lng]=[lng_l+lng*0.1,lat_l+lat*0.1]

    urls=[]
    for lat in range(0,lat_num):
        for lng in range(0,lng_num):    
            for b in range(0,20):
                page_num=str(b)
                url='http://api.map.baidu.com/place/v2/search?query='+tag+'&bounds='+str((arr[lat][lng][0]))+','+str((arr[lat][lng][1]))+','+str((arr[lat+1][lng+1][0]))+','+str((arr[lat+1][lng+1][1]))+'&page_size=20&page_num='+str(page_num)+'&output=json&ak='+ak
                urls.append(url)

采集数据

从已获取到的url中对json数据的格式进行解析,我这里是直接将解析到的数据拼接写入文件中。

def getdata(url):
    try:
        socket.setdefaulttimeout(timeout)
            html=requests.get(url)
            data=html.json()
            if data['results']!=None:
              for item in data['results']:
                  jname=item['name']#获取名称
                  jlat=item['location']['lat']#获取经纬度
                  jlon=item['location']['lng']
                  jarea=item['area']#获取行政区
                  jadd=item['address']#获取具体地址
                  j_str=jname+','+str(jlat)+','+str(jlon)+','+jarea+','+jadd+','+'\n'
    except:
        getdata(url)

程序的不足与缺陷

回头看以前的代码,真是丑的一批......

首先是url获取的那段代码,三层for循环实在是令人窒息。其次是数据存储方式,之前因为图省事,是直接写到txt文本的,之后可以优化为写入MySQL数据库,存储和使用更加方便。然后还有这个数据量一旦过于庞大,尤其是按经纬度区域检索进行爬取时,py的速度已经很慢了,也没有开多线程,所以爬取速度会随着url的增加而奇慢无比。最后是之前打包过一个黑框程序,能用是能用,但是是直接运行在dos窗口中的,没有界面,抽空写个界面,就算是个比较完成的爬虫小软件了。下次一定好好优化一下,下次一定。

源码 & 下载

麻辣GIS为了防止资源恶意爬取导致被和谐,此处内容被作者隐藏。
验证码:

关注本站微信公众号,回复“资源下载”,获取验证码。

在微信里搜索“麻辣GIS”或微信扫描右侧二维码即可关注本站微信公众号。

相关阅读

麻辣GIS-纶纶

作者:

一位向 CS 投诚的 GISer

声明

1.本文所分享的所有需要用户下载使用的内容(包括但不限于软件、数据、图片)来自于网络或者麻辣GIS粉丝自行分享,版权归该下载资源的合法拥有者所有,如有侵权请第一时间联系本站删除。

2.下载内容仅限个人学习使用,请切勿用作商用等其他用途,否则后果自负。

手机阅读
公众号关注
知识星球
手机阅读
麻辣GIS微信公众号关注
最新GIS干货
关注麻辣GIS知识星球
私享圈子

留言板(小编看到第一时间回复)