我正在编写一个小型Python库,它从Horizons、JPL的太阳系数据和星历计算服务中获取数据。他们的批处理CGI的概述是这里。虽然脚本很简单,但我想使它尽可能清晰和标准化。
其思想是使用观察者(中心)、目标(命令)、日期时间和所需数据(数量)的位置初始化HorizonsRequest类。响应可以作为发送回的行的完整列表检索,也可以作为请求值的字典检索。
要求木星(599)的角度,它的距离,和相对于地球的光旅行时间(399)在当前时间。Horizons用户可以使用web界面找到这些数字ids。
request = horizons.HorizonsRequest("399", "599", datetime.utcnow(), "2,20,21")
request.send()
dictionary = request.get_dictionary()
for key in dictionary:
print(key, ":", dictionary[key])import sys
import urllib.request
import math
from datetime import datetime, timedelta
def get_julian_datetime(date):
# Ensure correct format
if not isinstance(date, datetime):
raise TypeError('Invalid type for parameter "date" - expecting datetime')
elif date.year < 1801 or date.year > 2099:
raise ValueError('Datetime must be between year 1801 and 2099')
# Perform the calculation
julian_datetime = 367 * date.year - int((7 * (date.year + int((date.month + 9)
/ 12.0))) / 4.0) + int((275 * date.month) / 9.0) + date.day + 1721013.5
+ (date.hour + date.minute / 60.0 + date.second / math.pow(60,2)) / 24.0
- 0.5 * math.copysign(1, 100 * date.year + date.month - 190002.5) + 0.5
return julian_datetime
class HorizonsRequest:
def __init__(self, center, target, datetime, quantities):
self.keys = {
"CENTER": center,
"COMMAND": target,
"QUANTITIES": quantities,
"TLIST": str(get_julian_datetime(datetime)),
"MAKE_EPHEM": "YES",
"OBJ_DATA": "NO",
"TABLE_TYPE": "OBSERVER",
"CAL_FORMAT": "BOTH",
"ANG_FORMAT": "DEG",
"CSV_FORMAT": "YES"
}
self.response = []
self.dictionary = {}
def set_key(self, key, value):
self.keys[key] = str(value)
def delete_key(self, key):
self.keys.pop(key, None)
def send(self):
# create request
request = "https://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=1"
for key in self.keys:
request += "&" + key + "='" + self.keys[key] + "'"
# send request
file = urllib.request.urlopen(request)
for line in file:
self.response.append(line.decode('utf-8').replace('\n', ''))
def get_dictionary(self):
keys = []
values = []
# locate data position in response
i = 0
while i < len(self.response):
if "$SOE" in self.response[i]:
keys = self.response[i - 2].split(",")
values = self.response[i + 1].split(",")
i += 1
# create dictionary
i = 0
while i < len(keys):
self.dictionary[keys[i].strip()] = values[i].strip()
i += 1
return self.dictionary
def get_response(self):
return self.response如有任何反馈,将不胜感激。
发布于 2020-07-30 01:17:59
urllib是一种痛苦的使用。使用请求代替。除其他外,所有这些代码:
for key in self.keys:
request += "&" + key + "='" + self.keys[key] + "'"就会消失。请求具有字典中的查询字符串格式。
你是否需要自己做这件事是值得怀疑的。找到像https://pypi.org/project/julian/这样的库。
date.year < 1801 or date.year > 2099应该是
not (1800 < date.year < 2100)math.pow(60,2)应该只是
60**2我建议HorizonsRequest.keys (顺便说一句,它不仅仅是一个键的集合--它是一个字典,所以它的名字是错的)在send中需要它之前不要构造它。也不应公开任意的set_key / delete_key。理论上,您应该对请求格式有足够的了解,即要创建它的信息存储在更强类型的变量中,这些变量可以得到更好的验证。例如,不要存储
"OBJ_DATA": "NO",作为类成员;相反,存储
obj_data: bool = Falsehttps://codereview.stackexchange.com/questions/246205
复制相似问题