1,关于本Notebook 刚刚过去的这个周末,有用户问能否获取安居客小区的经纬度。之前我们发布过几个案例,介绍了怎样通过GooSeeker采集获取和地理位置名相关的微博签到位置数据,然后在Jupyter Notebook中获取签到地的经纬度: 2. Jupyter Notebook怎样获取微博签到地的经纬度并在地图上显示 今天这个Notebook演示怎样基于安居客二手房小区列表快捷采集结果excel,得到实际的小区经纬度。 基本原理很简单:在网站上并没有经纬度信息,但是可以用网络爬虫采集到详细的地址信息,那么可以使用地图api,将地址信息翻译成经纬度。为了便于使用,我们把调用地图api的过程用notebook实现了,如果读者想用于其他场景,修改一下notebook的代码部分即可。 1.1,使用的数据表 本Jupyter Notebook使用安居客二手房小区列表快捷采集采集得到的结果表:temp_安居客二手房小区列表_规则1二手房小区列表_2021xxxxxxxxxxx.xlsx。 1.2,数据采集 见之前已发布的1篇文章: 如何使用快捷采集-以安居客房源采集为例 该文讲解采集安居客房源,与本文要采集的安居客二手房小区列表的方法是基本一样的。 1.3,本模板适应的场景 本模板根据安居客二手房小区列表快捷采集采集得到的结果表:temp_安居客二手房小区列表_规则1二手房小区列表_2021xxxxxxxxxxx.xlsx,对数据进行基本处理后,调用百度api获取每个小区的经纬度。 1.4,使用方法 基本操作顺序是: 1. 把安居客二手房小区列表快捷采集采集得到的结果表:temp_安居客二手房小区列表_规则1二手房小区列表_2021xxxxxxxxxxx.xlsx, 放在本notebook的data/raw文件夹中 2. 从头到尾执行本notebook的单元 注意:每个notebook项目目录都预先规划好了,具体参看Jupyter Notebook项目目录规划参考。如果要做多个分析项目,把整个模板目录专门拷贝一份给每个分析项目。 1.5,简要技术说明 在每个功能项单元,如果不需要关心的编程细节,将注明【编程细节】。 本notebook主要实现以下几个步骤: 1. 读取data/raw文件夹中的安居客二手房小区列表采集结果文件:temp_安居客二手房小区列表_规则1二手房小区列表_2021xxxxxxxxxxx.xlsx 2. 对数据表进行基本的预处理 3. 调用百度api获取每个小区的经纬度 2,第三方库 无 3,数据源 数据源是安居客二手房小区列表快捷采集采集得到的结果表:temp_安居客二手房小区列表_规则1二手房小区列表_2021xxxxxxxxxxx.xlsx。供参考和实验。 4,修改历史 2021-07-19:第一版发布 5,版权说明 本notebook是GooSeeker大数据分析团队开发的,本notebook中的代码可自由共享使用,包括转发、复制、修改、用于其他项目中。 6,准备程序环境 导入必要的Python程序包,设定要分析的文件名变量: file_garden_list:小区列表 【编程细节】本节下面的代码将对上述词频表名变量赋值 import pandas as pd import os import requests import time %xmode Verbose import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # 存原始数据的目录 raw_data_dir = os.path.join(os.getcwd(), '..\\..\\data\\raw') # 存处理后的数据的目录 processed_data_dir = os.path.join(os.getcwd(), '..\\..\\data\\processed') filename_temp = pd.Series(['安居客二手房小区列表']) file_garden_list = '' 7,检测data\raw目录下是否有安居客二手房小区表 temp_安居客二手房小区列表_规则1二手房小区列表_2021xxxxxxxxxxx.xlsx是将要被分析的数据表,应该预先放在data/raw文件夹。下面的代码将检查是否有excel文件,如果有,给文件名变量赋值。 # 0:'词频', 1:'分词效果', 2:'选词矩阵', 3:'选词匹配', 4:'选词结果', 5:'共词矩阵' print(raw_data_dir + '\r\n') for item_filename in os.listdir(raw_data_dir): if filename_temp[0] in item_filename: file_garden_list = item_filename continue if file_garden_list: print("小区列表采集excel表:", "data\\raw\\", file_garden_list) else: print("小区列表采集excel表:不存在") 输出结果 C:\Users\work\workspace_219\notebook\Jupyter Notebook怎样获取安居客二手房小区经纬度\notebook\eda\..\..\data\raw 小区列表采集excel表: data\raw\ temp_安居客二手房小区列表_规则_1_二手房小区列表_20210719101549421.xlsx 8,读取安居客小区列表结果表 以下的演示以安居客二手房小区列表快捷采集采集得到的结果表:temp_安居客二手房小区列表_规则1二手房小区列表_2021xxxxxxxxxxx.xlsx为例, 需要把结果表放在本notebook的data/raw文件夹中 df = pd.read_excel(os.path.join(raw_data_dir, file_garden_list)) 9,查看安居客小区列表结果表原始数据 df.head(10) 10,数据预处理 按已经做的测试,如果直接把“北京”或者“碧桐园”发给百度api,会查不到这个地点。 但是发“北京市”或者“北京市中环荣域”就可以查到。 所以需要对数据做预处理。 10.1,规范地址名称 1. 在城市名称后面加个“市” 2. 把城市名添加到小区名称前 for idx,row in df.iterrows(): df.loc[idx,"城市"] = df.loc[idx,"城市"] + "市" df.loc[idx,"小区"] = df.loc[idx,"城市"] + df.loc[idx,"小区"] 10.2,显示替换后的数据 df.head(10) 10.3,在dataframe的最后增加一列:经纬度 df["经纬度"] = "" 10.4,定义获取经纬度数据的函数 #定义获取经纬度的函数,供后面调用 def is_json(myjson): try: json_object = json.loads(myjson) except: return False return True def geocodeB(address): """ @ address: 名称字符串 @ 返回值:经度,纬度 """ #base_url = "http://api.map.baidu.com/geocoder?address={address}&output=json&key=AK直接粘贴在这里".format(address=address) base_url = "http://api.map.baidu.com/geocoder?address={address}&output=json".format(address=address) response = requests.get(base_url) #time.sleep(1) try: answer = response.json() latitude = answer['result']['location']['lng'] longitude = answer['result']['location']['lat'] return str(latitude) + "," + str(longitude) except: return "" 10.5,获取经纬度数据 for idx,row in df.iterrows(): if len(str(df.loc[idx,"小区"])) > 0: df.loc[idx,"经纬度"] = geocodeB(df.loc[idx,"小区"]) print(idx, df.loc[idx,"小区"], df.loc[idx,"经纬度"]) #if idx > 20: # break 10.6,显示获取了经纬度后的数据 df.head(10) 10.7,把签到地点按经纬度标注到地图上 from pyecharts.faker import Faker from pyecharts import options as opts from pyecharts.charts import Geo from pyecharts.globals import ChartType, SymbolType, GeoType import pandas as pd import json lldata = [] count = [] for idx,row in df.iterrows(): if (len(df.loc[idx,"经纬度"]) > 0 and df.loc[idx,"小区"] != 'nan'): newrecord = (df.loc[idx,"小区"] ,df.loc[idx,"经纬度"].split(",")[0], df.loc[idx,"经纬度"].split(",")[1] ) lldata.append(newrecord) count.append(1) def add_adress_json(lldata) -> Geo: # http://api.map.baidu.com/geocoder?key=f247cdb592eb43ebac6ccd27f796e2d2&output=json&address= #test_data_ = [("测试点1", 116.512885, 39.847469), ("测试点2", 125.155373, 42.933308), ("测试点3", 87.416029, 43.477086)] #count = [1000, 2000, 500] address_ = [] json_data = {} for ss in range(len(lldata)): json_data[lldata[ss][0]] = [lldata[ss][1], lldata[ss][2]] address_.append(lldata[ss][0])
json_str = json.dumps(json_data, ensure_ascii=False, indent=4) with open('test_data.json', 'w', encoding='utf-8') as json_file: json_file.write(json_str)
c = ( Geo() .add_schema(maptype="china") # 可以换成 world,或 china .add_coordinate_json(json_file='test_data.json') # 加入自定义的点 # 为自定义的点添加属性 #.add("", data_pair =[list(z) for z in zip(address_, count)], symbol_size = 30, large_threshold = 2000, symbol="pin") .add('',data_pair =[list(z) for z in zip(address_, count)], type_=GeoType.EFFECT_SCATTER, symbol_size=10) .set_series_opts(label_opts=opts.LabelOpts(is_show=False)) .set_global_opts( visualmap_opts=opts.VisualMapOpts(max_ = 2000),title_opts=opts.TitleOpts(title="")) ) return c
add_json = add_adress_json(lldata) #add_json.render(path="test_json.html") add_json.render_notebook() 11,下载本Jupyter Notebook 下载源代码请进入:根据二手房地址查到经纬度并标记到地图上 |