在上一次用pandas做数据分析、matplotlib实现可视化的任务中,主要对于“价格”信息做了简单的处理,了解到赣州地区房价水平的范围,各区县的房价水平,根据自己的预算大致可以确定一些楼盘目标作为备选。然而,买房要考虑的不仅仅是价格,房子所处地段及位置背后包含的丰富信息更为重要,好的地段也决定了房子升值空间。

那怎么分析像地址这种地理信息呢?我习惯使用高德地图搜索一下,很方便地了解楼盘及其周边的地理信息。当数据量很大,或者希望在地图上呈现价格等信息时,就需要实现地图的海量标点,自己完成比较困难,但是可以利用python在资源调用的优势,借助百度地图开放的能力实现这一目的。

下面这个任务,将调用百度地图API的功能把爬取的“地址”信息通过地图及标点的方式呈现出来,先上完成效果图:

一、方案和步骤

前两次任务更多的是为了熟悉requests、bs4、pandas、matploylib等函数库而产生的,这一次是先有需求再希望通过python来完成,所以把方案策划部分放在最前面:该怎么把地址文本信息转换成地图上的标点呢?为此,我上网搜索了一些教程:

  • 感谢 《利用python和百度地图API实现数据地图标注》 的作者(网上转载版本太多,都不知道原创是谁了),知道可以在百度地图上海量标点,需要获取到经纬度坐标;
  • 感谢廖sir的博客《python实现百度地图API获取某地址的经纬度》,知道可以调用百度地图API从地址文本信息转换到经纬度坐标;

所以步骤明确如下:

第一步,调用百度地图API把详细地址转换成经纬度坐标信息,并保存;

第二步,把经纬度坐标+楼盘名+价格等信息转换成百度地图HTML可以看懂的格式;

第三步,把百度地图“加载海量点”的html代码中的“标点”变量信息替换成我们的信息,输出地图网页

首先,访问百度地图开放平台,右上角“控制台”——“个人信息”——“认证个人开发者”——“认证成功”——“控制台”——左边菜单列表“应用管理”——“我的应用”——创建应用,可以看到下面的页面:

填写页面名称,选择应用类型和服务(这次任务会用到的是地理编码),请求校验方式我借鉴廖sir的博客选择sn校验方式,点击“提交后”,会得到一个ak码,因为选择sn校验还会有一个sk码。

地理编码:
http://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation //GET请求


地理编码服务的详情可以访问百度地图官方介绍,实操部分会讲解怎么调用,其他不过多赘述。

二、函数库准备

首先需要导入此次任务需要用到的函数库:pandas、json、urllib、hashlib。

import pandas as pd       # 表格型数据处理很方便
import json               # 处理json格式的文件,读取、写入、保存等
import urllib             # 处理网址url型数据
import hashlib            # 哈希算法、摘要算法,把中文转换成一个字符串便于计算机读懂
  • json:处理json格式文件的库,json是一种通用的数据类型,是目前Web主流的数据交换格式。

  • urllib:因为地理编码的调用需要通过一个url来请求,要访问不同地址,url里的‘address’参数需要改变,所以用urllib这个包来处理url数据。

  • hashlib:其中有个hashlib,听起来很深奥是不是,想进一步了解的可以自行学习,这里用到它主要是需要把url里的中文字符转换成服务器能看的懂的数据,而哈希算法可以通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)

三、实际操作

(一)把地址转换为经纬度坐标

  1. 把你生成的ak、sk填写到提示位置
  2. !!!!!……!!!!!内替换成你的数据文件
  3. 我测试了爬取来的1)“地址”原始数据、2)“楼盘名”、3)“赣州”+“地址”+“楼盘名”去找到他们的经纬度坐标,测试结果表明:准确度上,楼盘名优于地址(有可能是网站的地址信息本来就比较模糊),信息越细获取的经纬度越准确。
# 定义一个调用百度地图API地理编码的函数
def getlnglat(address):baidu_aqi_url = 'http://api.map.baidu.com'output = 'json'ak = 你的ak密钥  # 百度地图自行创建的应用ak,自行填写sk = 你的sk密钥  # 百度地图api选择sn校验方式是会生成这个sk码,自行填写# 生成sn码,因为百度地图api设置时选择“请求校验方式”为sn校验方式queryStr = '/geocoding/v3/?address=' + address + '&output='+output+'&ak=' + akencodedStr = urllib.parse.quote(queryStr, safe="/:=&?#+!$,;'@()*[]")    # 因为地址是中文字符串,在网址中需要转换编码,safe内的保留字符不转换rawStr = encodedStr + sk#用哈希算法生成sn码sn = (hashlib.md5(urllib.parse.quote_plus(rawStr).encode("utf8")).hexdigest())# 生成urlurl = urllib.parse.quote(baidu_aqi_url+queryStr+"&sn="+sn, safe="/:=&?#+!$,;'@()*[]")req = urllib.request.urlopen(url)      # urllib.request.urlopen()函数用于实现对目标url的访问,因为直接导入了urlopen模块,故直接使用。res = req.read().decode()try:                                   # try语句做异常处理temp = json.loads(res)print(json.dumps(temp, indent=4, ensure_ascii=False))lat = temp['result']['location']['lat']lng = temp['result']['location']['lng']print('{}的纬度为{},经度为{}'.format(address, lat, lng))except:lat = Nonelng = Nonereturn lat, lng  # 纬度 latitude   ,   经度 longitude  ,def main():"""主函数"""# !!!!!把括号里的文件名替换成你的文件名!!!!!newhouse_price_data = pd.read_csv('ganzhou_newhouse_current_price.csv',encoding='GBK')# 数据清洗,可以把没有具体价格的新房信息剔除,表里混入了两个鹰潭市的数据,通过drop删去newhouse_price_data.drop([105, 108],axis=0,inplace=True)                    # inplace代表是否真正删去# 增加列名为纬度和经度的两个新列,填充NaN值location_data = newhouse_price_data.reindex(columns = ['楼盘名','区县','地址','纬度','经度','价格'],fill_value = None) # reindex()方法同时添加多列,用columns属性定义列名,及列的位置,fill_value默认补充添加列的值for index in location_data.index:address = '赣州市'+newhouse_price_data.loc[index,'地址']+newhouse_price_data.loc[index, '楼盘名']# 调用上面定义的getlnglat函数get_location = getlnglat(address)get_lat = get_location[0]get_lng = get_location[1]location_data.loc[index,'纬度'] = get_latlocation_data.loc[index,'经度'] = get_lng# !!!!!把括号里的文件名替换成你的文件名!!!!!location_data.to_csv('new_location_of_real_state_ganzhou_v2.csv',mode = 'w',index = False,encoding='GBK')if __name__ == '__main__':main()

(二)生成百度地图“加载海量点”的数据格式,包含所需信息经纬度、楼盘名、价格。

location_data_html = pd.DataFrame(columns=['content'])for index in location_data.index:location_data_html.loc[index, 'content'] = "{" + \"'lat':" + str(location_data.loc[index, "纬度"]) + "," + \"'lng':" + str(location_data.loc[index, "经度"]) + "," + \"'quyu':" + "'" + str(location_data.loc[index, "楼盘名"])+"'" + "," +\"'jiage':" + "'" + str(location_data.loc[index, "价格"])+"'" +"}" + ","location_data_html.to_csv("real_state_data_html_v2.csv", encoding="GBK",index = False)

(三)替换百度地图“加载海量点”代码,通过网页查看结果
打开百度地图开放平台“加载海量点”示例,看到如下页面内容:

打勾处就是我们需要的html代码了,把代码全选复制,在pycharm里新建一个“HTML File”,粘贴。

根据我们的需要,我们可以修改代码里的内容:

  1. 修改标题:把title行的文字改成“赣州在售新房分布”;

  2. 把“你的密钥”替换成你生成的ak码。(敲黑板、划重点!因为结果需要通过网页显示,这里我们需要在百度地图开放平台的控制台新创建一个应用类型为“浏览器”的应用,使用Javascript API服务,见下图。这里校验方式只能选择白名单,我填写的是“*”(半角),不限制。

  3. 根据你获取到的坐标确定地图的中心点(打开默认是以中心点为中心的地图画面),后面的参数“5”表示地图规格大小,说白了数字越大街道、店铺等信息越容易显示,这里我修改参数为“12”,查看结果是可以放大缩小,所以可随意修改。

  4. 最重要的部分,把蓝框圈起来的部分删去(示例中密密麻麻的海量点),把第二步生成的数据粘贴至此处,细节见下图红框处:

    注意两点,第二步生成的数据,花括号{……}前后有引号删去,最后一个数据行后的逗号不要复制到。
    图中的“var options”、“function(e)”(表示click时发生的动作函数)都是可以修改的。
    我这里把shape修改为’circle‘,圆点,把function修改为点击显示”楼盘名,房价为<价格>“。

        ];  // 添加海量点数据var options = {size: BMAP_POINT_SIZE_SMALL,shape: BMAP_POINT_SHAPE_CIRCLE,color: '#d340c3'}var pointCollection = new BMap.PointCollection(points, options);  // 初始化PointCollectionpointCollection.addEventListener('click', function (e) {alert(e.point.quyu + ',房价为:' + e.point.jiage);  // 监听点击事件});

四、查看结果

确认没有语法、缩进格式错误后,可以在pycharm内右键浏览器打开:

结果如下图,就可以很方便地查看楼盘所处地段了:

老规矩,全部代码如下:
part 1:python file

# 定义一个调用百度地图API地理编码的函数
def getlnglat(address):baidu_aqi_url = 'http://api.map.baidu.com'output = 'json'ak = 你的ak密钥  # 百度地图自行创建的应用ak,自行填写sk = 你的sk密钥  # 百度地图api选择sn校验方式是会生成这个sk码,自行填写# 生成sn码,因为百度地图api设置时选择“请求校验方式”为sn校验方式queryStr = '/geocoding/v3/?address=' + address + '&output='+output+'&ak=' + akencodedStr = urllib.parse.quote(queryStr, safe="/:=&?#+!$,;'@()*[]")    # 因为地址是中文字符串,在网址中需要转换编码,safe内的保留字符不转换rawStr = encodedStr + sk#用哈希算法生成sn码sn = (hashlib.md5(urllib.parse.quote_plus(rawStr).encode("utf8")).hexdigest())# 生成urlurl = urllib.parse.quote(baidu_aqi_url+queryStr+"&sn="+sn, safe="/:=&?#+!$,;'@()*[]")req = urllib.request.urlopen(url)      # urllib.request.urlopen()函数用于实现对目标url的访问,因为直接导入了urlopen模块,故直接使用。res = req.read().decode()try:                                   # try语句做异常处理temp = json.loads(res)print(json.dumps(temp, indent=4, ensure_ascii=False))lat = temp['result']['location']['lat']lng = temp['result']['location']['lng']print('{}的纬度为{},经度为{}'.format(address, lat, lng))except:lat = Nonelng = Nonereturn lat, lng  # 纬度 latitude   ,   经度 longitude  ,def main():"""主函数"""# !!!!!把括号里的文件名替换成你的文件名!!!!!newhouse_price_data = pd.read_csv('ganzhou_newhouse_current_price.csv',encoding='GBK')# 数据清洗,可以把没有具体价格的新房信息剔除,表里混入了两个鹰潭市的数据,通过drop删去newhouse_price_data.drop([105, 108],axis=0,inplace=True)                    # inplace代表是否真正删去# 增加列名为纬度和经度的两个新列,填充NaN值location_data = newhouse_price_data.reindex(columns = ['楼盘名','区县','地址','纬度','经度','价格'],fill_value = None) # reindex()方法同时添加多列,用columns属性定义列名,及列的位置,fill_value默认补充添加列的值for index in location_data.index:address = '赣州市'+newhouse_price_data.loc[index,'地址']+newhouse_price_data.loc[index, '楼盘名']# 调用上面定义的getlnglat函数get_location = getlnglat(address)get_lat = get_location[0]get_lng = get_location[1]location_data.loc[index,'纬度'] = get_latlocation_data.loc[index,'经度'] = get_lng# !!!!!把括号里的文件名替换成你的文件名!!!!!location_data.to_csv('new_location_of_real_state_ganzhou_v2.csv',mode = 'w',index = False,encoding='GBK')"""生成html需要的坐标信息"""location_data_html = pd.DataFrame(columns=['content'])for index in location_data.index:location_data_html.loc[index, 'content'] = "{" + \"'lat':" + str(location_data.loc[index, "纬度"]) + "," + \"'lng':" + str(location_data.loc[index, "经度"]) + "," + \"'quyu':" + "'" + str(location_data.loc[index, "楼盘名"])+"'" + "," +\"'jiage':" + "'" + str(location_data.loc[index, "价格"])+"'" +"}" + ","location_data_html.to_csv("real_state_data_html_v2.csv", encoding="GBK",index = False)if __name__ == '__main__':main()

part 2:HTML file

作者:Michel
功能:调用百度地图api实现地图标点
版本:1.0
日期:2020/3/19<!DOCTYPE HTML>
<html>
<head><title>赣州在售新房分布图</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"><style type="text/css">html,body{margin:0;width:100%;height:100%;background:#ffffff;}#map{width:100%;height:100%;}#panel {position: absolute;top:30px;left:10px;z-index: 999;color: #fff;}#login{position:absolute;width:300px;height:40px;left:50%;top:50%;margin:-40px 0 0 -150px;}#login input[type=password]{width:200px;height:30px;padding:3px;line-height:30px;border:1px solid #000;}#login input[type=submit]{width:80px;height:38px;display:inline-block;line-height:38px;}</style><script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=你的密钥"></script><script type="text/javascript" src="/jsdemo/data/points-sample-data.js"></script>
</head>
<body><div id="map"></div><script type="text/javascript">var map = new BMap.Map("map", {});                        // 创建Map实例map.centerAndZoom(new BMap.Point(114.9548132, 25.72821081), 12);     // 初始化地图,设置中心点坐标和地图级别map.enableScrollWheelZoom();                        //启用滚轮放大缩小if (document.createElement('canvas').getContext) {  // 判断当前浏览器是否支持绘制海量点var points = [
{'lat':25.87060199249849,'lng':114.91570502057392,'quyu':'新力.帝泊湾','jiage':'10000'},
……
{'lat':25.710305687085405,'lng':114.8102956961347,'quyu':'赣州灯饰城','jiage':'7600'}];  // 添加海量点数据var options = {size: BMAP_POINT_SIZE_SMALL,shape: BMAP_POINT_SHAPE_CIRCLE,color: '#d340c3'}var pointCollection = new BMap.PointCollection(points, options);  // 初始化PointCollectionpointCollection.addEventListener('click', function (e) {alert(e.point.quyu + ',房价为:' + e.point.jiage);  // 监听点击事件});map.addOverlay(pointCollection);  // 添加Overlay} else {alert('请在chrome、safari、IE8+以上浏览器查看本示例');}</script>
</body>
</html>

(三)爬取新房销售信息——位置坐标转换+地图标点可视化篇相关推荐

  1. (二)爬取新房销售信息——数据分析+可视化篇

    pandas & matplotlib 用于数据分析和可视化 上一个任务通过requests.BeautifulSoup4两个功能强大.用法简洁的函数库已经获取到了楼盘名.地址和价格这些新房信 ...

  2. Python实现淘宝爬取——奶粉销售信息爬取及其数据可视化

    简介 双十一刚过,TB的销售额又创下了新高,我也为2000+亿做出了贡献 恰巧买了一袋德运奶粉,味道还不错.我就在想,接触爬虫也有两个多月了,还没有爬过TB这种经典的网站,借着劲头就爬取了一下TB上奶 ...

  3. 1分钟爬取全国高校信息,制成大屏可视化!

    记得当初高考完,我选学校的时候是在书店买的高校信息排名的书,然而书中的信息都是很久之前的,并没有什么太大帮助.今天就来带大家爬点真正有用的东西,全国高校信息,涵盖绝大多数高校,并制作可视化看板.话不多 ...

  4. 其实特简单,1分钟爬取全国高校信息并制成大屏可视化

    大家好,记得当初高考完,我选学校的时候是在书店买的高校信息排名的书,然而书中的信息都是很久之前的,并没有什么太大帮助. [注]文末提供技术交流群 干货推荐 深度盘点:这20套可视化炫酷大屏真香啊(附源 ...

  5. 爬取51job职位信息--进行专业市场需求可视化分析(python、tableau、DBeaver)

    爬取51job信管专业相关岗位的情况进行可视化分析. 采用工具:python.tableau(可视化).DBeaver(数据库管理软件) 文章目录 一.数据爬取 1.1导入相关的库 1.2对每个岗位搜 ...

  6. 什么你还不知道招聘信息,小唐来教你——最新2021爬取拉勾网招聘信息(二)

    文章目录 前言 一.准备我们的库 二.数据清洗 三.核密度图及词云制作 四.完整代码 五.扩展 上一篇:什么你还不知道招聘信息,小唐来教你--最新2021爬取拉勾网招聘信息(一) 下一篇:没有拉! 前 ...

  7. 2021最新 python爬取12306列车信息自动抢票并自动识别验证码(三)购票篇

    项目前言 tiebanggg又来更新了,项目--[12306-tiebanggg-master]注:本项目仅供学习研究,如若侵犯到贵公司权益请联系我第一时间进行删除:切忌用于一切非法途径,否则后果自行 ...

  8. [Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(三) —— 数据的持久化——使用MongoDB存储爬取的数据

    上一篇:[Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(二) -- 编写一个基本的 Spider 爬取微博用户信息 在上一篇博客中,我们已经新建了一个爬虫应用,并简单实现了爬取一位微 ...

  9. python爬取微博用户信息(三)—— 创建MicroBlog类实例

    这一节,主要讲述 main.py文件,该文件创建了一个MicroBlog类,MicroBlog类中包含一些爬取微博内容的函数. 以及简单介绍traceback的用法. 感兴趣的小伙伴可以收藏哦! 另外 ...

最新文章

  1. 云计算灾备原理与预防恢复方案
  2. Python 办公自动化,一键给PDF文件加密,超方便
  3. 张勇:做一个透明经济体的CEO
  4. PC 远程控制 android手机的方法之一VNC
  5. mysql insert replace_mysql 操作总结 INSERT和REPLACE
  6. java开发实战经典
  7. DataGrid使用心得(附大量代码)
  8. convenient functions in numpy
  9. 运用.NET Framework中的类来创建看上去很专业的报表。
  10. java服务端验证框架_SpringBoot服务端数据校验过程详解
  11. 递归算法经典实例小结(C#实现)
  12. C盘扩容好帮手——傲梅分区助手
  13. 俞军:百度首席产品架构师
  14. python简单网格五子棋_python实现简单五子棋游戏
  15. VideoPlayer视频播放
  16. Codeforces Round #828 (Div. 3)-赛后总结
  17. 2023江苏大学计算机考研信息汇总
  18. 如何看待自己正在遭受的挫折?
  19. 国外数藏动态:7月6日至10日即将发售的藏品
  20. NTIRE2021 视频超分竞赛简要回顾

热门文章

  1. openstack 使用iscsi连接网盘并提供cinder存储服务
  2. 盘点最令人难忘的十大谍战剧经典
  3. java反射类型转换_Java反射探索研究(转)
  4. 2017年乌镇互联网大会嘉宾分享要点实录
  5. 使用AWS最便宜的GPU实例  from 动手学深度学习v2 李沐大神
  6. clickhouse集群搭建
  7. vue+mysql实现前端对接数据库
  8. linux下git和github搭建使用教程
  9. 补助方针收紧,意在倒逼新能源汽车?
  10. 求职应聘面试常见问题回答技巧