在使用urllib向在线api发送多个循环请求方面寻求帮助。
我目前正在处理一些Python脚本,以帮助我们确定雷达与拟议中的风力涡轮机开发之间的潜在视线问题。
最后一个难题是创建一个高度剖面,以便我们可以快速评估哪些涡轮机可能是问题,哪些不是问题。我一直在尝试操纵here中发现的现有代码来查询我已经签名并拥有密钥的OpenElevation API。
以前,我曾尝试将从GIS软件中提取的高程数据解析为.xyz文件。但是,这很耗时,提取的高程仅精确到小数点后三位。
该代码从radars.csv
中读取,然后将该雷达与每个单独的涡轮机配对,发送视线请求。不幸的是,当我反复遇到connection forcibly closed
或gateway time-out
错误返回时,我想一定是在轰炸服务器。
import csv
import math
import urllib.request
import json
import matplotlib.pyplot as plt
##Extract data from radar and turbine csv files##
with open('readfiles/radars.csv') as csvfile: #get radar data
reader = csv.reader(csvfile, delimiter=',')
for row in reader:
#START-END POINT
P1=[]
P2=[]
radarlong=(float(row[0])) #convert to correct data types
radarlat=(float(row[1]))
radarheight=(int(row[2]))
radarname=(row[3])
P1.append(radarlong)
P1.append(radarlat)
##Open windfarm csv and store variables
with open('readfiles/windfarms.csv') as csvfile: #get windfarm data
reader = csv.reader(csvfile, delimiter=',')
for row in reader:
windfarmlong = (float(row[0])) #convert to correct data types
windfarmlat = (float(row[1]))
windfarmheight = (int(row[2]))
windfarmname = (row[3])
P2=[windfarmlong, windfarmlat]
print(P1, P2)
#NUMBER OF POINTS
s=100
interval_lat=(P2[0]-P1[0])/s #interval for latitude
interval_lon=(P2[1]-P1[1])/s #interval for longitude
#SET A NEW VARIABLE FOR START POINT
lat0=P1[0]
lon0=P1[1]
#LATITUDE AND LONGITUDE LIST
lat_list=[lat0]
lon_list=[lon0]
#GENERATING POINTS
for i in range(s):
lat_step=lat0+interval_lat
lon_step=lon0+interval_lon
lon0=lon_step
lat0=lat_step
lat_list.append(lat_step)
lon_list.append(lon_step)
#HAVERSINE FUNCTION
def haversine(lat1,lon1,lat2,lon2):
lat1_rad=math.radians(lat1)
lat2_rad=math.radians(lat2)
lon1_rad=math.radians(lon1)
lon2_rad=math.radians(lon2)
delta_lat=lat2_rad-lat1_rad
delta_lon=lon2_rad-lon1_rad
a=math.sqrt((math.sin(delta_lat/2))**2+math.cos(lat1_rad)*math.cos(lat2_rad)*(math.sin(delta_lon/2))**2)
d=2*6371000*math.asin(a)
return d
#DISTANCE CALCULATION
d_list=[]
for j in range(len(lat_list)):
lat_p=lat_list[j]
lon_p=lon_list[j]
dp=haversine(lat0,lon0,lat_p,lon_p)/1000 #km
d_list.append(dp)
d_list_rev=d_list[::-1] #reverse list
#CONSTRUCT JSON
d_ar=[{}]*len(lat_list)
for i in range(len(lat_list)):
d_ar[i]={"latitude":lat_list[i],"longitude":lon_list[i]}
location={"locations":d_ar}
json_data=json.dumps(location,skipkeys=int).encode('utf8')
try:
#SEND REQUEST
url="https://api.open-elevation.com/api/v1/lookup"
response = urllib.request.Request(url,json_data,headers={'Content-Type': 'application/json'})
fp=urllib.request.urlopen(response)
#RESPONSE PROCESSING
res_byte=fp.read()
res_str=res_byte.decode("utf8")
js_str=json.loads(res_str)
#print (js_mystr)
fp.close()
#GETTING ELEVATION
response_len=len(js_str['results'])
elev_list=[]
for j in range(response_len):
elev_list.append(js_str['results'][j]['elevation'])
#BASIC STAT INFORMATION
mean_elev=round((sum(elev_list)/len(elev_list)),3)
min_elev=min(elev_list)
max_elev=max(elev_list)
distance=d_list_rev[-1]
#PLOT ELEVATION PROFILE
base_reg=0
plt.figure(figsize=(10,4))
plt.plot(d_list_rev,elev_list)
plt.plot([0,distance],[min_elev,min_elev],'--g',label='min: '+str(min_elev)+' m')
plt.plot([0,distance],[max_elev,max_elev],'--r',label='max: '+str(max_elev)+' m')
plt.plot([0,distance],[mean_elev,mean_elev],'--y',label='ave: '+str(mean_elev)+' m')
plt.fill_between(d_list_rev,elev_list,base_reg,alpha=0.1)
plt.text(d_list_rev[0],elev_list[0],"P1")
plt.text(d_list_rev[-1],elev_list[-1],"P2")
plt.xlabel("Distance(km)")
plt.ylabel("Elevation(m)")
plt.grid()
plt.legend(fontsize='small')
plt.show()
except Exception as e:
print(str(e))
在尝试批量处理大量数据时,有人可以建议我如何有效地查询远程API吗?我也很抱歉,如果我错过了一些基本的知识,或者我想以尽可能低效的方式来解决这个问题-我是Python的新手,而且一般来说都是编码的,所以我想边学习边学习。
答案 0 :(得分:1)
您的主要问题是对服务器的请求过多。您已经将坐标列表发送到'https://api.open-elevation.com/api/v1/lookup'。
我看到了增加请求数量的唯一方法。
将数据分组到一个请求中
在proxy
中使用requests
您可以使用https://free-proxy-list.net/或类似网址中的免费代理。
import requests
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
requests.get('http://example.org', proxies=proxies)
import time
time.sleep(5)