脚本实现功能:根据能访问到的非影像图服务地址,爬取矢量数据。
本机环境:ArcGIS10.8,Python27
服务数据下载有arcgis版本要求,高于10.5的arcgis在服务数据里有中文时不会报错。
import urllib2
import urllib
import os
import arcpy
import time
import sys
# 输入参数分为四个,保存数据和工作空间的路径folder,服务的ip地址(带端口),服务的名称(带文件夹名称),保存数据的gdb和合并数据的元要素类名称
def download(folder,ip,serviceName,dataName):
arcpy.env.workspace = folder
date = time.strftime("%Y%m%d_%H%M%S", time.localtime())
# service url
url = "http://{0}/arcgis/rest/services/{1}/MapServer/0/query?".format(ip,serviceName)
# 创建一个gdb,新建的数据都会在gdb里面执行操作。不使用shp的原因是一些服务里会包含注记,注记无法保存在shp里。
arcpy.CreateFileGDB_management(folder, '{1}_{0}.gdb'.format(date,dataName))
gdb = folder + '/{1}_{0}.gdb'.format(date,dataName)
# OBJECTID = 1
# 设定只获取一条数据的参数,这一条数据是作为基础数据来做使用。
paramsSample = urllib.urlencode({'where':'OBJECTID = 1',
'geometryType': 'esriGeometryEnvelope',
'spatialRel': 'esriSpatialRelIntersects',
'relationParam': '',
'outFields': '*',
'returnGeometry': 'true',
'geometryPrecision':'',
'outSR': '',
'returnIdsOnly': 'false',
'returnCountOnly': 'false',
'orderByFields': '',
'groupByFieldsForStatistics': '',
'returnZ': 'false',
'returnM': 'false',
'returnDistinctValues': 'false',
'f': 'pjson'})
# 创建一个请求并使用 urllib 读取它
requestSample = urllib2.Request(url, paramsSample)
responseSample = urllib2.urlopen(requestSample)
jsonSample = responseSample.read()
#设置写入的json文件路径和名称,转出为要素类的路径和名称
mapservice_jsonSample = folder + '/mapservice.json'
mapservice_shpSample = gdb + '/{0}'.format(dataName)
# 将JSON响应写入文本文件
with open(mapservice_jsonSample, "wb") as ms_jsonSample:
ms_jsonSample.write(jsonSample)
# JSON文件转为要素类
arcpy.JSONToFeatures_conversion(mapservice_jsonSample, mapservice_shpSample)
# cursor更新,清空仅有的一行数据
cursor = arcpy.UpdateCursor(mapservice_shpSample)
for row in cursor:
cursor.deleteRow(row)
os.remove(mapservice_jsonSample)
# 部分server服务发布时会默认设置返回数据记录数量为1000条,因此按照1000为单位,循环更新参数来爬取json,再转为要素类后合并到之前清空的要素类里。
# OBJECTID > 0 and OBJECTID <= 1000
a = 1
while a:
b = (a-1)*1000
c = a*1000
# 设置sql语句
where_clase = 'OBJECTID > {0} and OBJECTID <= {1}'.format(b,c)
print where_clase
params = urllib.urlencode({'where': where_clase,
'geometryType': 'esriGeometryEnvelope',
'spatialRel': 'esriSpatialRelIntersects',
'relationParam': '',
'outFields': '*',
'returnGeometry': 'true',
'geometryPrecision':'',
'outSR': '',
'returnIdsOnly': 'false',
'returnCountOnly': 'false',
'orderByFields': '',
'groupByFieldsForStatistics': '',
'returnZ': 'false',
'returnM': 'false',
'returnDistinctValues': 'false',
'f': 'pjson'})
request = urllib2.Request(url, params)
response = urllib2.urlopen(request)
json = response.read()
mapservice_json = folder + '/mapservice{0}.json'.format(a)
mapservice_shp = gdb + '/mapservice{0}'.format(a)
with open(mapservice_json, "wb") as ms_json:
ms_json.write(json)
arcpy.JSONToFeatures_conversion(mapservice_json, mapservice_shp)
# 设置一个循环停止,统计转出的要素类的数据量,不为0继续,为0则跳出循环
result = arcpy.GetCount_management(mapservice_shp)
count = int(result.getOutput(0))
print count
if count != 0:
# json转出的要素类合并到上面清空的要素类里
arcpy.Append_management(mapservice_shp, mapservice_shpSample, "NO_TEST")
arcpy.Delete_management(mapservice_shp)
os.remove(mapservice_json)
a += 1
else:
arcpy.Delete_management(mapservice_shp)
os.remove(mapservice_json)
break
if __name__ == '__main__':
input1 = sys.argv[1]
input2 = sys.argv[2]
input3 = sys.argv[3]
input4 = sys.argv[4]
download(input1,input2,input3,input4)