python爬取百度地图数据可视化_数据爬取实战——POI爬取
及数据可视化
数据爬取实战——POI爬取及数据可视化
爬⾍技术和GIS结合在⼀起可以碰撞出意想不到的⽕花,通过百度地图api/forlium/requests/wordcloud库可以爬取到感兴趣的POI数据,并直观地将其显⽰出来。本章通过requests库调⽤百度地图api爬取数据,并利⽤forlium库可视化数据,最后⽤wordcloud库统计出现频率最⾼的汉字,制作词云。
(1)调⽤百度地图api/requests库爬取POI数据
Method1
def method_region():
print("请输⼊所需要爬取数据的⾏政区划名称,如南京市,南京市⿎楼区等")
city=str(input())
print ('开始')
urls=[] #声明⼀个数组列表
for i in range(0,20):
page_num=str(i)
url='api.map.baidu/place/v2/search?
query='+name+'®ion='+city+'&page_size=20&page_num='+str(page_num)+'&output=json&ak='+ak
urls.append(url)
print ('url列表读取完成')
for url in urls:
getdata(url)
print('爬取中,请耐⼼等待')
f.close()
print ('完成,⽂件位于D盘⽬录下,请查看')
Method2
def method_bounds(): #读取POI更多,更细
print("请输⼊所选取地图矩形区域范围的左下⾓经度")
lat_l=float(input())
print("请输⼊所选取地图矩形区域范围的左下⾓纬度")
lng_l=float(input())
print("请输⼊所选取地图矩形区域范围的右上⾓经度")
lat_r=float(input())
print("请输⼊所选取地图矩形区域范围的右上⾓纬度")
lng_r=float(input())
a=(lat_l>=lat_r or lng_l>=lng_r)
while a:
print('经纬度输⼊错误,请重新输⼊')
print("请输⼊所选取地图矩形区域范围的左下⾓经度")
lat_l=float(input())
print("请输⼊所选取地图矩形区域范围的左下⾓纬度")
lng_l=float(input())
print("请输⼊所选取地图矩形区域范围的右上⾓经度")
lat_r=float(input())
print("请输⼊所选取地图矩形区域范围的右上⾓纬度")java资料下载
lng_r=float(input())
a=(lat_l>lat_r or lng_l>lng_r)
lng_c=lng_r-lng_l
lat_c=lat_r-lat_l
#将研究区按经纬度步长⼤⼩划分若⼲块,存储每块左下、右上经纬度
lng_num=int(lng_c/0.1)+1 #经纬度跨步越⼩,采集数据越多
lat_num=int(lat_c/0.1)+1
s((lat_num+1,lng_num+1,2)) #前两维是⾏数、列数,第三维是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]array push函数
urls=[]
print('开始')
for lat in range(0,lat_num):
for lng in range(0,lng_num):
for b in range(0,20): #每块最多读取20页POI数据
page_num=str(b)
url='api.map.baidu/place/v2/search?query='+name+'&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)
print ('url列表读取完成')
for url in urls:
getdata(url)
print('爬取中,请耐⼼等待')
f.close()
print ('完成,⽂件位于D盘⽬录下,请查看')
这⾥介绍⼀下Method2。它采⽤的思想主要是这样的,虽然我们对某⼀块区域爬取的数据数量受到了限制(400个/20页),但我们可以通过将⼀整块较⼤的矩形区域划分为若⼲⼩矩形块,然后分别遍历爬取从⽽解决这个问题。划分的步长越⼩(这⾥是0.1),爬取的越仔细,数据量也越⼤,亲测0.01时爬取的数据⽐前者多了2000+。在⽹格⼩到⼀定程度的时候,⽹格内的POI数量⼩于400,就不会受到20页等的限制了,这时爬取的数据较为详细。
上图是三维数组的形式,函数中⽤于存储经纬度的列表是三维数组,前两维是⾏数和列数,第三维存储了经纬度数据,具体存放形式如上图。
def getdata(url):
try:
socket.setdefaulttimeout(timeout) #设置间隔时间,防⽌爬取时被阻断
(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'
f.write(j_str)
#time.sleep(1)
except:
getdata(url)
这段代码不⽤多说吧,requests发起get请求,解析数据为json格式,然后获取到名称、经纬度、⾏政区、地址等信息。
(2)制作heatmap
获取这些数据后,为了进⾏数据的可视化,我们学习了forlium模块。
f olium是js上著名的地理信息可视化库leaflet.js为Python提供的接⼝,通过它,我们可以通过在Python端编写代码操纵数据,来调⽤leaflet的相关功能,基于内建的osm或⾃⾏获取的osm资源和地图原件进⾏地理信息内容的可视化,以及制作优美的可交互地图。其语法格式类似ggplot2,是通过不断添加图层元素来定义⼀个Map对象,最后以⼏种⽅式将Map对象展现出来。
import numpy as np
import pandas as pd
import folium
import webbrowser #浏览器
from folium.plugins import HeatMap
poi_file = 'D:\'
p_lon =[]
p_lat =[]
poi_name =[]
f = open(poi_file, 'r', encoding='utf-8') #注意encoding='utf-8'
for line adlines(): #逐⾏读取
line = line.split(',')
p_lon.append(line[2])
p_lat.append(line[1])
poi_name.append(line[0])
f.close()
data = [ [p_lat[i], p_lon[i]] for i in range(2000) ] #将数据制作成[lats,lons,weights]的形式,这⾥只显⽰2000个POI数据
map_osm = folium.Map(location=[1,2],zoom_start=5) #绘制Map,开始缩放程度是5倍
求函数值域的几种基本方法
HeatMap(data).add_to(map_osm) # 绘制热⼒图,并将热⼒图添加到map⾥
python请求并解析json数据file_path = r"D:/text.html"
map_osm.save(file_path) # 保存为html⽂件
webbrowser.open(file_path) # 默认浏览器打开
如图,效果还算不错的嘛。
(3)wordcloud制作
早就听过wordcloud的⼤名了,选取⽂本中的⾼频词汇,然后按频率分布制作词云。这⾥由于字符串属于中⽂字符,需要下载字体⽂件,进⾏解译(旁门左道字体)。
import wordcloud
#注:⽂件名不能为wordcloud.py,会导不了库
poi_name = []
f = open( 'D:\','r',encoding='utf-8')
for line adlines():
line = line.split(',')
poi_name.append(line[0])
text = str(poi_name) #列表转str字符串
wc = wordcloud.WordCloud(
background_color='white',
font_path="D:\Tablefile\POI_GET\POI_f" #添加字体,否则中⽂字体会乱码
)
<_file(r"D:\Tablefile\POI_GET\POI_GET-master\1.png")
沙县⼩吃果然傲视雄啊,哈哈。
这⾥还介绍⼀下jieba库,这个库可以针对⽂本进⾏词义判断,从⽽进⾏划分,常常和wordcloud配合使⽤。import jieba
seg_list = jieba.cut("他来到上海交通⼤学", cut_all=False)
print("【精确模式】:" + "/ ".join(seg_list))
另外说⼀句,本期博客是markdown编写的,格式确实相当不错呢!
java程序设计任务驱动实训教程