arcgis与python的结合_结合GIS与Python,爬取百度商业POI

一、总体思路

1-利用arcgis创建渔网,商业网点稀疏用大矩形,商业网点密集用小矩形

2-求出矩形左下角和右上角坐标点,读取矩形表得到坐标串

maxX= !shape.extent.xmax!

minX= !shape.extent.xmin!

3-采用百度API矩形区域检索,发起GET请求,并解析json数据

4-本地存储到Excel

5-转为shp,gis可视化

二、代码实现

1、利用arcgis创建渔网,商业网点稀疏用大矩形,商业网点密集用小矩形

由于百度API限制,一个矩形范围内仅能下载400条记录(400个POI),为了减少请求次数,提高效率,对目标区域进行处理:商业网点稀疏用大矩形,商业网点密集用小矩形。这里利用ArcGIS渔网工具,最小网格为2KM*2KM。类似如下图:

2、求出矩形左下角和右上角坐标点,读取矩形表得到坐标串

1-新建左下角X,左下角Y,右上角X,右上角Y,bsm字段

2-利用arcmap字段计算器工具计算每个矩形的左下角和右上角坐标点,表达式为:

左下角X,Y:                  右上角X,Y:

minX= !shape.extent.xmin!            maxX= !shape.extent.xmax!

minY= !shape.extent.ymin!            maxY= !shape.extent.ymax!

3-代码读取坐标串

1 importpandas as pd2 def get_bounds(self,path,sheet_name): #1读取矩形表

3 bounds={}4 df = pd.read_excel(io = path, sheet_name=sheet_name)5 for index indf.index:6 bsm = df.at[index, 'bsm']7 ymin = df.at[index, '左下角Y']8 xmin = df.at[index, '左下角X']9 ymax = df.at[index, '右上角Y']10 xmax = df.at[index, '右上角X']11 coord = str(ymin) + ',' + str(xmin) + ',' + str(ymax) + ',' +str(xmax)12 bounds[bsm] = coord #一个标识码对应一个坐标串,方便后续查看每个矩形框下载完成情况

13 return bounds

3、采用矩形区域检索,发起GET请求,并解析json数据

4、本地存储到Excel

百度API文档示例:http://api.map.baidu.com/place/v2/search?query=银行&bounds=39.915,116.404,39.975,116.414&output=json&ak={您的密钥} //GET请求

百度POI分类:http://lbsyun.baidu.com/index.php?title=lbscloud/poitags

1 def get_poi(self,query,bound,bsm,path): #2发起请求

2 wb = openpyxl.load_workbook(path) #打开工作簿

3 ws1 = wb['POI'] #选取表单,为了写入POI信息

4 ws2 = wb['Summary'] #为了记录每个矩形框下载情况是否超400条记录,如果有超过,就得重新分成小矩形

5 for page_num in range(20): #请求页面循环,返回的poi是百度坐标需要坐标转换

6 print('正在爬取矩形框bsm为{0}的第{1}页数据...'.format(bsm,page_num+1))7 url = 'http://api.map.baidu.com/place/v2/search'

8 params ={9 'query': query, #示例,;分开

10 'bounds': bound, #1:检索矩形区域,多组坐标间以","分隔 # 38.76623,116.43213,39.54321,116.46773 lat,lng(左下角坐标),lat,lng(右上角坐标)

11 'output': 'json',12 'coord_type': '1', #1(wgs84ll即GPS经纬度) 表示输入的是wgs坐标

13 'page_size': '20',14 'page_num': page_num, #0代表第一页

15 'ak': '你的ak'

16 }17 #拿到一页详情

18 detail_page = requests.get(url=url,params=params,headers=self.headers).json()19 if len(detail_page['results']) == 0 and detail_page['status'] == 0: #判断如果请求页面没有数据,就爬取下一页

20 print('请求成功,但是没有记录,开始下一页爬取。')21 break

22 #解析

23 for dic_result in detail_page['results']:24 total = detail_page['total'] #后续查看爬取情况是否满400条记录

25 #基本信息,做判断相应的关键字中是否都有结果,没有赋值为‘’

26 if 'name' indic_result.keys():27 name = dic_result['name']28 else:29 name = ''

30 if 'location' indic_result.keys():31 lng, lat = cc.bd09_to_wgs84(dic_result['location']['lng'], dic_result['location']['lat']) #百度坐标转gps

32 else:33 lng, lat = '',''

34 if 'address' indic_result.keys():35 address = dic_result['address']36 else:37 address=''

38 #详情信息

39 #if dic_result['detail_info'].key():

40 #price = dic_result['detail_info']['price'] #均价

41 #overall_rating = dic_result['detail_info']['overall_rating'] #总体评分

42 #comment_num = dic_result['detail_info']['comment_num'] #评论数

43 #return [name,lng,lat,address,bsm],[bsm,total]

44 ws1.append([name,lng,lat,address,bsm])45 ws2.append([bsm,total])46 print('矩形框bsm为{0}的第{1}页数据下载成功!'.format(bsm,page_num+1))47 time.sleep(0.5) #防止访问过快,百度服务求拒绝请求

48 wb.save(path)49 print('-------矩形框bsm为{0}数据下载完成-------'.format(bsm))

5、GIS可视化

利用GIS的核密度工具,生成商业网点热力图。population字段为权重字段,不同商业网点不同的规模,这里不做设置,仅仅体现数量的密集度。也可以结合arcScene做3D效果。

    

附完整代码

这里没必要用类编程,只是现学现用了,直接函数式编程即可

12 importrequests,time,openpyxl,os13 importpandas as pd14 importcoordconversion as cc15 classBaiduSpider():16 def __init__(self):17 self.headers={18 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36'

19 }20

21 def get_bounds(self,path,sheet_name): #1读取矩形表

22 bounds={}23 df = pd.read_excel(io = path, sheet_name=sheet_name)24 for index indf.index:25 bsm = df.at[index, 'bsm']26 ymin = df.at[index, '左下角Y']27 xmin = df.at[index, '左下角X']28 ymax = df.at[index, '右上角Y']29 xmax = df.at[index, '右上角X']30 coord = str(ymin) + ',' + str(xmin) + ',' + str(ymax) + ',' +str(xmax)31 bounds[bsm] =coord32 returnbounds33

34 def get_poi(self,query,bound,bsm,path): #2发起请求

35 wb = openpyxl.load_workbook(path) #打开工作簿

36 ws1 = wb['POI'] #选取表单,为了写入POI信息

37 ws2 = wb['Summary'] #为了记录每个矩形框下载情况是否超400条记录,如果有超过,就得重新分成小矩形

38 for page_num in range(20): #请求页面循环,返回的poi是百度坐标需要坐标转换

39 print('正在爬取矩形框bsm为{0}的第{1}页数据...'.format(bsm,page_num+1))40 url = 'http://api.map.baidu.com/place/v2/search'

41 params ={42 'query': query, #示例,;分开

43 'bounds': bound, #1:检索矩形区域,多组坐标间以","分隔 # 38.76623,116.43213,39.54321,116.46773 lat,lng(左下角坐标),lat,lng(右上角坐标)

44 'output': 'json',45 'coord_type': '1', #1(wgs84ll即GPS经纬度) 表示输入的是wgs坐标

46 'page_size': '20',47 'page_num': page_num, #0代表第一页

48 'ak': '你的ak'

49 }50 #拿到一页详情

51 detail_page = requests.get(url=url,params=params,headers=self.headers).json()52 if len(detail_page['results']) == 0 and detail_page['status'] == 0: #判断如果请求页面没有数据,就爬取下一页

53 print('请求成功,但是没有记录,开始下一页爬取。')54 break

55 #解析

56 for dic_result in detail_page['results']:57 total = detail_page['total'] #后续查看爬取情况是否满400条记录

58 #基本信息,做判断相应的关键字中是否都有结果,没有赋值为‘’

59 if 'name' indic_result.keys():60 name = dic_result['name']61 else:62 name = ''

63 if 'location' indic_result.keys():64 lng, lat = cc.bd09_to_wgs84(dic_result['location']['lng'], dic_result['location']['lat']) #百度坐标转gps

65 else:66 lng, lat = '',''

67 if 'address' indic_result.keys():68 address = dic_result['address']69 else:70 address=''

71 #详情信息

72 #if dic_result['detail_info'].key():

73 #price = dic_result['detail_info']['price'] #均价

74 #overall_rating = dic_result['detail_info']['overall_rating'] #总体评分

75 #comment_num = dic_result['detail_info']['comment_num'] #评论数

76 #return [name,lng,lat,address,bsm],[bsm,total]

77 ws1.append([name,lng,lat,address,bsm])78 ws2.append([bsm,total])79 print('矩形框bsm为{0}的第{1}页数据下载成功!'.format(bsm,page_num+1))80 time.sleep(0.5) #防止访问过快,百度服务求拒绝请求

81 wb.save(path)82 print('-------矩形框bsm为{0}数据下载完成-------'.format(bsm))83

84 def creat_excel(self,path): #写

85 if notos.path.exists(path):86 wb = openpyxl.Workbook() #创建工作簿

87 ws1=wb.create_sheet('POI') #新增一个POI表单

88 ws1.append(['name', 'lng', 'lat', 'address', 'bsm'])89 ws2=wb.create_sheet('Summary') #新增一个汇总表单

90 ws2.append(['bsm','total'])91 wb.save(path) #保存

92

93 if __name__=='__main__':94 query = '休闲娱乐'

95 bs =BaiduSpider()96 bs.creat_excel(path = query + '商业网点POI.xlsx')97 bounds=bs.get_bounds(path = r'F:\商业网点规划\矩形表.xlsx', sheet_name = 'Sheet1') #读取矩形表

98 for bsm, bound in bounds.items(): #矩形框循环,bsm用于记录哪些矩形框已经爬取过了

99 bs.get_poi(query = query,bound = bound,bsm = bsm,path = query + '商业网点POI.xlsx')100 #print(bsm,bound)

101 print('---------------程序结束!--------------')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值