作者: 国服帅座
爬虫三步走,或者三步骤,或者三部曲,爱咋叫咋叫。
第一步,爬取单个数据;第二步,整合为函数;第三步,for循环大批量处理。
爬取经纬度有许多种方式,可以用Python或R调用高德(百度)地图API,不过这样略显复杂。本文重点展现爬虫的三个步骤,因而将爬取经纬度的难度降低,利用R语言中的 baidumap 包。虽然形式有所简化,但实质还是百度地图API在起作用。
1.爬取单个数据
library(jsonlite)library(stringr)# library(devtools) # 在github上下载baidumap包# install_github('badbye/baidumap',force=TRUE)library(baidumap) options(baidumap.key = '你的百度密钥') # 百度密钥
首先,我们要加载爬虫所用的包。此处用到的是 baidumap 包,使用该包需要输入你的百度密钥,提前申请一下。此外,还会用到的是 jsonlite 包,这个包的作用是将 json 格式的数据转化为R语言可以处理的数据;stringr包本身与爬虫无关,但是下面需要用它连接字符串。
data = getCoordinate('启东市') # 以江苏省启东市为例data
getCoordinate 是 baidumap 包中的一个重要函数,参数是地名。
由于是爬取单个数据,此处便以江苏省启东市为例。
得出的结果中包括众多参数,其中明显包括了经度和纬度。由于 data 输出的内容是 json 格式的,R语言没法直接提取经纬度,这时候需要仰仗 jsonlite 包中的 fromJSON 函数了。
df = fromJSON(data)df = as.data.frame(df)dfmode(df)
这里得到的 df 是列表格式,一个键对应着一个值。虽然经度和纬度是分开来的,但是我们希望二者能够写到一起,并用逗号分开。
longitude = df$result.location.lnglatitude = df$result.location.latcoords = str_c(longitude, ',', latitude) # 将经纬度连接起来coords
结果显示,启东市经纬度如上。
2.整合为函数
为什么要将第一步的过程整合为一个函数呢?这是为下一步的for循环服务的。上一步中的启东市只是一个个例,但爬虫的意义在于大批量处理,从第一步到第三步,是由特殊走向一般的过程,而第二步则是桥梁。所谓特殊到一般,也就是常量到变量,这个变量就是自变量。我们希望构建一个函数,这个函数自变量的位置上,不仅仅是启东市,还可以是许多其他的地方。
# 下面设置函数coords = function(i) {
data = getCoordinate(i)
df = as.data.frame(fromJSON(data)) # 将json格式转化为R的格式
longitude = df $ result.location.lng
latitude = df $ result.location.lat
return (str_c(longitude, ',', latitude)) # 整合经度和纬度 }
这里的 i 就是自变量,替代了之前步骤中的启东市。
把启东市作为自变量代入,所得结果同上。说明该函数是正确的。
address1 = coords('启东市') # 获得启东市坐标address2 = coords('乌鲁木齐市') # 获得乌鲁木齐市坐标address1; address2
3.for循环大批量处理
也许你要大批量获得许多城市的经纬度,这些地名都在一张Excel表上。我在此处举了个例子,这张叫“城市名示例.xlsx”的表上只有一个字段,包括10个城市名。如果有100个城市,操作流程是一样的。
library(openxlsx)table = read.xlsx('城市名示例.xlsx',1) # 打开工作目录中该Excel文件的第一张表city = unlist(table['城市']) # R列表类似于Python字典,没法索引,故先unlist# View(city)result = list() # 个人理解:R列表类似于Python字典,根据键来取值for (i in 1:length(city)) {
location = coords(city[i])
result[city[i]] = location # 列表中一个城市名对应一个坐标}result# 下面无非是一些格式的调整罢了# View(result)result2 = as.data.frame(result) # 此时可导出,但要在excel中转置# View(result2)result3 = t(result2) # 在R中先将其转置,但导出后无城市名# View(result3)result4 = cbind(rownames(result3),result3) # 将转置后的行名作为一列添入数据框# View(result4)write.xlsx(result4,'城市坐标.xlsx') # 将结果输出
在新文件“城市坐标.xlsx”中,显示结果如下:
将V1和V2修改为“城市”和“坐标”即可。